1 /* api_posdb.cc: tests which need a backend with positional information
2 *
3 * Copyright 1999,2000,2001 BrightStation PLC
4 * Copyright 2002 Ananova Ltd
5 * Copyright 2002,2003,2004,2005,2006,2007,2009 Olly Betts
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 * USA
21 */
22
23 #include <config.h>
24
25 #include "api_posdb.h"
26
27 #include <string>
28 #include <vector>
29
30 using namespace std;
31
32 #include <xapian.h>
33 #include "testsuite.h"
34 #include "testutils.h"
35
36 #include "apitest.h"
37
38 /// Simple test of NEAR
DEFINE_TESTCASE(near1,positional)39 DEFINE_TESTCASE(near1, positional) {
40 Xapian::Database mydb(get_database("apitest_phrase"));
41 Xapian::Enquire enquire(mydb);
42 Xapian::Stem stemmer("english");
43 enquire.set_weighting_scheme(Xapian::BoolWeight());
44
45 // make a query
46 vector<Xapian::Query> subqs;
47 Xapian::Query q;
48 subqs.push_back(Xapian::Query(stemmer("phrase")));
49 subqs.push_back(Xapian::Query(stemmer("fridge")));
50 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
51 enquire.set_query(q);
52
53 // retrieve the top ten results
54 Xapian::MSet mymset = enquire.get_mset(0, 10);
55 mset_expect_order(mymset);
56
57 subqs.clear();
58 subqs.push_back(Xapian::Query(stemmer("phrase")));
59 subqs.push_back(Xapian::Query(stemmer("near")));
60 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 2);
61 enquire.set_query(q);
62
63 // retrieve the top ten results
64 mymset = enquire.get_mset(0, 10);
65 mset_expect_order(mymset, 3);
66
67 subqs.clear();
68 subqs.push_back(Xapian::Query(stemmer("phrase")));
69 subqs.push_back(Xapian::Query(stemmer("near")));
70 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 3);
71 enquire.set_query(q);
72
73 // retrieve the top ten results
74 mymset = enquire.get_mset(0, 10);
75 mset_expect_order(mymset, 1, 3);
76
77 subqs.clear();
78 subqs.push_back(Xapian::Query(stemmer("phrase")));
79 subqs.push_back(Xapian::Query(stemmer("near")));
80 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 5);
81 enquire.set_query(q);
82
83 // retrieve the top ten results
84 mymset = enquire.get_mset(0, 10);
85 mset_expect_order(mymset, 1, 3);
86
87 subqs.clear();
88 subqs.push_back(Xapian::Query(stemmer("phrase")));
89 subqs.push_back(Xapian::Query(stemmer("near")));
90 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 6);
91 enquire.set_query(q);
92
93 // retrieve the top ten results
94 mymset = enquire.get_mset(0, 10);
95 mset_expect_order(mymset, 1, 2, 3);
96
97 subqs.clear();
98 subqs.push_back(Xapian::Query(stemmer("leave")));
99 subqs.push_back(Xapian::Query(stemmer("fridge")));
100 subqs.push_back(Xapian::Query(stemmer("on")));
101 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 3);
102 enquire.set_query(q);
103
104 // retrieve the top ten results
105 mymset = enquire.get_mset(0, 10);
106 mset_expect_order(mymset, 4, 5, 6, 7, 8, 9);
107
108 subqs.clear();
109 subqs.push_back(Xapian::Query(stemmer("leave")));
110 subqs.push_back(Xapian::Query(stemmer("fridge")));
111 subqs.push_back(Xapian::Query(stemmer("on")));
112 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 4);
113 enquire.set_query(q);
114
115 // retrieve the top ten results
116 mymset = enquire.get_mset(0, 10);
117 mset_expect_order(mymset, 4, 5, 6, 7, 8, 9, 10);
118
119 subqs.clear();
120 subqs.push_back(Xapian::Query(stemmer("leave")));
121 subqs.push_back(Xapian::Query(stemmer("fridge")));
122 subqs.push_back(Xapian::Query(stemmer("on")));
123 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 5);
124 enquire.set_query(q);
125
126 // retrieve the top ten results
127 mymset = enquire.get_mset(0, 10);
128 mset_expect_order(mymset, 4, 5, 6, 7, 8, 9, 10, 11);
129
130 subqs.clear();
131 subqs.push_back(Xapian::Query(stemmer("leave")));
132 subqs.push_back(Xapian::Query(stemmer("fridge")));
133 subqs.push_back(Xapian::Query(stemmer("on")));
134 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 6);
135 enquire.set_query(q);
136
137 // retrieve the top ten results
138 mymset = enquire.get_mset(0, 10);
139 mset_expect_order(mymset, 4, 5, 6, 7, 8, 9, 10, 11, 12);
140
141 subqs.clear();
142 subqs.push_back(Xapian::Query(stemmer("leave")));
143 subqs.push_back(Xapian::Query(stemmer("fridge")));
144 subqs.push_back(Xapian::Query(stemmer("on")));
145 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 7);
146 enquire.set_query(q);
147
148 // retrieve the top twenty results
149 mymset = enquire.get_mset(0, 20);
150 mset_expect_order(mymset, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
151
152 subqs.clear();
153 subqs.push_back(Xapian::Query(stemmer("leave")));
154 subqs.push_back(Xapian::Query(stemmer("fridge")));
155 subqs.push_back(Xapian::Query(stemmer("on")));
156 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 8);
157 enquire.set_query(q);
158
159 // retrieve the top ten results
160 mymset = enquire.get_mset(0, 20);
161 mset_expect_order(mymset, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
162
163 subqs.clear();
164 subqs.push_back(Xapian::Query(stemmer("leave")));
165 subqs.push_back(Xapian::Query(stemmer("fridge")));
166 subqs.push_back(Xapian::Query(stemmer("on")));
167 // test really large window size
168 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 999999999);
169 enquire.set_query(q);
170
171 // retrieve the top ten results
172 mymset = enquire.get_mset(0, 20);
173 mset_expect_order(mymset, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
174
175 return true;
176 }
177
178 /// Test NEAR over operators
DEFINE_TESTCASE(near2,positional)179 DEFINE_TESTCASE(near2, positional) {
180 Xapian::Database mydb(get_database("apitest_phrase"));
181 Xapian::Enquire enquire(mydb);
182 Xapian::Stem stemmer("english");
183 enquire.set_weighting_scheme(Xapian::BoolWeight());
184
185 // make a query
186 vector<Xapian::Query> subqs;
187 Xapian::Query q;
188 subqs.push_back(Xapian::Query(Xapian::Query::OP_AND,
189 Xapian::Query(stemmer("phrase")),
190 Xapian::Query(stemmer("near"))));
191 subqs.push_back(Xapian::Query(stemmer("and")));
192 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 2);
193 enquire.set_query(q);
194
195 // retrieve the top ten results
196 Xapian::MSet mymset = enquire.get_mset(0, 10);
197 mset_expect_order(mymset, 1);
198
199 subqs.clear();
200 subqs.push_back(Xapian::Query(Xapian::Query::OP_AND,
201 Xapian::Query(stemmer("phrase")),
202 Xapian::Query(stemmer("near"))));
203 subqs.push_back(Xapian::Query(stemmer("operator")));
204 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 2);
205 enquire.set_query(q);
206
207 // retrieve the top ten results
208 mymset = enquire.get_mset(0, 10);
209 mset_expect_order(mymset, 2);
210
211 subqs.clear();
212 subqs.push_back(Xapian::Query(stemmer("operator")));
213 subqs.push_back(Xapian::Query(Xapian::Query::OP_AND,
214 Xapian::Query(stemmer("phrase")),
215 Xapian::Query(stemmer("near"))));
216 q = Xapian::Query(Xapian::Query::OP_NEAR, subqs.begin(), subqs.end(), 2);
217 enquire.set_query(q);
218
219 // retrieve the top ten results
220 mymset = enquire.get_mset(0, 10);
221 mset_expect_order(mymset, 2);
222
223 return true;
224 }
225
226 /// Simple test of PHRASE
DEFINE_TESTCASE(phrase1,positional)227 DEFINE_TESTCASE(phrase1, positional) {
228 Xapian::Database mydb(get_database("apitest_phrase"));
229 Xapian::Enquire enquire(mydb);
230 Xapian::Stem stemmer("english");
231 enquire.set_weighting_scheme(Xapian::BoolWeight());
232
233 // make a query
234 vector<Xapian::Query> subqs;
235 Xapian::Query q;
236 subqs.push_back(Xapian::Query(stemmer("phrase")));
237 subqs.push_back(Xapian::Query(stemmer("fridge")));
238 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
239 enquire.set_query(q);
240
241 // retrieve the top ten results
242 Xapian::MSet mymset = enquire.get_mset(0, 10);
243 mset_expect_order(mymset);
244
245 subqs.clear();
246 subqs.push_back(Xapian::Query(stemmer("phrase")));
247 subqs.push_back(Xapian::Query(stemmer("near")));
248 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
249 enquire.set_query(q);
250
251 // retrieve the top ten results
252 mymset = enquire.get_mset(0, 10);
253 mset_expect_order(mymset);
254
255 subqs.clear();
256 subqs.push_back(Xapian::Query(stemmer("phrase")));
257 subqs.push_back(Xapian::Query(stemmer("near")));
258 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 3);
259 enquire.set_query(q);
260
261 // retrieve the top ten results
262 mymset = enquire.get_mset(0, 10);
263 mset_expect_order(mymset, 1);
264
265 subqs.clear();
266 subqs.push_back(Xapian::Query(stemmer("phrase")));
267 subqs.push_back(Xapian::Query(stemmer("near")));
268 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 5);
269 enquire.set_query(q);
270
271 // retrieve the top ten results
272 mymset = enquire.get_mset(0, 10);
273 mset_expect_order(mymset, 1);
274
275 subqs.clear();
276 subqs.push_back(Xapian::Query(stemmer("phrase")));
277 subqs.push_back(Xapian::Query(stemmer("near")));
278 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 6);
279 enquire.set_query(q);
280
281 // retrieve the top ten results
282 mymset = enquire.get_mset(0, 10);
283 mset_expect_order(mymset, 1, 2);
284
285 subqs.clear();
286 subqs.push_back(Xapian::Query(stemmer("leave")));
287 subqs.push_back(Xapian::Query(stemmer("fridge")));
288 subqs.push_back(Xapian::Query(stemmer("on")));
289 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 3);
290 enquire.set_query(q);
291
292 // retrieve the top ten results
293 mymset = enquire.get_mset(0, 10);
294 mset_expect_order(mymset, 4);
295
296 subqs.clear();
297 subqs.push_back(Xapian::Query(stemmer("leave")));
298 subqs.push_back(Xapian::Query(stemmer("fridge")));
299 subqs.push_back(Xapian::Query(stemmer("on")));
300 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 4);
301 enquire.set_query(q);
302
303 // retrieve the top ten results
304 mymset = enquire.get_mset(0, 10);
305 mset_expect_order(mymset, 4);
306
307 subqs.clear();
308 subqs.push_back(Xapian::Query(stemmer("leave")));
309 subqs.push_back(Xapian::Query(stemmer("fridge")));
310 subqs.push_back(Xapian::Query(stemmer("on")));
311 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 5);
312 enquire.set_query(q);
313
314 // retrieve the top ten results
315 mymset = enquire.get_mset(0, 10);
316 mset_expect_order(mymset, 4);
317
318 subqs.clear();
319 subqs.push_back(Xapian::Query(stemmer("leave")));
320 subqs.push_back(Xapian::Query(stemmer("fridge")));
321 subqs.push_back(Xapian::Query(stemmer("on")));
322 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 6);
323 enquire.set_query(q);
324
325 // retrieve the top ten results
326 mymset = enquire.get_mset(0, 10);
327 mset_expect_order(mymset, 4);
328
329 subqs.clear();
330 subqs.push_back(Xapian::Query(stemmer("leave")));
331 subqs.push_back(Xapian::Query(stemmer("fridge")));
332 subqs.push_back(Xapian::Query(stemmer("on")));
333 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 7);
334 enquire.set_query(q);
335
336 // retrieve the top twenty results
337 mymset = enquire.get_mset(0, 20);
338 mset_expect_order(mymset, 4);
339
340 subqs.clear();
341 subqs.push_back(Xapian::Query(stemmer("leave")));
342 subqs.push_back(Xapian::Query(stemmer("fridge")));
343 subqs.push_back(Xapian::Query(stemmer("on")));
344 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 8);
345 enquire.set_query(q);
346
347 // retrieve the top 20 results
348 mymset = enquire.get_mset(0, 20);
349 mset_expect_order(mymset, 4);
350
351 // test really large window size
352 subqs.clear();
353 subqs.push_back(Xapian::Query(stemmer("leave")));
354 subqs.push_back(Xapian::Query(stemmer("fridge")));
355 subqs.push_back(Xapian::Query(stemmer("on")));
356 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 999999999);
357 enquire.set_query(q);
358
359 // retrieve the top 20 results
360 mymset = enquire.get_mset(0, 20);
361 mset_expect_order(mymset, 4);
362
363 // regression test (was matching doc 15, should fail)
364 subqs.clear();
365 subqs.push_back(Xapian::Query(stemmer("first")));
366 subqs.push_back(Xapian::Query(stemmer("second")));
367 subqs.push_back(Xapian::Query(stemmer("third")));
368 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 9);
369 enquire.set_query(q);
370
371 // retrieve the top ten results
372 mymset = enquire.get_mset(0, 10);
373 mset_expect_order(mymset);
374
375 // regression test (should match doc 15, make sure still does with fix)
376 subqs.clear();
377 subqs.push_back(Xapian::Query(stemmer("first")));
378 subqs.push_back(Xapian::Query(stemmer("second")));
379 subqs.push_back(Xapian::Query(stemmer("third")));
380 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 10);
381 enquire.set_query(q);
382
383 // retrieve the top ten results
384 mymset = enquire.get_mset(0, 10);
385 mset_expect_order(mymset, 15);
386
387 // regression test (phrase matching was getting order wrong when
388 // build_and_tree reordered vector of PostLists)
389 subqs.clear();
390 subqs.push_back(Xapian::Query(stemmer("milk")));
391 subqs.push_back(Xapian::Query(stemmer("rare")));
392 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
393 enquire.set_query(q);
394
395 // retrieve the top ten results
396 mymset = enquire.get_mset(0, 10);
397 mset_expect_order(mymset, 16);
398
399 // regression test (phrase matching was getting order wrong when
400 // build_and_tree reordered vector of PostLists)
401 subqs.clear();
402 subqs.push_back(Xapian::Query(stemmer("rare")));
403 subqs.push_back(Xapian::Query(stemmer("milk")));
404 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
405 enquire.set_query(q);
406
407 // retrieve the top ten results
408 mymset = enquire.get_mset(0, 10);
409 mset_expect_order(mymset, 17);
410
411 return true;
412 }
413
414 /// Test PHRASE over operators
DEFINE_TESTCASE(phrase2,positional)415 DEFINE_TESTCASE(phrase2, positional) {
416 Xapian::Database mydb(get_database("apitest_phrase"));
417 Xapian::Enquire enquire(mydb);
418 Xapian::Stem stemmer("english");
419 enquire.set_weighting_scheme(Xapian::BoolWeight());
420
421 // make a query
422 vector<Xapian::Query> subqs;
423 Xapian::Query q;
424 subqs.push_back(Xapian::Query(Xapian::Query::OP_AND,
425 Xapian::Query(stemmer("phrase")),
426 Xapian::Query(stemmer("near"))));
427 subqs.push_back(Xapian::Query(stemmer("and")));
428 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
429 enquire.set_query(q);
430
431 // retrieve the top ten results
432 Xapian::MSet mymset = enquire.get_mset(0, 10);
433 mset_expect_order(mymset);
434
435 subqs.clear();
436 subqs.push_back(Xapian::Query(Xapian::Query::OP_AND,
437 Xapian::Query(stemmer("phrase")),
438 Xapian::Query(stemmer("near"))));
439 subqs.push_back(Xapian::Query(stemmer("operator")));
440 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
441 enquire.set_query(q);
442
443 // retrieve the top ten results
444 mymset = enquire.get_mset(0, 10);
445 mset_expect_order(mymset, 2);
446
447 subqs.clear();
448 subqs.push_back(Xapian::Query(stemmer("operator")));
449 subqs.push_back(Xapian::Query(Xapian::Query::OP_AND,
450 Xapian::Query(stemmer("phrase")),
451 Xapian::Query(stemmer("near"))));
452 q = Xapian::Query(Xapian::Query::OP_PHRASE, subqs.begin(), subqs.end(), 2);
453 enquire.set_query(q);
454
455 // retrieve the top ten results
456 mymset = enquire.get_mset(0, 10);
457 mset_expect_order(mymset);
458
459 return true;
460 }
461
462 /// Test getting position lists from databases
DEFINE_TESTCASE(poslist1,positional)463 DEFINE_TESTCASE(poslist1, positional) {
464 Xapian::Database mydb(get_database("apitest_poslist"));
465
466 Xapian::Stem stemmer("english");
467 string term = stemmer("sponge");
468
469 Xapian::PositionIterator pli = mydb.positionlist_begin(2, term);
470
471 TEST(pli != mydb.positionlist_end(2, term));
472 TEST(*pli == 1);
473 pli++;
474 TEST(pli != mydb.positionlist_end(2, term));
475 TEST(*pli == 2);
476 pli++;
477 TEST(pli != mydb.positionlist_end(2, term));
478 TEST(*pli == 3);
479 pli++;
480 TEST(pli != mydb.positionlist_end(2, term));
481 TEST(*pli == 5);
482 pli++;
483 TEST(pli != mydb.positionlist_end(2, term));
484 TEST(*pli == 8);
485 pli++;
486 TEST(pli != mydb.positionlist_end(2, term));
487 TEST(*pli == 13);
488 pli++;
489 TEST(pli != mydb.positionlist_end(2, term));
490 TEST(*pli == 21);
491 pli++;
492 TEST(pli != mydb.positionlist_end(2, term));
493 TEST(*pli == 34);
494 pli++;
495 TEST(pli == mydb.positionlist_end(2, term));
496
497 return true;
498 }
499
DEFINE_TESTCASE(poslist2,positional && writable)500 DEFINE_TESTCASE(poslist2, positional && writable) {
501 Xapian::WritableDatabase db = get_writable_database();
502
503 Xapian::Document doc;
504 doc.add_term("nopos");
505 Xapian::docid did = db.add_document(doc);
506
507 // Check what happens when term doesn't exist - should give an empty list.
508 // Threw RangeError in Xapian < 1.1.0.
509 TEST_EQUAL(db.positionlist_begin(did, "nosuchterm"),
510 db.positionlist_end(did, "nosuchterm"));
511
512 // Check what happens when the document doesn't even exist - should give
513 // an empty list. Threw DocNotFoundError in Xapian < 1.1.0.
514 TEST_EQUAL(db.positionlist_begin(123, "nosuchterm"),
515 db.positionlist_end(123, "nosuchterm"));
516
517 TEST_EQUAL(db.positionlist_begin(did, "nopos"),
518 db.positionlist_end(did, "nopos"));
519
520 Xapian::Document doc2 = db.get_document(did);
521
522 Xapian::TermIterator term = doc2.termlist_begin();
523
524 {
525 Xapian::PositionIterator i = term.positionlist_begin();
526 TEST_EQUAL(i, term.positionlist_end());
527 }
528
529 Xapian::Document doc3;
530 doc3.add_posting("hadpos", 1);
531 Xapian::docid did2 = db.add_document(doc3);
532
533 Xapian::Document doc4 = db.get_document(did2);
534 doc4.remove_posting("hadpos", 1);
535 db.replace_document(did2, doc4);
536
537 {
538 Xapian::PositionIterator i = db.positionlist_begin(did2, "hadpos");
539 TEST_EQUAL(i, db.positionlist_end(did2, "hadpos"));
540 }
541
542 db.delete_document(did);
543 // Check what happens when the document doesn't exist (but once did).
544 TEST_EQUAL(db.positionlist_begin(did, "nosuchterm"),
545 db.positionlist_end(did, "nosuchterm"));
546
547 return true;
548 }
549
550 /// Test playing with a positionlist, testing skip_to in particular.
551 /// (used to be quartztest's test_positionlist1).
DEFINE_TESTCASE(poslist3,positional && writable)552 DEFINE_TESTCASE(poslist3, positional && writable) {
553 Xapian::WritableDatabase db = get_writable_database();
554
555 Xapian::Document document;
556 document.add_posting("foo", 5);
557 document.add_posting("foo", 8);
558 document.add_posting("foo", 10);
559 document.add_posting("foo", 12);
560 db.add_document(document);
561
562 Xapian::PositionIterator pl = db.positionlist_begin(1, "foo");
563 Xapian::PositionIterator pl_end = db.positionlist_end(1, "foo");
564
565 TEST(pl != pl_end);
566 TEST_EQUAL(*pl, 5);
567 ++pl;
568 TEST(pl != pl_end);
569 TEST_EQUAL(*pl, 8);
570 ++pl;
571 TEST(pl != pl_end);
572 TEST_EQUAL(*pl, 10);
573 ++pl;
574 TEST(pl != pl_end);
575 TEST_EQUAL(*pl, 12);
576 ++pl;
577 TEST(pl == pl_end);
578
579 pl = db.positionlist_begin(1, "foo");
580 pl.skip_to(5);
581 TEST(pl != pl_end);
582 TEST_EQUAL(*pl, 5);
583
584 pl.skip_to(9);
585 TEST(pl != pl_end);
586 TEST_EQUAL(*pl, 10);
587
588 ++pl;
589 TEST(pl != pl_end);
590 TEST_EQUAL(*pl, 12);
591
592 pl.skip_to(12);
593 TEST(pl != pl_end);
594 TEST_EQUAL(*pl, 12);
595
596 pl.skip_to(13);
597 TEST(pl == pl_end);
598
599 return true;
600 }
601
602 // Regression test - in 0.9.4 (and many previous versions) you couldn't get a
603 // PositionIterator from a TermIterator from Database::termlist_begin().
604 //
605 // Also test that positionlist_count() is implemented for this case, which it
606 // wasn't in 1.0.2 and earlier.
DEFINE_TESTCASE(positfromtermit1,positional)607 DEFINE_TESTCASE(positfromtermit1, positional) {
608 Xapian::Database db(get_database("apitest_phrase"));
609 Xapian::TermIterator t(db.termlist_begin(7));
610 TEST_NOT_EQUAL(t, db.termlist_end(7));
611 Xapian::PositionIterator p = t.positionlist_begin();
612 TEST_NOT_EQUAL(p, t.positionlist_end());
613
614 try {
615 TEST_EQUAL(t.positionlist_count(), 1);
616 t.skip_to("on");
617 TEST_NOT_EQUAL(t, db.termlist_end(7));
618 TEST_EQUAL(t.positionlist_count(), 2);
619 } catch (const Xapian::UnimplementedError &) {
620 SKIP_TEST("TermList::positionlist_count() not yet implemented for this backend");
621 }
622
623 return true;
624 }
625