root / tags / 1.0.8 / xapian-core / tests / api_posdb.cc

Revision 9737, 21.0 kB (checked in by olly, 14 months ago)

tests/api_posdb.cc,tests/apitest.cc: Add "writable" flag and use it
for poslist2 and poslist3.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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 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
30using 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
39DEFINE_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
179DEFINE_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
227DEFINE_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
415DEFINE_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
463DEFINE_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    TEST_EXCEPTION(Xapian::DocNotFoundError, mydb.positionlist_begin(55, term));
498
499    /* FIXME: what exception should be thrown here?  Quartz throws
500     * Xapian::DocNotFoundError, and InMemory throws Xapian::RangeError.
501     */
502    TEST_EXCEPTION(Xapian::RuntimeError, mydb.positionlist_begin(2, "adskfjadsfa"));
503    TEST_EXCEPTION(Xapian::DocNotFoundError, mydb.positionlist_begin(55, "adskfjadsfa"));
504
505    return true;
506}
507
508DEFINE_TESTCASE(poslist2, positional && writable) {
509    Xapian::WritableDatabase db = get_writable_database();
510
511    Xapian::Document doc;
512    doc.add_term("nopos");
513    Xapian::docid did = db.add_document(doc);
514
515    TEST_EXCEPTION(Xapian::RangeError,
516        // Check what happens when term doesn't exist
517        Xapian::PositionIterator i = db.positionlist_begin(did, "nosuchterm");
518    );
519
520    TEST_EXCEPTION(Xapian::DocNotFoundError,
521        // Check what happens when the document doesn't even exist
522        Xapian::PositionIterator i = db.positionlist_begin(123, "nosuchterm");
523    );
524
525    {
526        Xapian::PositionIterator i = db.positionlist_begin(did, "nopos");
527        TEST_EQUAL(i, db.positionlist_end(did, "nopos"));
528    }
529
530    Xapian::Document doc2 = db.get_document(did);
531
532    Xapian::TermIterator term = doc2.termlist_begin();
533
534    {
535        Xapian::PositionIterator i = term.positionlist_begin();
536        TEST_EQUAL(i, term.positionlist_end());
537    }
538
539    Xapian::Document doc3;
540    doc3.add_posting("hadpos", 1);
541    Xapian::docid did2 = db.add_document(doc3);
542
543    Xapian::Document doc4 = db.get_document(did2);
544    doc4.remove_posting("hadpos", 1);
545    db.replace_document(did2, doc4);
546
547    {
548        Xapian::PositionIterator i = db.positionlist_begin(did2, "hadpos");
549        TEST_EQUAL(i, db.positionlist_end(did2, "hadpos"));
550    }
551
552    db.delete_document(did);
553    TEST_EXCEPTION(Xapian::DocNotFoundError,
554        // Check what happens when the document doesn't even exist
555        // (but once did)
556        Xapian::PositionIterator i = db.positionlist_begin(did, "nosuchterm");
557    );
558
559    return true;
560}
561
562/// Test playing with a positionlist, testing skip_to in particular.
563/// (used to be quartztest's test_positionlist1).
564DEFINE_TESTCASE(poslist3, positional && writable) {
565    Xapian::WritableDatabase db = get_writable_database();
566
567    vector<Xapian::termpos> positions;
568
569    Xapian::Document document;
570    document.add_posting("foo", 5);
571    document.add_posting("foo", 8);
572    document.add_posting("foo", 10);
573    document.add_posting("foo", 12);
574    db.add_document(document);
575
576    TEST_EXCEPTION(Xapian::RangeError, db.positionlist_begin(1, "foobar"));
577    TEST_EXCEPTION(Xapian::DocNotFoundError, db.positionlist_begin(2, "foo"));
578    TEST_EXCEPTION(Xapian::DocNotFoundError, db.positionlist_begin(2, "foobar"));
579    Xapian::PositionIterator pl = db.positionlist_begin(1, "foo");
580    Xapian::PositionIterator pl_end = db.positionlist_end(1, "foo");
581
582    TEST(pl != pl_end);
583    TEST_EQUAL(*pl, 5);
584    ++pl;
585    TEST(pl != pl_end);
586    TEST_EQUAL(*pl, 8);
587    ++pl;
588    TEST(pl != pl_end);
589    TEST_EQUAL(*pl, 10);
590    ++pl;
591    TEST(pl != pl_end);
592    TEST_EQUAL(*pl, 12);
593    ++pl;
594    TEST(pl == pl_end);
595
596    pl = db.positionlist_begin(1, "foo");
597    pl.skip_to(5);
598    TEST(pl != pl_end);
599    TEST_EQUAL(*pl, 5);
600
601    pl.skip_to(9);
602    TEST(pl != pl_end);
603    TEST_EQUAL(*pl, 10);
604
605    ++pl;
606    TEST(pl != pl_end);
607    TEST_EQUAL(*pl, 12);
608
609    pl.skip_to(12);
610    TEST(pl != pl_end);
611    TEST_EQUAL(*pl, 12);
612
613    pl.skip_to(13);
614    TEST(pl == pl_end);
615
616    return true;
617}
618
619// Regression test - in 0.9.4 (and many previous versions) you couldn't get a
620// PositionIterator from a TermIterator from Database::termlist_begin().
621//
622// Also test that positionlist_count() is implemented for this case, which it
623// wasn't in 1.0.2 and earlier.
624DEFINE_TESTCASE(positfromtermit1, positional) {
625    Xapian::Database db(get_database("apitest_phrase"));
626    Xapian::TermIterator t(db.termlist_begin(7));
627    TEST_NOT_EQUAL(t, db.termlist_end(7));
628    Xapian::PositionIterator p = t.positionlist_begin();
629    TEST_NOT_EQUAL(p, t.positionlist_end());
630
631    try {
632        TEST_EQUAL(t.positionlist_count(), 1);
633        t.skip_to("on");
634        TEST_NOT_EQUAL(t, db.termlist_end(7));
635        TEST_EQUAL(t.positionlist_count(), 2);
636    } catch (const Xapian::UnimplementedError &) {
637        SKIP_TEST("TermList::positionlist_count() not yet implemented for this backend");
638    }
639
640    return true;
641}
Note: See TracBrowser for help on using the browser.