00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025
00026 #include "api_nodb.h"
00027
00028 #include <xapian.h>
00029
00030 #include "apitest.h"
00031 #include "testsuite.h"
00032 #include "testutils.h"
00033 #include "utils.h"
00034
00035 #include "autoptr.h"
00036 #include <list>
00037 #include <string>
00038 #include <vector>
00039
00040 using namespace std;
00041
00042
00043 DEFINE_TESTCASE(trivial1, !backend) {
00044 return true;
00045 }
00046
00047
00048 DEFINE_TESTCASE(getqterms1, !backend) {
00049 list<string> answers_list;
00050 answers_list.push_back("one");
00051 answers_list.push_back("two");
00052 answers_list.push_back("three");
00053 answers_list.push_back("four");
00054
00055 Xapian::Query myquery(Xapian::Query::OP_OR,
00056 Xapian::Query(Xapian::Query::OP_AND,
00057 Xapian::Query("one", 1, 1),
00058 Xapian::Query("three", 1, 3)),
00059 Xapian::Query(Xapian::Query::OP_OR,
00060 Xapian::Query("four", 1, 4),
00061 Xapian::Query("two", 1, 2)));
00062
00063 list<string> list1;
00064 {
00065 Xapian::TermIterator t;
00066 for (t = myquery.get_terms_begin(); t != myquery.get_terms_end(); ++t)
00067 list1.push_back(*t);
00068 }
00069 TEST(list1 == answers_list);
00070 list<string> list2(myquery.get_terms_begin(), myquery.get_terms_end());
00071 TEST(list2 == answers_list);
00072 return true;
00073 }
00074
00075
00076
00077 DEFINE_TESTCASE(getqterms2, !backend) {
00078 Xapian::Query empty_query;
00079 TEST_EQUAL(empty_query.get_terms_begin(), empty_query.get_terms_end());
00080 return true;
00081 }
00082
00083
00084 DEFINE_TESTCASE(emptyquery2, !backend) {
00085
00086 TEST(Xapian::Query().empty());
00087
00088 TEST(Xapian::Query().get_length() == 0);
00089 vector<Xapian::Query> v;
00090 TEST(Xapian::Query(Xapian::Query::OP_OR, v.begin(), v.end()).empty());
00091 TEST(Xapian::Query(Xapian::Query::OP_OR, v.begin(), v.end()).get_length() == 0);
00092 return true;
00093 }
00094
00096 DEFINE_TESTCASE(emptyquery3, !backend) {
00097 static const Xapian::Query::op ops[] = {
00098 Xapian::Query::OP_AND,
00099 Xapian::Query::OP_OR,
00100 Xapian::Query::OP_XOR,
00101 Xapian::Query::OP_AND_MAYBE,
00102 Xapian::Query::OP_AND_NOT
00103 };
00104
00105 for (size_t i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i) {
00106 tout << "Testing op #" << i << endl;
00107 Xapian::Query empty;
00108 Xapian::Query q("test");
00109 Xapian::Query qcombine(ops[i], empty, q);
00110 tout << qcombine.get_description() << endl;
00111 Xapian::Query qcombine2(ops[i], q, empty);
00112 tout << qcombine2.get_description() << endl;
00113 }
00114
00115 return true;
00116 }
00117
00118
00119 DEFINE_TESTCASE(querylen1, !backend) {
00120
00121 Xapian::Query myquery;
00122 myquery = Xapian::Query(Xapian::Query::OP_OR,
00123 Xapian::Query("foo"),
00124 Xapian::Query("bar"));
00125 myquery = Xapian::Query(Xapian::Query::OP_AND,
00126 myquery,
00127 Xapian::Query(Xapian::Query::OP_OR,
00128 Xapian::Query("wibble"),
00129 Xapian::Query("spoon")));
00130
00131 TEST_EQUAL(myquery.get_length(), 4);
00132 TEST(!myquery.empty());
00133 return true;
00134 }
00135
00136
00137 DEFINE_TESTCASE(querylen2, !backend) {
00138
00139 string terms[3] = {
00140 "foo",
00141 "bar",
00142 "baz"
00143 };
00144 Xapian::Query queries[3] = {
00145 Xapian::Query("wibble"),
00146 Xapian::Query("wobble"),
00147 Xapian::Query(Xapian::Query::OP_OR, string("jelly"), string("belly"))
00148 };
00149
00150 Xapian::Query myquery;
00151 vector<string> v1(terms, terms + 3);
00152 vector<Xapian::Query> v2(queries, queries + 3);
00153 vector<Xapian::Query *> v3;
00154 AutoPtr<Xapian::Query> dynquery1(new Xapian::Query(Xapian::Query::OP_AND,
00155 string("ball"),
00156 string("club")));
00157 AutoPtr<Xapian::Query> dynquery2(new Xapian::Query("ring"));
00158 v3.push_back(dynquery1.get());
00159 v3.push_back(dynquery2.get());
00160
00161 Xapian::Query myq1 = Xapian::Query(Xapian::Query::OP_AND, v1.begin(), v1.end());
00162 tout << "myq1=" << myq1 << "\n";
00163 TEST_EQUAL(myq1.get_length(), 3);
00164
00165 Xapian::Query myq2_1 = Xapian::Query(Xapian::Query::OP_OR, v2.begin(), v2.end());
00166 tout << "myq2_1=" << myq2_1 << "\n";
00167 TEST_EQUAL(myq2_1.get_length(), 4);
00168
00169 Xapian::Query myq2_2 = Xapian::Query(Xapian::Query::OP_AND, v3.begin(), v3.end());
00170 tout << "myq2_2=" << myq2_2 << "\n";
00171 TEST_EQUAL(myq2_2.get_length(), 3);
00172
00173 Xapian::Query myq2 = Xapian::Query(Xapian::Query::OP_OR, myq2_1, myq2_2);
00174 tout << "myq2=" << myq2 << "\n";
00175 TEST_EQUAL(myq2.get_length(), 7);
00176
00177 myquery = Xapian::Query(Xapian::Query::OP_OR, myq1, myq2);
00178 tout << "myquery=" << myquery << "\n";
00179 TEST_EQUAL(myquery.get_length(), 10);
00180
00181 return true;
00182 }
00183
00184
00185 DEFINE_TESTCASE(queryvalid1, !backend) {
00186 vector<Xapian::Query> v1;
00187
00188 TEST_EXCEPTION(Xapian::InvalidArgumentError,
00189 Xapian::Query(Xapian::Query::OP_AND_NOT, v1.begin(), v1.end()));
00190 tout << "ANDNOT () checked" << endl;
00191 v1.push_back(Xapian::Query("bad"));
00192 TEST_EXCEPTION(Xapian::InvalidArgumentError,
00193 Xapian::Query(Xapian::Query::OP_AND_NOT, v1.begin(), v1.end()));
00194 tout << "ANDNOT (\"bad\") checked" << endl;
00195 v1.clear();
00196 v1.push_back(Xapian::Query());
00197 TEST_EXCEPTION(Xapian::InvalidArgumentError,
00198 Xapian::Query(Xapian::Query::OP_AND_NOT, v1.begin(), v1.end()));
00199 tout << "ANDNOT (Xapian::Query()) checked" << endl;
00200 Xapian::Query q2(Xapian::Query::OP_XOR, Xapian::Query("foo"), Xapian::Query("bar"));
00201 tout << "XOR (\"foo\", \"bar\") checked" << endl;
00202 return true;
00203 }
00204
00205
00206 DEFINE_TESTCASE(subqcollapse1, !backend) {
00207 Xapian::Query queries1[3] = {
00208 Xapian::Query("wibble"),
00209 Xapian::Query("wobble"),
00210 Xapian::Query(Xapian::Query::OP_OR, string("jelly"), string("belly"))
00211 };
00212
00213 Xapian::Query queries2[3] = {
00214 Xapian::Query(Xapian::Query::OP_AND, string("jelly"), string("belly")),
00215 Xapian::Query("wibble"),
00216 Xapian::Query("wobble")
00217 };
00218
00219 vector<Xapian::Query> vec1(queries1, queries1 + 3);
00220 Xapian::Query myquery1(Xapian::Query::OP_OR, vec1.begin(), vec1.end());
00221 TEST_EQUAL(myquery1.get_description(),
00222 "Xapian::Query((wibble OR wobble OR jelly OR belly))");
00223
00224 vector<Xapian::Query> vec2(queries2, queries2 + 3);
00225 Xapian::Query myquery2(Xapian::Query::OP_AND, vec2.begin(), vec2.end());
00226 TEST_EQUAL(myquery2.get_description(),
00227 "Xapian::Query((jelly AND belly AND wibble AND wobble))");
00228
00229 return true;
00230 }
00231
00232
00233 DEFINE_TESTCASE(emptyquerypart1, !backend) {
00234 vector<string> emptyterms;
00235 Xapian::Query query(Xapian::Query::OP_OR, emptyterms.begin(), emptyterms.end());
00236 TEST(Xapian::Query(Xapian::Query::OP_AND, query, Xapian::Query("x")).empty());
00237 TEST(Xapian::Query(Xapian::Query::OP_AND, query, Xapian::Query("x")).get_length() == 0);
00238 TEST(!Xapian::Query(Xapian::Query::OP_OR, query, Xapian::Query("x")).empty());
00239 TEST(Xapian::Query(Xapian::Query::OP_OR, query, Xapian::Query("x")).get_length() == 1);
00240 return true;
00241 }
00242
00243 DEFINE_TESTCASE(singlesubq1, !backend) {
00244 vector<string> oneterm;
00245 oneterm.push_back("solo");
00246 Xapian::Query q_eliteset(Xapian::Query::OP_ELITE_SET, oneterm.begin(), oneterm.end(), 1);
00247 Xapian::Query q_near(Xapian::Query::OP_NEAR, oneterm.begin(), oneterm.end(), 1);
00248 Xapian::Query q_phrase(Xapian::Query::OP_PHRASE, oneterm.begin(), oneterm.end(), 1);
00249 return true;
00250 }
00251
00252 DEFINE_TESTCASE(stemlangs1, !backend) {
00253 string langs = Xapian::Stem::get_available_languages();
00254 tout << "available languages '" << langs << "'" << endl;
00255 TEST(!langs.empty());
00256
00257
00258 langs += " da nl en fi fr de hu it no pt ro ru es sv tr none";
00259
00260 string::size_type i = 0;
00261 while (true) {
00262 string::size_type spc = langs.find(' ', i);
00263
00264
00265 TEST_NOT_EQUAL(i, spc);
00266
00267
00268
00269 string language = langs.substr(i, spc - i);
00270 tout << "checking language code '" << language << "' works" << endl;
00271 Xapian::Stem stemmer(language);
00272 if (language.size() > 2) {
00273 string expected("Xapian::Stem(");
00274 expected += language;
00275 expected += ')';
00276 TEST_EQUAL(stemmer.get_description(), expected);
00277 }
00278
00279 if (spc == string::npos) break;
00280 i = spc + 1;
00281 }
00282
00283
00284 Xapian::Stem stem_nothing = Xapian::Stem("");
00285 TEST_EQUAL(stem_nothing.get_description(), "Xapian::Stem(none)");
00286
00287 return true;
00288 }
00289
00290
00291 DEFINE_TESTCASE(weight1, !backend) {
00292 Xapian::Weight * wt;
00293
00294 Xapian::BoolWeight boolweight;
00295 TEST_EQUAL(boolweight.name(), "Xapian::BoolWeight");
00296 wt = Xapian::BoolWeight().unserialise(boolweight.serialise());
00297 TEST_EQUAL(boolweight.serialise(), wt->serialise());
00298 delete wt;
00299
00300 Xapian::TradWeight tradweight_dflt;
00301 Xapian::TradWeight tradweight(1.0);
00302 TEST_EQUAL(tradweight.name(), "Xapian::TradWeight");
00303 TEST_EQUAL(tradweight_dflt.serialise(), tradweight.serialise());
00304 wt = Xapian::TradWeight().unserialise(tradweight.serialise());
00305 TEST_EQUAL(tradweight.serialise(), wt->serialise());
00306 delete wt;
00307
00308 Xapian::TradWeight tradweight2(2.0);
00309 TEST_NOT_EQUAL(tradweight.serialise(), tradweight2.serialise());
00310
00311 Xapian::BM25Weight bm25weight_dflt;
00312 Xapian::BM25Weight bm25weight(1, 0, 1, 0.5, 0.5);
00313 TEST_EQUAL(bm25weight.name(), "Xapian::BM25Weight");
00314 TEST_EQUAL(bm25weight_dflt.serialise(), bm25weight.serialise());
00315 wt = Xapian::BM25Weight().unserialise(bm25weight.serialise());
00316 TEST_EQUAL(bm25weight.serialise(), wt->serialise());
00317 delete wt;
00318
00319 Xapian::BM25Weight bm25weight2(1, 0.5, 1, 0.5, 0.5);
00320 TEST_NOT_EQUAL(bm25weight.serialise(), bm25weight2.serialise());
00321
00322 return true;
00323 }
00324
00325
00326 DEFINE_TESTCASE(nosuchdb1, !backend) {
00327
00328 try {
00329 Xapian::Database db("NOsuChdaTabASe");
00330 } catch (const Xapian::DatabaseOpeningError & e) {
00331
00332
00333 TEST_STRINGS_EQUAL(e.get_msg(), "Couldn't stat 'NOsuChdaTabASe'");
00334 }
00335
00336 return true;
00337 }
00338
00339
00340 DEFINE_TESTCASE(addvalue1, !backend) {
00341
00342 Xapian::Document doc;
00343 doc.add_value(1, "original");
00344 doc.add_value(1, "replacement");
00345 TEST_EQUAL(doc.get_value(1), "replacement");
00346
00347 doc.add_value(2, "too");
00348 doc.add_value(3, "free");
00349 doc.add_value(4, "for");
00350
00351 doc.remove_value(2);
00352 doc.remove_value(4);
00353 TEST_EQUAL(doc.get_value(0), "");
00354 TEST_EQUAL(doc.get_value(1), "replacement");
00355 TEST_EQUAL(doc.get_value(2), "");
00356 TEST_EQUAL(doc.get_value(3), "free");
00357 TEST_EQUAL(doc.get_value(4), "");
00358
00359 return true;
00360 }
00361
00362
00363 DEFINE_TESTCASE(poscollapse2, !backend) {
00364 Xapian::Query q(Xapian::Query::OP_OR, Xapian::Query("this", 1, 1), Xapian::Query("this", 1, 1));
00365 TEST_EQUAL(q.get_length(), 2);
00366 return true;
00367 }
00368
00369
00370
00371 DEFINE_TESTCASE(uninitdb1, !backend) {
00372 Xapian::Database db;
00373 TEST_EXCEPTION(Xapian::InvalidArgumentError,
00374 Xapian::Enquire enq(db));
00375 return true;
00376 }
00377
00378
00379 DEFINE_TESTCASE(scaleweight3, !backend) {
00380 Xapian::Query matchnothing(Xapian::Query::MatchNothing);
00381 Xapian::Query query(Xapian::Query::OP_SCALE_WEIGHT, matchnothing, 3.0);
00382 TEST_EQUAL(query.get_description(), "Xapian::Query()");
00383 return true;
00384 }
00385
00386
00387 DEFINE_TESTCASE(scaleweight4, !backend) {
00388
00389
00390 double factor = 179.76931348623157e306;
00391 volatile double recip = 1.0 / factor;
00392 double nearly1 = factor * recip;
00393
00394 TEST_NOT_EQUAL(nearly1, 1.0);
00395 Xapian::Query foo("foo");
00396 Xapian::Query foo_nearly1(Xapian::Query::OP_SCALE_WEIGHT, foo, nearly1);
00397 TEST_EQUAL(foo_nearly1.get_description(), "Xapian::Query(foo)");
00398
00399 return true;
00400 }
00401
00402
00403 DEFINE_TESTCASE(rset3, !backend) {
00404 Xapian::RSet rset;
00405 TEST_EXCEPTION(Xapian::InvalidArgumentError, rset.add_document(0));
00406 TEST(rset.empty());
00407 TEST_EQUAL(rset.size(), 0);
00408 rset.add_document(1);
00409 rset.add_document(static_cast<Xapian::docid>(-1));
00410 TEST_EXCEPTION(Xapian::InvalidArgumentError, rset.add_document(0));
00411 TEST(!rset.empty());
00412 TEST_EQUAL(rset.size(), 2);
00413 return true;
00414 }
00415
00416
00417 DEFINE_TESTCASE(rset4, !backend) {
00418 Xapian::RSet rset;
00419 rset.add_document(1);
00420
00421 TEST_STRINGS_EQUAL(rset.get_description(), "RSet(RSet::Internal(1))");
00422 return true;
00423 }
00424
00425
00426 DEFINE_TESTCASE(valuesetmatchdecider1, !backend) {
00427 Xapian::ValueSetMatchDecider vsmd1(0, true);
00428 vsmd1.add_value("42");
00429 Xapian::ValueSetMatchDecider vsmd2(0, false);
00430 vsmd2.remove_value("nosuch");
00431 vsmd2.add_value("42");
00432 Xapian::ValueSetMatchDecider vsmd3(0, true);
00433 vsmd3.add_value("42");
00434 vsmd3.add_value("blah");
00435
00436 Xapian::Document doc;
00437 TEST(!vsmd1(doc));
00438 TEST(vsmd2(doc));
00439 TEST(!vsmd3(doc));
00440 doc.add_value(0, "42");
00441 TEST(vsmd1(doc));
00442 TEST(!vsmd2(doc));
00443 TEST(vsmd3(doc));
00444 doc.add_value(0, "blah");
00445 TEST(!vsmd1(doc));
00446 TEST(vsmd2(doc));
00447 TEST(vsmd3(doc));
00448
00449 vsmd3.remove_value("nosuch");
00450 vsmd3.remove_value("blah");
00451 TEST(!vsmd1(doc));
00452 TEST(vsmd2(doc));
00453 TEST(!vsmd3(doc));
00454 doc.add_value(0, "42");
00455 TEST(vsmd1(doc));
00456 TEST(!vsmd2(doc));
00457 TEST(vsmd3(doc));
00458
00459 return true;
00460 }
00461
00462
00463 DEFINE_TESTCASE(emptymset1, !backend) {
00464 Xapian::MSet emptymset;
00465 TEST_EXCEPTION(Xapian::InvalidOperationError,
00466 emptymset.get_termfreq("foo"));
00467 return true;
00468 }