Branch data Line data Source code
1 : : /* api_nodb.cc: tests which don't use any of the backends
2 : : *
3 : : * Copyright 1999,2000,2001 BrightStation PLC
4 : : * Copyright 2002 Ananova Ltd
5 : : * Copyright 2002,2003,2004,2005,2006,2007,2008,2009,2010 Olly Betts
6 : : * Copyright 2006 Lemur Consulting Ltd
7 : : *
8 : : * This program is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU General Public License as
10 : : * published by the Free Software Foundation; either version 2 of the
11 : : * License, or (at your option) any later version.
12 : : *
13 : : * This program is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : * GNU General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU General Public License
19 : : * along with this program; if not, write to the Free Software
20 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21 : : * USA
22 : : */
23 : :
24 : : #include <config.h>
25 : :
26 : : #include "api_nodb.h"
27 : :
28 : : #include <xapian.h>
29 : :
30 : : #include "apitest.h"
31 : : #include "testsuite.h"
32 : : #include "testutils.h"
33 : : #include "utils.h"
34 : :
35 : : #include "autoptr.h"
36 : : #include <list>
37 : : #include <string>
38 : : #include <vector>
39 : :
40 : : using namespace std;
41 : :
42 : : // always succeeds
43 : 1 : DEFINE_TESTCASE(trivial1, !backend) {
44 : 1 : return true;
45 : : }
46 : :
47 : : // tests that get_query_terms() returns the terms in the right order
48 : 1 : DEFINE_TESTCASE(getqterms1, !backend) {
49 : 1 : list<string> answers_list;
50 : 1 : answers_list.push_back("one");
51 : 1 : answers_list.push_back("two");
52 : 1 : answers_list.push_back("three");
53 : 1 : answers_list.push_back("four");
54 : :
55 : : Xapian::Query myquery(Xapian::Query::OP_OR,
56 : : Xapian::Query(Xapian::Query::OP_AND,
57 : : Xapian::Query("one", 1, 1),
58 : : Xapian::Query("three", 1, 3)),
59 : : Xapian::Query(Xapian::Query::OP_OR,
60 : : Xapian::Query("four", 1, 4),
61 : 1 : Xapian::Query("two", 1, 2)));
62 : :
63 : 1 : list<string> list1;
64 : : {
65 : 1 : Xapian::TermIterator t;
66 [ + + ]: 5 : for (t = myquery.get_terms_begin(); t != myquery.get_terms_end(); ++t)
67 : 5 : list1.push_back(*t);
68 : : }
69 [ - + # # ]: 1 : TEST(list1 == answers_list);
70 : 1 : list<string> list2(myquery.get_terms_begin(), myquery.get_terms_end());
71 [ - + # # ]: 1 : TEST(list2 == answers_list);
72 : 1 : return true;
73 : : }
74 : :
75 : : // tests that get_query_terms() doesn't SEGV on an empty query
76 : : // (regression test for bug in 0.9.0)
77 : 1 : DEFINE_TESTCASE(getqterms2, !backend) {
78 : 1 : Xapian::Query empty_query;
79 [ - + ][ # # ]: 1 : TEST_EQUAL(empty_query.get_terms_begin(), empty_query.get_terms_end());
80 : 1 : return true;
81 : : }
82 : :
83 : : // tests that empty queries work correctly
84 : 1 : DEFINE_TESTCASE(emptyquery2, !backend) {
85 : : // test that Query::empty() is true for an empty query.
86 [ - + ][ # # ]: 1 : TEST(Xapian::Query().empty());
87 : : // test that an empty query has length 0
88 [ - + ][ # # ]: 1 : TEST(Xapian::Query().get_length() == 0);
89 : 1 : vector<Xapian::Query> v;
90 [ - + ][ # # ]: 1 : TEST(Xapian::Query(Xapian::Query::OP_OR, v.begin(), v.end()).empty());
91 [ - + ][ # # ]: 1 : TEST(Xapian::Query(Xapian::Query::OP_OR, v.begin(), v.end()).get_length() == 0);
92 : 1 : return true;
93 : : }
94 : :
95 : : /// Regression test for behaviour for an empty query with AND_NOT.
96 : 1 : DEFINE_TESTCASE(emptyquery3, !backend) {
97 : : static const Xapian::Query::op ops[] = {
98 : : Xapian::Query::OP_AND,
99 : : Xapian::Query::OP_OR,
100 : : Xapian::Query::OP_XOR,
101 : : Xapian::Query::OP_AND_MAYBE,
102 : : Xapian::Query::OP_AND_NOT
103 : : };
104 : :
105 [ + + ]: 6 : for (size_t i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i) {
106 : 5 : tout << "Testing op #" << i << endl;
107 : 5 : Xapian::Query empty;
108 : 5 : Xapian::Query q("test");
109 : 5 : Xapian::Query qcombine(ops[i], empty, q);
110 : 5 : tout << qcombine.get_description() << endl;
111 : 5 : Xapian::Query qcombine2(ops[i], q, empty);
112 : 5 : tout << qcombine2.get_description() << endl;
113 : : }
114 : :
115 : 1 : return true;
116 : : }
117 : :
118 : : // tests that query lengths are calculated correctly
119 : 1 : DEFINE_TESTCASE(querylen1, !backend) {
120 : : // test that a simple query has the right length
121 : 1 : Xapian::Query myquery;
122 : : myquery = Xapian::Query(Xapian::Query::OP_OR,
123 : : Xapian::Query("foo"),
124 : 1 : Xapian::Query("bar"));
125 : : myquery = Xapian::Query(Xapian::Query::OP_AND,
126 : : myquery,
127 : : Xapian::Query(Xapian::Query::OP_OR,
128 : : Xapian::Query("wibble"),
129 : 1 : Xapian::Query("spoon")));
130 : :
131 [ - + # # ]: 1 : TEST_EQUAL(myquery.get_length(), 4);
132 [ - + ][ # # ]: 1 : TEST(!myquery.empty());
133 : 1 : return true;
134 : : }
135 : :
136 : : // tests that query lengths are calculated correctly
137 : 1 : DEFINE_TESTCASE(querylen2, !backend) {
138 : : // test with an even bigger and strange query
139 : : string terms[3] = {
140 : : "foo",
141 : : "bar",
142 : : "baz"
143 [ # # ][ # # ]: 1 : };
144 : : Xapian::Query queries[3] = {
145 : : Xapian::Query("wibble"),
146 : : Xapian::Query("wobble"),
147 : : Xapian::Query(Xapian::Query::OP_OR, string("jelly"), string("belly"))
148 [ # # ][ # # ]: 1 : };
149 : :
150 : 1 : Xapian::Query myquery;
151 : 1 : vector<string> v1(terms, terms + 3);
152 : 1 : vector<Xapian::Query> v2(queries, queries + 3);
153 : 1 : vector<Xapian::Query *> v3;
154 : : AutoPtr<Xapian::Query> dynquery1(new Xapian::Query(Xapian::Query::OP_AND,
155 : : string("ball"),
156 : 1 : string("club")));
157 : 1 : AutoPtr<Xapian::Query> dynquery2(new Xapian::Query("ring"));
158 : 1 : v3.push_back(dynquery1.get());
159 : 1 : v3.push_back(dynquery2.get());
160 : :
161 : 1 : Xapian::Query myq1 = Xapian::Query(Xapian::Query::OP_AND, v1.begin(), v1.end());
162 : 1 : tout << "myq1=" << myq1 << "\n";
163 [ - + # # ]: 1 : TEST_EQUAL(myq1.get_length(), 3);
164 : :
165 : 1 : Xapian::Query myq2_1 = Xapian::Query(Xapian::Query::OP_OR, v2.begin(), v2.end());
166 : 1 : tout << "myq2_1=" << myq2_1 << "\n";
167 [ - + # # ]: 1 : TEST_EQUAL(myq2_1.get_length(), 4);
168 : :
169 : 1 : Xapian::Query myq2_2 = Xapian::Query(Xapian::Query::OP_AND, v3.begin(), v3.end());
170 : 1 : tout << "myq2_2=" << myq2_2 << "\n";
171 [ - + # # ]: 1 : TEST_EQUAL(myq2_2.get_length(), 3);
172 : :
173 : 1 : Xapian::Query myq2 = Xapian::Query(Xapian::Query::OP_OR, myq2_1, myq2_2);
174 : 1 : tout << "myq2=" << myq2 << "\n";
175 [ - + # # ]: 1 : TEST_EQUAL(myq2.get_length(), 7);
176 : :
177 : 1 : myquery = Xapian::Query(Xapian::Query::OP_OR, myq1, myq2);
178 : 1 : tout << "myquery=" << myquery << "\n";
179 [ - + # # ]: 1 : TEST_EQUAL(myquery.get_length(), 10);
180 : :
181 [ # # ][ + + ]: 7 : return true;
[ # # ][ + + ]
182 : : }
183 : :
184 : : // tests that queries validate correctly
185 : 1 : DEFINE_TESTCASE(queryvalid1, !backend) {
186 : 1 : vector<Xapian::Query> v1;
187 : : // Need two arguments
188 [ + - ][ - + ]: 2 : TEST_EXCEPTION(Xapian::InvalidArgumentError,
[ # # ][ - + ]
189 : : Xapian::Query(Xapian::Query::OP_AND_NOT, v1.begin(), v1.end()));
190 : 1 : tout << "ANDNOT () checked" << endl;
191 : 1 : v1.push_back(Xapian::Query("bad"));
192 [ + - ][ - + ]: 2 : TEST_EXCEPTION(Xapian::InvalidArgumentError,
[ # # ][ - + ]
193 : : Xapian::Query(Xapian::Query::OP_AND_NOT, v1.begin(), v1.end()));
194 : 1 : tout << "ANDNOT (\"bad\") checked" << endl;
195 : 1 : v1.clear();
196 : 1 : v1.push_back(Xapian::Query());
197 [ + - ][ - + ]: 2 : TEST_EXCEPTION(Xapian::InvalidArgumentError,
[ # # ][ - + ]
198 : : Xapian::Query(Xapian::Query::OP_AND_NOT, v1.begin(), v1.end()));
199 : 1 : tout << "ANDNOT (Xapian::Query()) checked" << endl;
200 : 1 : Xapian::Query q2(Xapian::Query::OP_XOR, Xapian::Query("foo"), Xapian::Query("bar"));
201 : 1 : tout << "XOR (\"foo\", \"bar\") checked" << endl;
202 : 1 : return true;
203 : : }
204 : :
205 : : // tests that collapsing of queries includes subqueries
206 : 1 : DEFINE_TESTCASE(subqcollapse1, !backend) {
207 : : Xapian::Query queries1[3] = {
208 : : Xapian::Query("wibble"),
209 : : Xapian::Query("wobble"),
210 : : Xapian::Query(Xapian::Query::OP_OR, string("jelly"), string("belly"))
211 [ # # ][ # # ]: 1 : };
212 : :
213 : : Xapian::Query queries2[3] = {
214 : : Xapian::Query(Xapian::Query::OP_AND, string("jelly"), string("belly")),
215 : : Xapian::Query("wibble"),
216 : : Xapian::Query("wobble")
217 [ # # ][ # # ]: 1 : };
218 : :
219 : 1 : vector<Xapian::Query> vec1(queries1, queries1 + 3);
220 : 1 : Xapian::Query myquery1(Xapian::Query::OP_OR, vec1.begin(), vec1.end());
221 [ - + ][ # # ]: 1 : TEST_EQUAL(myquery1.get_description(),
222 : : "Xapian::Query((wibble OR wobble OR jelly OR belly))");
223 : :
224 : 1 : vector<Xapian::Query> vec2(queries2, queries2 + 3);
225 : 1 : Xapian::Query myquery2(Xapian::Query::OP_AND, vec2.begin(), vec2.end());
226 [ - + ][ # # ]: 1 : TEST_EQUAL(myquery2.get_description(),
227 : : "Xapian::Query((jelly AND belly AND wibble AND wobble))");
228 : :
229 [ # # ][ + + ]: 7 : return true;
[ # # ][ + + ]
230 : : }
231 : :
232 : : // test behaviour when creating a query from an empty vector
233 : 1 : DEFINE_TESTCASE(emptyquerypart1, !backend) {
234 : 1 : vector<string> emptyterms;
235 : 1 : Xapian::Query query(Xapian::Query::OP_OR, emptyterms.begin(), emptyterms.end());
236 [ - + ][ # # ]: 1 : TEST(Xapian::Query(Xapian::Query::OP_AND, query, Xapian::Query("x")).empty());
237 [ - + ][ # # ]: 1 : TEST(Xapian::Query(Xapian::Query::OP_AND, query, Xapian::Query("x")).get_length() == 0);
238 [ - + ][ # # ]: 1 : TEST(!Xapian::Query(Xapian::Query::OP_OR, query, Xapian::Query("x")).empty());
239 [ - + ][ # # ]: 1 : TEST(Xapian::Query(Xapian::Query::OP_OR, query, Xapian::Query("x")).get_length() == 1);
240 : 1 : return true;
241 : : }
242 : :
243 : 1 : DEFINE_TESTCASE(singlesubq1, !backend) {
244 : 1 : vector<string> oneterm;
245 : 1 : oneterm.push_back("solo");
246 : 1 : Xapian::Query q_eliteset(Xapian::Query::OP_ELITE_SET, oneterm.begin(), oneterm.end(), 1);
247 : 1 : Xapian::Query q_near(Xapian::Query::OP_NEAR, oneterm.begin(), oneterm.end(), 1);
248 : 1 : Xapian::Query q_phrase(Xapian::Query::OP_PHRASE, oneterm.begin(), oneterm.end(), 1);
249 : 1 : return true;
250 : : }
251 : :
252 : 1 : DEFINE_TESTCASE(stemlangs1, !backend) {
253 : 1 : string langs = Xapian::Stem::get_available_languages();
254 : 1 : tout << "available languages '" << langs << "'" << endl;
255 [ - + # # ]: 1 : TEST(!langs.empty());
256 : :
257 : : // Also test the language codes and none.
258 : 1 : langs += " da nl en fi fr de hu it no pt ro ru es sv tr none";
259 : :
260 : 1 : string::size_type i = 0;
261 [ + + ][ + + ]: 35 : while (true) {
262 : 35 : string::size_type spc = langs.find(' ', i);
263 : : // The only spaces in langs should be a single one between each pair
264 : : // of language names.
265 [ - + # # ]: 35 : TEST_NOT_EQUAL(i, spc);
266 : :
267 : : // Try making a stemmer for this language. We should be able to create
268 : : // it without an exception being thrown.
269 : 35 : string language = langs.substr(i, spc - i);
270 : 35 : tout << "checking language code '" << language << "' works" << endl;
271 : 35 : Xapian::Stem stemmer(language);
272 [ + + ]: 35 : if (language.size() > 2) {
273 : 20 : string expected("Xapian::Stem(");
274 : 20 : expected += language;
275 : 20 : expected += ')';
276 [ - + ][ # # ]: 20 : TEST_EQUAL(stemmer.get_description(), expected);
277 : : }
278 : :
279 [ + + ]: 35 : if (spc == string::npos) break;
280 : 34 : i = spc + 1;
281 : : }
282 : :
283 : : // Stem("") should give an object which doesn't change any input.
284 : 1 : Xapian::Stem stem_nothing = Xapian::Stem("");
285 [ - + ][ # # ]: 1 : TEST_EQUAL(stem_nothing.get_description(), "Xapian::Stem(none)");
286 : :
287 : 1 : return true;
288 : : }
289 : :
290 : : // Some simple tests of the built in weighting schemes.
291 : 1 : DEFINE_TESTCASE(weight1, !backend) {
292 : : Xapian::Weight * wt;
293 : :
294 : 1 : Xapian::BoolWeight boolweight;
295 [ - + ][ # # ]: 1 : TEST_EQUAL(boolweight.name(), "Xapian::BoolWeight");
296 : 1 : wt = Xapian::BoolWeight().unserialise(boolweight.serialise());
297 [ - + ][ # # ]: 1 : TEST_EQUAL(boolweight.serialise(), wt->serialise());
298 [ + - ]: 1 : delete wt;
299 : :
300 : 1 : Xapian::TradWeight tradweight_dflt;
301 : 1 : Xapian::TradWeight tradweight(1.0);
302 [ - + ][ # # ]: 1 : TEST_EQUAL(tradweight.name(), "Xapian::TradWeight");
303 [ - + ][ # # ]: 1 : TEST_EQUAL(tradweight_dflt.serialise(), tradweight.serialise());
304 : 1 : wt = Xapian::TradWeight().unserialise(tradweight.serialise());
305 [ - + ][ # # ]: 1 : TEST_EQUAL(tradweight.serialise(), wt->serialise());
306 [ + - ]: 1 : delete wt;
307 : :
308 : 1 : Xapian::TradWeight tradweight2(2.0);
309 [ - + ][ # # ]: 1 : TEST_NOT_EQUAL(tradweight.serialise(), tradweight2.serialise());
310 : :
311 : 1 : Xapian::BM25Weight bm25weight_dflt;
312 : 1 : Xapian::BM25Weight bm25weight(1, 0, 1, 0.5, 0.5);
313 [ - + ][ # # ]: 1 : TEST_EQUAL(bm25weight.name(), "Xapian::BM25Weight");
314 [ - + ][ # # ]: 1 : TEST_EQUAL(bm25weight_dflt.serialise(), bm25weight.serialise());
315 : 1 : wt = Xapian::BM25Weight().unserialise(bm25weight.serialise());
316 [ - + ][ # # ]: 1 : TEST_EQUAL(bm25weight.serialise(), wt->serialise());
317 [ + - ]: 1 : delete wt;
318 : :
319 : 1 : Xapian::BM25Weight bm25weight2(1, 0.5, 1, 0.5, 0.5);
320 [ - + ][ # # ]: 1 : TEST_NOT_EQUAL(bm25weight.serialise(), bm25weight2.serialise());
321 : :
322 : 1 : return true;
323 : : }
324 : :
325 : : // Regression test.
326 : 1 : DEFINE_TESTCASE(nosuchdb1, !backend) {
327 : : // This is a "nodb" test because it doesn't test a particular backend.
328 : : try {
329 : 3 : Xapian::Database db("NOsuChdaTabASe");
330 : 2 : } catch (const Xapian::DatabaseOpeningError & e) {
331 : : // We don't really require this exact message, but in Xapian <= 1.1.0
332 : : // this gave "Couldn't detect type of database".
333 [ - + ][ # # ]: 1 : TEST_STRINGS_EQUAL(e.get_msg(), "Couldn't stat 'NOsuChdaTabASe'");
334 : : }
335 : :
336 : 1 : return true;
337 : : }
338 : :
339 : : // Feature tests for value manipulations.
340 : 1 : DEFINE_TESTCASE(addvalue1, !backend) {
341 : : // Regression test for add_value on an existing value (bug#82).
342 : 1 : Xapian::Document doc;
343 : 1 : doc.add_value(1, "original");
344 : 1 : doc.add_value(1, "replacement");
345 [ - + ][ # # ]: 1 : TEST_EQUAL(doc.get_value(1), "replacement");
346 : :
347 : 1 : doc.add_value(2, "too");
348 : 1 : doc.add_value(3, "free");
349 : 1 : doc.add_value(4, "for");
350 : :
351 : 1 : doc.remove_value(2);
352 : 1 : doc.remove_value(4);
353 [ - + ][ # # ]: 1 : TEST_EQUAL(doc.get_value(0), "");
354 [ - + ][ # # ]: 1 : TEST_EQUAL(doc.get_value(1), "replacement");
355 [ - + ][ # # ]: 1 : TEST_EQUAL(doc.get_value(2), "");
356 [ - + ][ # # ]: 1 : TEST_EQUAL(doc.get_value(3), "free");
357 [ - + ][ # # ]: 1 : TEST_EQUAL(doc.get_value(4), "");
358 : :
359 : 1 : return true;
360 : : }
361 : :
362 : : // tests that the collapsing on termpos optimisation gives correct query length
363 : 1 : DEFINE_TESTCASE(poscollapse2, !backend) {
364 : 1 : Xapian::Query q(Xapian::Query::OP_OR, Xapian::Query("this", 1, 1), Xapian::Query("this", 1, 1));
365 [ - + # # ]: 1 : TEST_EQUAL(q.get_length(), 2);
366 : 1 : return true;
367 : : }
368 : :
369 : : // regression test of querying an uninitialised database: should report an
370 : : // error; used to segfault with 1.0.0.
371 : 1 : DEFINE_TESTCASE(uninitdb1, !backend) {
372 : 1 : Xapian::Database db;
373 [ + - ][ - + ]: 2 : TEST_EXCEPTION(Xapian::InvalidArgumentError,
[ # # ][ - + ]
374 : : Xapian::Enquire enq(db));
375 : 1 : return true;
376 : : }
377 : :
378 : : // Test a scaleweight query applied to a match nothing query
379 : 1 : DEFINE_TESTCASE(scaleweight3, !backend) {
380 : 1 : Xapian::Query matchnothing(Xapian::Query::MatchNothing);
381 : 1 : Xapian::Query query(Xapian::Query::OP_SCALE_WEIGHT, matchnothing, 3.0);
382 [ - + ][ # # ]: 1 : TEST_EQUAL(query.get_description(), "Xapian::Query()");
383 : 1 : return true;
384 : : }
385 : :
386 : : // Test that scaling by a weight close to 1 is optimised away.
387 : 1 : DEFINE_TESTCASE(scaleweight4, !backend) {
388 : : // Factor is a double which, when multiplied by its reciprocal, doesn't
389 : : // give exactly 1.0
390 : 1 : double factor = 179.76931348623157e306;
391 : 1 : volatile double recip = 1.0 / factor;
392 : 1 : double nearly1 = factor * recip;
393 : :
394 [ - + ][ # # ]: 1 : TEST_NOT_EQUAL(nearly1, 1.0);
395 : 1 : Xapian::Query foo("foo");
396 : 1 : Xapian::Query foo_nearly1(Xapian::Query::OP_SCALE_WEIGHT, foo, nearly1);
397 [ - + ][ # # ]: 1 : TEST_EQUAL(foo_nearly1.get_description(), "Xapian::Query(foo)");
398 : :
399 : 1 : return true;
400 : : }
401 : :
402 : : // Regression test - before 1.1.0, you could add docid 0 to an RSet.
403 : 1 : DEFINE_TESTCASE(rset3, !backend) {
404 : 1 : Xapian::RSet rset;
405 [ + - ][ - + ]: 2 : TEST_EXCEPTION(Xapian::InvalidArgumentError, rset.add_document(0));
[ # # ][ - + ]
406 [ - + # # ]: 1 : TEST(rset.empty());
407 [ - + ][ # # ]: 1 : TEST_EQUAL(rset.size(), 0);
408 : 1 : rset.add_document(1);
409 : 1 : rset.add_document(static_cast<Xapian::docid>(-1));
410 [ + - ][ - + ]: 2 : TEST_EXCEPTION(Xapian::InvalidArgumentError, rset.add_document(0));
[ # # ][ - + ]
411 [ - + # # ]: 1 : TEST(!rset.empty());
412 [ - + ][ # # ]: 1 : TEST_EQUAL(rset.size(), 2);
413 : 1 : return true;
414 : : }
415 : :
416 : : // Regression test - RSet::get_description() gave a malformed answer in 1.0.7.
417 : 1 : DEFINE_TESTCASE(rset4, !backend) {
418 : 1 : Xapian::RSet rset;
419 : 1 : rset.add_document(1);
420 : : // In 1.0.7 this gave: RSet(RSet(RSet::Internal(, 1))
421 [ - + ][ # # ]: 1 : TEST_STRINGS_EQUAL(rset.get_description(), "RSet(RSet::Internal(1))");
422 : 1 : return true;
423 : : }
424 : :
425 : : // Direct test of ValueSetMatchDecider
426 : 1 : DEFINE_TESTCASE(valuesetmatchdecider1, !backend) {
427 : 1 : Xapian::ValueSetMatchDecider vsmd1(0, true);
428 : 1 : vsmd1.add_value("42");
429 : 1 : Xapian::ValueSetMatchDecider vsmd2(0, false);
430 : 1 : vsmd2.remove_value("nosuch"); // Test removing a value which isn't present.
431 : 1 : vsmd2.add_value("42");
432 : 1 : Xapian::ValueSetMatchDecider vsmd3(0, true);
433 : 1 : vsmd3.add_value("42");
434 : 1 : vsmd3.add_value("blah");
435 : :
436 : 1 : Xapian::Document doc;
437 [ - + # # ]: 1 : TEST(!vsmd1(doc));
438 [ - + ][ # # ]: 1 : TEST(vsmd2(doc));
439 [ - + ][ # # ]: 1 : TEST(!vsmd3(doc));
440 : 1 : doc.add_value(0, "42");
441 [ - + # # ]: 1 : TEST(vsmd1(doc));
442 [ - + ][ # # ]: 1 : TEST(!vsmd2(doc));
443 [ - + ][ # # ]: 1 : TEST(vsmd3(doc));
444 : 1 : doc.add_value(0, "blah");
445 [ - + # # ]: 1 : TEST(!vsmd1(doc));
446 [ - + ][ # # ]: 1 : TEST(vsmd2(doc));
447 [ - + ][ # # ]: 1 : TEST(vsmd3(doc));
448 : :
449 : 1 : vsmd3.remove_value("nosuch"); // Test removing a value which isn't present.
450 : 1 : vsmd3.remove_value("blah");
451 [ - + # # ]: 1 : TEST(!vsmd1(doc));
452 [ - + ][ # # ]: 1 : TEST(vsmd2(doc));
453 [ - + ][ # # ]: 1 : TEST(!vsmd3(doc));
454 : 1 : doc.add_value(0, "42");
455 [ - + # # ]: 1 : TEST(vsmd1(doc));
456 [ - + ][ # # ]: 1 : TEST(!vsmd2(doc));
457 [ - + ][ # # ]: 1 : TEST(vsmd3(doc));
458 : :
459 : 1 : return true;
460 : : }
461 : :
462 : : // Test that asking for the termfreq on an empty mset raises an exception.
463 : 1 : DEFINE_TESTCASE(emptymset1, !backend) {
464 : 1 : Xapian::MSet emptymset;
465 [ + - ][ - + ]: 4 : TEST_EXCEPTION(Xapian::InvalidOperationError,
[ # # ][ - + ]
466 : : emptymset.get_termfreq("foo"));
467 : 1 : return true;
468 : : }
|