add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / backwards / src / test / org / apache / lucene / search / spans / TestBasics.java
1 package org.apache.lucene.search.spans;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21 import java.io.Reader;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26
27 import org.apache.lucene.analysis.Analyzer;
28 import org.apache.lucene.analysis.LowerCaseTokenizer;
29 import org.apache.lucene.analysis.MockAnalyzer;
30 import org.apache.lucene.analysis.TokenFilter;
31 import org.apache.lucene.analysis.TokenStream;
32 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
33 import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
34 import org.apache.lucene.document.Document;
35 import org.apache.lucene.document.Field;
36 import org.apache.lucene.index.IndexReader;
37 import org.apache.lucene.index.Payload;
38 import org.apache.lucene.index.RandomIndexWriter;
39 import org.apache.lucene.index.Term;
40 import org.apache.lucene.search.BooleanClause;
41 import org.apache.lucene.search.BooleanQuery;
42 import org.apache.lucene.search.CheckHits;
43 import org.apache.lucene.search.IndexSearcher;
44 import org.apache.lucene.search.PhraseQuery;
45 import org.apache.lucene.search.Query;
46 import org.apache.lucene.search.QueryUtils;
47 import org.apache.lucene.search.TermQuery;
48 import org.apache.lucene.store.Directory;
49 import org.apache.lucene.util.English;
50 import org.apache.lucene.util.LuceneTestCase;
51 import org.apache.lucene.util._TestUtil;
52 import org.junit.AfterClass;
53 import org.junit.BeforeClass;
54 import org.junit.Test;
55
56 /**
57  * Tests basic search capabilities.
58  *
59  * <p>Uses a collection of 1000 documents, each the english rendition of their
60  * document number.  For example, the document numbered 333 has text "three
61  * hundred thirty three".
62  *
63  * <p>Tests are each a single query, and its hits are checked to ensure that
64  * all and only the correct documents are returned, thus providing end-to-end
65  * testing of the indexing and search code.
66  *
67  */
68 public class TestBasics extends LuceneTestCase {
69   private static IndexSearcher searcher;
70   private static IndexReader reader;
71   private static Directory directory;
72
73   static final class SimplePayloadFilter extends TokenFilter {
74     String fieldName;
75     int pos;
76     final PayloadAttribute payloadAttr;
77     final CharTermAttribute termAttr;
78
79     public SimplePayloadFilter(TokenStream input, String fieldName) {
80       super(input);
81       this.fieldName = fieldName;
82       pos = 0;
83       payloadAttr = input.addAttribute(PayloadAttribute.class);
84       termAttr = input.addAttribute(CharTermAttribute.class);
85     }
86
87     @Override
88     public boolean incrementToken() throws IOException {
89       if (input.incrementToken()) {
90         payloadAttr.setPayload(new Payload(("pos: " + pos).getBytes()));
91         pos++;
92         return true;
93       } else {
94         return false;
95       }
96     }
97
98     @Override
99     public void reset() throws IOException {
100       super.reset();
101       pos = 0;
102     }
103   }
104   
105   static final Analyzer simplePayloadAnalyzer = new Analyzer() {
106
107     @Override
108     public TokenStream tokenStream(String fieldName, Reader reader) {
109       return new SimplePayloadFilter(new LowerCaseTokenizer(TEST_VERSION_CURRENT, reader), fieldName);
110     }
111     
112   };
113   
114   @BeforeClass
115   public static void beforeClass() throws Exception {
116     directory = newDirectory();
117     RandomIndexWriter writer = new RandomIndexWriter(random, directory,
118         newIndexWriterConfig(TEST_VERSION_CURRENT, simplePayloadAnalyzer)
119                                                      .setMaxBufferedDocs(_TestUtil.nextInt(random, 50, 1000)).setMergePolicy(newLogMergePolicy()));
120     //writer.infoStream = System.out;
121     for (int i = 0; i < 2000; i++) {
122       Document doc = new Document();
123       doc.add(newField("field", English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
124       writer.addDocument(doc);
125     }
126     reader = writer.getReader();
127     searcher = newSearcher(reader);
128     writer.close();
129   }
130
131   @AfterClass
132   public static void afterClass() throws Exception {
133     searcher.close();
134     reader.close();
135     directory.close();
136     searcher = null;
137     reader = null;
138     directory = null;
139   }
140
141   @Test
142   public void testTerm() throws Exception {
143     Query query = new TermQuery(new Term("field", "seventy"));
144     checkHits(query, new int[]
145       {70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 170, 171, 172, 173, 174, 175,
146               176, 177, 178, 179, 270, 271, 272, 273, 274, 275, 276, 277, 278,
147               279, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 470, 471,
148               472, 473, 474, 475, 476, 477, 478, 479, 570, 571, 572, 573, 574,
149               575, 576, 577, 578, 579, 670, 671, 672, 673, 674, 675, 676, 677,
150               678, 679, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 870,
151               871, 872, 873, 874, 875, 876, 877, 878, 879, 970, 971, 972, 973,
152               974, 975, 976, 977, 978, 979, 1070, 1071, 1072, 1073, 1074, 1075,
153               1076, 1077, 1078, 1079, 1170, 1171, 1172, 1173, 1174, 1175, 1176,
154               1177, 1178, 1179, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277,
155               1278, 1279, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378,
156               1379, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479,
157               1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1670,
158               1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1770, 1771,
159               1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1870, 1871, 1872,
160               1873, 1874, 1875, 1876, 1877,
161               1878, 1879, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978,
162               1979});
163     }
164
165   @Test
166   public void testTerm2() throws Exception {
167     Query query = new TermQuery(new Term("field", "seventish"));
168     checkHits(query, new int[] {});
169   }
170
171   @Test
172   public void testPhrase() throws Exception {
173     PhraseQuery query = new PhraseQuery();
174     query.add(new Term("field", "seventy"));
175     query.add(new Term("field", "seven"));
176     checkHits(query, new int[]
177       {77, 177, 277, 377, 477, 577, 677, 777, 877,
178               977, 1077, 1177, 1277, 1377, 1477, 1577, 1677, 1777, 1877, 1977});
179   }
180
181   @Test
182   public void testPhrase2() throws Exception {
183     PhraseQuery query = new PhraseQuery();
184     query.add(new Term("field", "seventish"));
185     query.add(new Term("field", "sevenon"));
186     checkHits(query, new int[] {});
187   }
188
189   @Test
190   public void testBoolean() throws Exception {
191     BooleanQuery query = new BooleanQuery();
192     query.add(new TermQuery(new Term("field", "seventy")), BooleanClause.Occur.MUST);
193     query.add(new TermQuery(new Term("field", "seven")), BooleanClause.Occur.MUST);
194     checkHits(query, new int[]
195       {77, 177, 277, 377, 477, 577, 677, 770, 771, 772, 773, 774, 775, 776, 777,
196               778, 779, 877, 977, 1077, 1177, 1277, 1377, 1477, 1577, 1677,
197               1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, 1877,
198               1977});
199   }
200
201   @Test
202   public void testBoolean2() throws Exception {
203     BooleanQuery query = new BooleanQuery();
204     query.add(new TermQuery(new Term("field", "sevento")), BooleanClause.Occur.MUST);
205     query.add(new TermQuery(new Term("field", "sevenly")), BooleanClause.Occur.MUST);
206     checkHits(query, new int[] {});
207   }
208
209   @Test
210   public void testSpanNearExact() throws Exception {
211     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "seventy"));
212     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "seven"));
213     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {term1, term2},
214                                             0, true);
215     checkHits(query, new int[]
216       {77, 177, 277, 377, 477, 577, 677, 777, 877, 977, 1077, 1177, 1277, 1377, 1477, 1577, 1677, 1777, 1877, 1977});
217
218     assertTrue(searcher.explain(query, 77).getValue() > 0.0f);
219     assertTrue(searcher.explain(query, 977).getValue() > 0.0f);
220
221     QueryUtils.check(term1);
222     QueryUtils.check(term2);
223     QueryUtils.checkUnequal(term1,term2);
224   }
225   
226   public void testSpanTermQuery() throws Exception {
227     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "seventy"));
228     checkHits(term1, new int[]
229                              { 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 170,
230         171, 172, 173, 174, 175, 176, 177, 178, 179, 270, 271, 272, 273, 274,
231         275, 276, 277, 278, 279, 370, 371, 372, 373, 374, 375, 376, 377, 378,
232         379, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 570, 571, 572,
233         573, 574, 575, 576, 577, 578, 579, 670, 671, 672, 673, 674, 675, 676,
234         677, 678, 679, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 870,
235         871, 872, 873, 874, 875, 876, 877, 878, 879, 970, 971, 972, 973, 974,
236         975, 976, 977, 978, 979, 1070, 1071, 1072, 1073, 1074, 1075, 1076,
237         1077, 1078, 1079, 1170, 1270, 1370, 1470, 1570, 1670, 1770, 1870, 1970,
238         1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1271, 1272, 1273,
239         1274, 1275, 1276, 1277, 1278, 1279, 1371, 1372, 1373, 1374, 1375, 1376,
240         1377, 1378, 1379, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479,
241         1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1671, 1672, 1673,
242         1674, 1675, 1676, 1677, 1678, 1679, 1771, 1772, 1773, 1774, 1775, 1776,
243         1777, 1778, 1779, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, 1879,
244         1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979 });
245   }
246
247   @Test
248   public void testSpanNearUnordered() throws Exception {
249     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "nine"));
250     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "six"));
251     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {term1, term2},
252                                             4, false);
253
254     checkHits(query, new int[]
255       {609, 629, 639, 649, 659, 669, 679, 689, 699, 906, 926, 936, 946, 956,
256               966, 976, 986, 996, 1609, 1629, 1639, 1649, 1659, 1669,
257               1679, 1689, 1699, 1906, 1926, 1936, 1946, 1956, 1966, 1976, 1986,
258               1996});
259   }
260
261   @Test
262   public void testSpanNearOrdered() throws Exception {
263     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "nine"));
264     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "six"));
265     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {term1, term2},
266                                             4, true);
267     checkHits(query, new int[]
268       {906, 926, 936, 946, 956, 966, 976, 986, 996, 1906, 1926, 1936, 1946, 1956, 1966, 1976, 1986, 1996});
269   }
270
271   @Test
272   public void testSpanNot() throws Exception {
273     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "eight"));
274     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "one"));
275     SpanNearQuery near = new SpanNearQuery(new SpanQuery[] {term1, term2},
276                                            4, true);
277     SpanTermQuery term3 = new SpanTermQuery(new Term("field", "forty"));
278     SpanNotQuery query = new SpanNotQuery(near, term3);
279
280     checkHits(query, new int[]
281       {801, 821, 831, 851, 861, 871, 881, 891, 1801, 1821, 1831, 1851, 1861, 1871, 1881, 1891});
282
283     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
284     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
285   }
286   
287   @Test
288   public void testSpanWithMultipleNotSingle() throws Exception {
289     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "eight"));
290     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "one"));
291     SpanNearQuery near = new SpanNearQuery(new SpanQuery[] {term1, term2},
292                                            4, true);
293     SpanTermQuery term3 = new SpanTermQuery(new Term("field", "forty"));
294
295     SpanOrQuery or = new SpanOrQuery(term3);
296
297     SpanNotQuery query = new SpanNotQuery(near, or);
298
299     checkHits(query, new int[]
300       {801, 821, 831, 851, 861, 871, 881, 891,
301               1801, 1821, 1831, 1851, 1861, 1871, 1881, 1891});
302
303     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
304     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
305   }
306
307   @Test
308   public void testSpanWithMultipleNotMany() throws Exception {
309     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "eight"));
310     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "one"));
311     SpanNearQuery near = new SpanNearQuery(new SpanQuery[] {term1, term2},
312                                            4, true);
313     SpanTermQuery term3 = new SpanTermQuery(new Term("field", "forty"));
314     SpanTermQuery term4 = new SpanTermQuery(new Term("field", "sixty"));
315     SpanTermQuery term5 = new SpanTermQuery(new Term("field", "eighty"));
316
317     SpanOrQuery or = new SpanOrQuery(term3, term4, term5);
318
319     SpanNotQuery query = new SpanNotQuery(near, or);
320
321     checkHits(query, new int[]
322       {801, 821, 831, 851, 871, 891, 1801, 1821, 1831, 1851, 1871, 1891});
323
324     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
325     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
326   }
327
328   @Test
329   public void testNpeInSpanNearWithSpanNot() throws Exception {
330     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "eight"));
331     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "one"));
332     SpanNearQuery near = new SpanNearQuery(new SpanQuery[] {term1, term2},
333                                            4, true);
334     SpanTermQuery hun = new SpanTermQuery(new Term("field", "hundred"));
335     SpanTermQuery term3 = new SpanTermQuery(new Term("field", "forty"));
336     SpanNearQuery exclude = new SpanNearQuery(new SpanQuery[] {hun, term3},
337                                               1, true);
338     
339     SpanNotQuery query = new SpanNotQuery(near, exclude);
340
341     checkHits(query, new int[]
342       {801, 821, 831, 851, 861, 871, 881, 891,
343               1801, 1821, 1831, 1851, 1861, 1871, 1881, 1891});
344
345     assertTrue(searcher.explain(query, 801).getValue() > 0.0f);
346     assertTrue(searcher.explain(query, 891).getValue() > 0.0f);
347   }
348
349   @Test
350   public void testNpeInSpanNearInSpanFirstInSpanNot() throws Exception {
351     int n = 5;
352     SpanTermQuery hun = new SpanTermQuery(new Term("field", "hundred"));
353     SpanTermQuery term40 = new SpanTermQuery(new Term("field", "forty"));
354     SpanTermQuery term40c = (SpanTermQuery)term40.clone();
355
356     SpanFirstQuery include = new SpanFirstQuery(term40, n);
357     SpanNearQuery near = new SpanNearQuery(new SpanQuery[]{hun, term40c},
358                                            n-1, true);
359     SpanFirstQuery exclude = new SpanFirstQuery(near, n-1);
360     SpanNotQuery q = new SpanNotQuery(include, exclude);
361     
362     checkHits(q, new int[]{40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048,
363             1049, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1240, 1241, 1242, 1243, 1244,
364             1245, 1246, 1247, 1248, 1249, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1440, 1441, 1442,
365             1443, 1444, 1445, 1446, 1447, 1448, 1449, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1640,
366             1641, 1642, 1643, 1644, 1645, 1646, 1647,
367             1648, 1649, 1740, 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749, 1840, 1841, 1842, 1843, 1844, 1845, 1846,
368             1847, 1848, 1849, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949});
369   }
370   
371   @Test
372   public void testSpanFirst() throws Exception {
373     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "five"));
374     SpanFirstQuery query = new SpanFirstQuery(term1, 1);
375
376     checkHits(query, new int[]
377       {5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513,
378        514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527,
379        528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541,
380        542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555,
381        556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569,
382        570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583,
383        584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597,
384        598, 599});
385
386     assertTrue(searcher.explain(query, 5).getValue() > 0.0f);
387     assertTrue(searcher.explain(query, 599).getValue() > 0.0f);
388
389   }
390
391   @Test
392   public void testSpanPositionRange() throws Exception {
393     SpanPositionRangeQuery query;
394     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "five"));
395     query = new SpanPositionRangeQuery(term1, 1, 2);
396     checkHits(query, new int[]
397       {25,35, 45, 55, 65, 75, 85, 95});
398     assertTrue(searcher.explain(query, 25).getValue() > 0.0f);
399     assertTrue(searcher.explain(query, 95).getValue() > 0.0f);
400
401     query = new SpanPositionRangeQuery(term1, 0, 1);
402     checkHits(query, new int[]
403       {5, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512,
404               513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525,
405               526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538,
406               539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551,
407               552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564,
408               565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577,
409               578, 579, 580, 581, 582, 583, 584,
410               585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597,
411               598, 599});
412
413     query = new SpanPositionRangeQuery(term1, 6, 7);
414     checkHits(query, new int[]{});
415   }
416
417   @Test
418   public void testSpanPayloadCheck() throws Exception {
419     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "five"));
420     Payload pay = new Payload(("pos: " + 5).getBytes());
421     SpanQuery query = new SpanPayloadCheckQuery(term1, Collections.singletonList(pay.getData()));
422     checkHits(query, new int[]
423       {1125, 1135, 1145, 1155, 1165, 1175, 1185, 1195, 1225, 1235, 1245, 1255, 1265, 1275, 1285, 1295, 1325, 1335, 1345, 1355, 1365, 1375, 1385, 1395, 1425, 1435, 1445, 1455, 1465, 1475, 1485, 1495, 1525, 1535, 1545, 1555, 1565, 1575, 1585, 1595, 1625, 1635, 1645, 1655, 1665, 1675, 1685, 1695, 1725, 1735, 1745, 1755, 1765, 1775, 1785, 1795, 1825, 1835, 1845, 1855, 1865, 1875, 1885, 1895, 1925, 1935, 1945, 1955, 1965, 1975, 1985, 1995});
424     assertTrue(searcher.explain(query, 1125).getValue() > 0.0f);
425
426     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "hundred"));
427     SpanNearQuery snq;
428     SpanQuery[] clauses;
429     List<byte[]> list;
430     Payload pay2;
431     clauses = new SpanQuery[2];
432     clauses[0] = term1;
433     clauses[1] = term2;
434     snq = new SpanNearQuery(clauses, 0, true);
435     pay = new Payload(("pos: " + 0).getBytes());
436     pay2 = new Payload(("pos: " + 1).getBytes());
437     list = new ArrayList<byte[]>();
438     list.add(pay.getData());
439     list.add(pay2.getData());
440     query = new SpanNearPayloadCheckQuery(snq, list);
441     checkHits(query, new int[]
442       {500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599});
443     clauses = new SpanQuery[3];
444     clauses[0] = term1;
445     clauses[1] = term2;
446     clauses[2] = new SpanTermQuery(new Term("field", "five"));
447     snq = new SpanNearQuery(clauses, 0, true);
448     pay = new Payload(("pos: " + 0).getBytes());
449     pay2 = new Payload(("pos: " + 1).getBytes());
450     Payload pay3 = new Payload(("pos: " + 2).getBytes());
451     list = new ArrayList<byte[]>();
452     list.add(pay.getData());
453     list.add(pay2.getData());
454     list.add(pay3.getData());
455     query = new SpanNearPayloadCheckQuery(snq, list);
456     checkHits(query, new int[]
457       {505});
458   }
459
460   public void testComplexSpanChecks() throws Exception {
461     SpanTermQuery one = new SpanTermQuery(new Term("field", "one"));
462     SpanTermQuery thous = new SpanTermQuery(new Term("field", "thousand"));
463     //should be one position in between
464     SpanTermQuery hundred = new SpanTermQuery(new Term("field", "hundred"));
465     SpanTermQuery three = new SpanTermQuery(new Term("field", "three"));
466
467     SpanNearQuery oneThous = new SpanNearQuery(new SpanQuery[]{one, thous}, 0, true);
468     SpanNearQuery hundredThree = new SpanNearQuery(new SpanQuery[]{hundred, three}, 0, true);
469     SpanNearQuery oneThousHunThree = new SpanNearQuery(new SpanQuery[]{oneThous, hundredThree}, 1, true);
470     SpanQuery query;
471     //this one's too small
472     query = new SpanPositionRangeQuery(oneThousHunThree, 1, 2);
473     checkHits(query, new int[]{});
474     //this one's just right
475     query = new SpanPositionRangeQuery(oneThousHunThree, 0, 6);
476     checkHits(query, new int[]{1103, 1203,1303,1403,1503,1603,1703,1803,1903});
477
478     Collection<byte[]> payloads = new ArrayList<byte[]>();
479     Payload pay = new Payload(("pos: " + 0).getBytes());
480     Payload pay2 = new Payload(("pos: " + 1).getBytes());
481     Payload pay3 = new Payload(("pos: " + 3).getBytes());
482     Payload pay4 = new Payload(("pos: " + 4).getBytes());
483     payloads.add(pay.getData());
484     payloads.add(pay2.getData());
485     payloads.add(pay3.getData());
486     payloads.add(pay4.getData());
487     query = new SpanNearPayloadCheckQuery(oneThousHunThree, payloads);
488     checkHits(query, new int[]{1103, 1203,1303,1403,1503,1603,1703,1803,1903});
489
490   }
491
492
493   @Test
494   public void testSpanOr() throws Exception {
495     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "thirty"));
496     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "three"));
497     SpanNearQuery near1 = new SpanNearQuery(new SpanQuery[] {term1, term2},
498                                             0, true);
499     SpanTermQuery term3 = new SpanTermQuery(new Term("field", "forty"));
500     SpanTermQuery term4 = new SpanTermQuery(new Term("field", "seven"));
501     SpanNearQuery near2 = new SpanNearQuery(new SpanQuery[] {term3, term4},
502                                             0, true);
503
504     SpanOrQuery query = new SpanOrQuery(near1, near2);
505
506     checkHits(query, new int[]
507       {33, 47, 133, 147, 233, 247, 333, 347, 433, 447, 533, 547, 633, 647, 733,
508               747, 833, 847, 933, 947, 1033, 1047, 1133, 1147, 1233, 1247, 1333,
509               1347, 1433, 1447, 1533, 1547, 1633, 1647, 1733, 1747, 1833, 1847, 1933, 1947});
510
511     assertTrue(searcher.explain(query, 33).getValue() > 0.0f);
512     assertTrue(searcher.explain(query, 947).getValue() > 0.0f);
513   }
514
515   @Test
516   public void testSpanExactNested() throws Exception {
517     SpanTermQuery term1 = new SpanTermQuery(new Term("field", "three"));
518     SpanTermQuery term2 = new SpanTermQuery(new Term("field", "hundred"));
519     SpanNearQuery near1 = new SpanNearQuery(new SpanQuery[] {term1, term2},
520                                             0, true);
521     SpanTermQuery term3 = new SpanTermQuery(new Term("field", "thirty"));
522     SpanTermQuery term4 = new SpanTermQuery(new Term("field", "three"));
523     SpanNearQuery near2 = new SpanNearQuery(new SpanQuery[] {term3, term4},
524                                             0, true);
525
526     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {near1, near2},
527                                             0, true);
528
529     checkHits(query, new int[] {333, 1333});
530
531     assertTrue(searcher.explain(query, 333).getValue() > 0.0f);
532   }
533
534   @Test
535   public void testSpanNearOr() throws Exception {
536
537     SpanTermQuery t1 = new SpanTermQuery(new Term("field","six"));
538     SpanTermQuery t3 = new SpanTermQuery(new Term("field","seven"));
539     
540     SpanTermQuery t5 = new SpanTermQuery(new Term("field","seven"));
541     SpanTermQuery t6 = new SpanTermQuery(new Term("field","six"));
542
543     SpanOrQuery to1 = new SpanOrQuery(t1, t3);
544     SpanOrQuery to2 = new SpanOrQuery(t5, t6);
545     
546     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {to1, to2},
547                                             10, true);
548
549     checkHits(query, new int[]
550       {606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677,
551               686, 687, 696, 697, 706, 707, 726, 727, 736, 737, 746, 747, 756,
552               757, 766, 767, 776, 777, 786, 787, 796, 797, 1606, 1607, 1626,
553               1627, 1636, 1637, 1646, 1647, 1656, 1657, 1666, 1667, 1676, 1677,
554               1686, 1687, 1696, 1697, 1706, 1707, 1726, 1727, 1736, 1737,
555               1746, 1747, 1756, 1757, 1766, 1767, 1776, 1777, 1786, 1787, 1796,
556               1797});
557   }
558
559   @Test
560   public void testSpanComplex1() throws Exception {
561       
562     SpanTermQuery t1 = new SpanTermQuery(new Term("field","six"));
563     SpanTermQuery t2 = new SpanTermQuery(new Term("field","hundred"));
564     SpanNearQuery tt1 = new SpanNearQuery(new SpanQuery[] {t1, t2}, 0,true);
565
566     SpanTermQuery t3 = new SpanTermQuery(new Term("field","seven"));
567     SpanTermQuery t4 = new SpanTermQuery(new Term("field","hundred"));
568     SpanNearQuery tt2 = new SpanNearQuery(new SpanQuery[] {t3, t4}, 0,true);
569     
570     SpanTermQuery t5 = new SpanTermQuery(new Term("field","seven"));
571     SpanTermQuery t6 = new SpanTermQuery(new Term("field","six"));
572
573     SpanOrQuery to1 = new SpanOrQuery(tt1, tt2);
574     SpanOrQuery to2 = new SpanOrQuery(t5, t6);
575     
576     SpanNearQuery query = new SpanNearQuery(new SpanQuery[] {to1, to2},
577                                             100, true);
578     
579     checkHits(query, new int[]
580       {606, 607, 626, 627, 636, 637, 646, 647, 656, 657, 666, 667, 676, 677, 686, 687, 696,
581               697, 706, 707, 726, 727, 736, 737, 746, 747, 756, 757,
582               766, 767, 776, 777, 786, 787, 796, 797, 1606, 1607, 1626, 1627, 1636, 1637, 1646,
583               1647, 1656, 1657,
584               1666, 1667, 1676, 1677, 1686, 1687, 1696, 1697, 1706, 1707, 1726, 1727, 1736, 1737,
585               1746, 1747, 1756, 1757, 1766, 1767, 1776, 1777, 1786, 1787, 1796, 1797});
586   }
587   
588   @Test
589   public void testSpansSkipTo() throws Exception {
590     SpanTermQuery t1 = new SpanTermQuery(new Term("field", "seventy"));
591     SpanTermQuery t2 = new SpanTermQuery(new Term("field", "seventy"));
592     Spans s1 = t1.getSpans(searcher.getIndexReader());
593     Spans s2 = t2.getSpans(searcher.getIndexReader());
594
595     assertTrue(s1.next());
596     assertTrue(s2.next());
597
598     boolean hasMore = true;
599
600     do {
601       hasMore = skipToAccoringToJavaDocs(s1, s1.doc());
602       assertEquals(hasMore, s2.skipTo(s2.doc()));
603       assertEquals(s1.doc(), s2.doc());
604     } while (hasMore);
605   }
606
607   /** Skips to the first match beyond the current, whose document number is
608    * greater than or equal to <i>target</i>. <p>Returns true iff there is such
609    * a match.  <p>Behaves as if written: <pre>
610    *   boolean skipTo(int target) {
611    *     do {
612    *       if (!next())
613    *       return false;
614    *     } while (target > doc());
615    *     return true;
616    *   }
617    * </pre>
618    */
619   private boolean skipToAccoringToJavaDocs(Spans s, int target)
620       throws Exception {
621     do {
622       if (!s.next())
623         return false;
624     } while (target > s.doc());
625     return true;
626
627   }
628
629   private void checkHits(Query query, int[] results) throws IOException {
630     CheckHits.checkHits(random, query, "field", searcher, results);
631   }
632 }