import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TopDocsCollector;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.junit.Assert;
import org.junit.Test;

public class TestSpanNearQueryInOrder {

@Test
public void testSpanNearQueryInOrder() {
	RAMDirectory directory = new RAMDirectory();
	IndexWriter writer = new IndexWriter(directory, new StandardAnalyzer(Version.LUCENE_29), true, IndexWriter.MaxFieldLength.UNLIMITED);
	TopDocsCollector collector = TopScoreDocCollector.create(3, false);
	
	Document doc = new Document();
	
	// DOC1
	doc.add(new Field("text","dddd aaaa bbbb cccc", Field.Store.YES, Field.Index.ANALYZED));
	
	writer.addDocument(doc);
	doc = new Document();	
	
	// DOC2
	doc.add(new Field("text","dddd aaaa aaaa cccc"));
	
	writer.addDocument(doc);	
	doc = new Document();
	
	// DOC3
	doc.add(new Field("text","dddd aaaa yyyy aaaa xxxx cccc"));
	
	writer.addDocument(doc);
	writer.optimize();
	writer.close();

	searcher = new IndexSearcher(directory, false);

	SpanQuery[] clauses = new SpanQuery[2];
	clauses[0] = new SpanTermQuery(new Term("text", "aaaa")); // (1) match at position 2  (2) match at position 2,3 (3) match at position 2,4
	clauses[1] = new SpanTermQuery(new Term("text", "aaaa")); // (1) match at position 2  (2) match at position 2,3 (3) match at position 2,4
	
	// Don't care about order, so setting inOrder = false
	SpanNearQuery q = new SpanNearQuery(clauses, 1, false); // (1) difference 0 (2) difference 0, 1 (3) difference 0, 2
	searcher.search(q, collector);

	// This assert fails - 3 docs are returned. Expecting only DOC2 and DOC3
	Assert.assertEquals("Check 2 results", 2, collector.getTotalHits());	

	collector = new TopScoreDocCollector.create(3, false);
	clauses = new SpanQuery[2];
	clauses[0] = new SpanTermQuery(new Term("text", "aaaa"));
	clauses[1] = new SpanTermQuery(new Term("text", "aaaa"));
	
	// Don't care about order, so setting inOrder = false
	q = new SpanNearQuery(clauses, 0, false);
	searcher.search(q, collector);

	// This assert fails - 3 docs are returned. Expecting only DOC2
	Assert.assertEquals("Check 1 result", 1, collector.getTotalHits());	
}

}