"Fossies" - the Fresh Open Source Software Archive

Member "xapian-core-1.4.14/tests/api_nodb.cc" (23 Nov 2019, 20382 Bytes) of package /linux/www/xapian-core-1.4.14.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "api_nodb.cc": 1.4.13_vs_1.4.14.

    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,2015,2016,2017,2019 Olly Betts
    6  * Copyright 2006 Lemur Consulting Ltd
    7  * Copyright (C) 2016 Vivek Pal
    8  *
    9  * This program is free software; you can redistribute it and/or
   10  * modify it under the terms of the GNU General Public License as
   11  * published by the Free Software Foundation; either version 2 of the
   12  * License, or (at your option) any later version.
   13  *
   14  * This program is distributed in the hope that it will be useful,
   15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17  * GNU General Public License for more details.
   18  *
   19  * You should have received a copy of the GNU General Public License
   20  * along with this program; if not, write to the Free Software
   21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
   22  * USA
   23  */
   24 
   25 #include <config.h>
   26 
   27 #include "api_nodb.h"
   28 
   29 #include <xapian.h>
   30 
   31 #include "apitest.h"
   32 #include "testsuite.h"
   33 #include "testutils.h"
   34 
   35 #include <list>
   36 #include <string>
   37 #include <vector>
   38 
   39 using namespace std;
   40 
   41 // always succeeds
   42 DEFINE_TESTCASE(trivial1, !backend) {
   43     return true;
   44 }
   45 
   46 // tests that get_query_terms() returns the terms in the right order
   47 DEFINE_TESTCASE(getqterms1, !backend) {
   48     list<string> answers_list;
   49     answers_list.push_back("one");
   50     answers_list.push_back("two");
   51     answers_list.push_back("three");
   52     answers_list.push_back("four");
   53 
   54     Xapian::Query myquery(Xapian::Query::OP_OR,
   55         Xapian::Query(Xapian::Query::OP_AND,
   56             Xapian::Query("one", 1, 1),
   57             Xapian::Query("three", 1, 3)),
   58         Xapian::Query(Xapian::Query::OP_OR,
   59             Xapian::Query("four", 1, 4),
   60             Xapian::Query("two", 1, 2)));
   61 
   62     list<string> list1;
   63     {
   64     Xapian::TermIterator t;
   65     for (t = myquery.get_terms_begin(); t != myquery.get_terms_end(); ++t)
   66         list1.push_back(*t);
   67     }
   68     TEST(list1 == answers_list);
   69     list<string> list2(myquery.get_terms_begin(), myquery.get_terms_end());
   70     TEST(list2 == answers_list);
   71     return true;
   72 }
   73 
   74 // tests that get_query_terms() doesn't SEGV on an empty query
   75 // (regression test for bug in 0.9.0)
   76 DEFINE_TESTCASE(getqterms2, !backend) {
   77     Xapian::Query empty_query;
   78     TEST_EQUAL(empty_query.get_terms_begin(), empty_query.get_terms_end());
   79     TEST_EQUAL(empty_query.get_unique_terms_begin(),
   80            empty_query.get_unique_terms_end());
   81     return true;
   82 }
   83 
   84 // tests that empty queries work correctly
   85 DEFINE_TESTCASE(emptyquery2, !backend) {
   86     // test that Query::empty() is true for an empty query.
   87     TEST(Xapian::Query().empty());
   88     // test that an empty query has length 0
   89     TEST(Xapian::Query().get_length() == 0);
   90     vector<Xapian::Query> v;
   91     TEST(Xapian::Query(Xapian::Query::OP_OR, v.begin(), v.end()).empty());
   92     TEST(Xapian::Query(Xapian::Query::OP_OR, v.begin(), v.end()).get_length() == 0);
   93     return true;
   94 }
   95 
   96 /// Regression test for behaviour for an empty query with AND_NOT.
   97 DEFINE_TESTCASE(emptyquery3, !backend) {
   98     static const Xapian::Query::op ops[] = {
   99     Xapian::Query::OP_AND,
  100     Xapian::Query::OP_OR,
  101     Xapian::Query::OP_XOR,
  102     Xapian::Query::OP_AND_MAYBE,
  103     Xapian::Query::OP_AND_NOT
  104     };
  105 
  106     for (size_t i = 0; i < sizeof(ops) / sizeof(ops[0]); ++i) {
  107     tout << "Testing op #" << i << endl;
  108     Xapian::Query empty;
  109     Xapian::Query q("test");
  110     Xapian::Query qcombine(ops[i], empty, q);
  111     tout << qcombine.get_description() << endl;
  112     Xapian::Query qcombine2(ops[i], q, empty);
  113     tout << qcombine2.get_description() << endl;
  114     Xapian::Query qcombine3(ops[i], empty, empty);
  115     tout << qcombine3.get_description() << endl;
  116     }
  117 
  118     return true;
  119 }
  120 
  121 // tests that query lengths are calculated correctly
  122 DEFINE_TESTCASE(querylen1, !backend) {
  123     // test that a simple query has the right length
  124     Xapian::Query myquery;
  125     myquery = Xapian::Query(Xapian::Query::OP_OR,
  126               Xapian::Query("foo"),
  127               Xapian::Query("bar"));
  128     myquery = Xapian::Query(Xapian::Query::OP_AND,
  129               myquery,
  130               Xapian::Query(Xapian::Query::OP_OR,
  131                   Xapian::Query("wibble"),
  132                   Xapian::Query("spoon")));
  133 
  134     TEST_EQUAL(myquery.get_length(), 4);
  135     TEST(!myquery.empty());
  136     return true;
  137 }
  138 
  139 // tests that query lengths are calculated correctly
  140 DEFINE_TESTCASE(querylen2, !backend) {
  141     // test with an even bigger and strange query
  142     string terms[3] = {
  143     "foo",
  144     "bar",
  145     "baz"
  146     };
  147     Xapian::Query queries[3] = {
  148     Xapian::Query("wibble"),
  149     Xapian::Query("wobble"),
  150     Xapian::Query(Xapian::Query::OP_OR, string("jelly"), string("belly"))
  151     };
  152 
  153     Xapian::Query myquery;
  154     vector<string> v1(terms, terms + 3);
  155     vector<Xapian::Query> v2(queries, queries + 3);
  156     vector<Xapian::Query *> v3;
  157     Xapian::Query query1(Xapian::Query::OP_AND, string("ball"), string("club"));
  158     Xapian::Query query2("ring");
  159     v3.push_back(&query1);
  160     v3.push_back(&query2);
  161 
  162     Xapian::Query myq1 = Xapian::Query(Xapian::Query::OP_AND, v1.begin(), v1.end());
  163     tout << "myq1=" << myq1 << "\n";
  164     TEST_EQUAL(myq1.get_length(), 3);
  165 
  166     Xapian::Query myq2_1 = Xapian::Query(Xapian::Query::OP_OR, v2.begin(), v2.end());
  167     tout << "myq2_1=" << myq2_1 << "\n";
  168     TEST_EQUAL(myq2_1.get_length(), 4);
  169 
  170     Xapian::Query myq2_2 = Xapian::Query(Xapian::Query::OP_AND, v3.begin(), v3.end());
  171     tout << "myq2_2=" << myq2_2 << "\n";
  172     TEST_EQUAL(myq2_2.get_length(), 3);
  173 
  174     Xapian::Query myq2 = Xapian::Query(Xapian::Query::OP_OR, myq2_1, myq2_2);
  175     tout << "myq2=" << myq2 << "\n";
  176     TEST_EQUAL(myq2.get_length(), 7);
  177 
  178     myquery = Xapian::Query(Xapian::Query::OP_OR, myq1, myq2);
  179     tout << "myquery=" << myquery << "\n";
  180     TEST_EQUAL(myquery.get_length(), 10);
  181 
  182     return true;
  183 }
  184 
  185 // tests that queries validate correctly
  186 DEFINE_TESTCASE(queryvalid1, !backend) {
  187     Xapian::Query q2(Xapian::Query::OP_XOR, Xapian::Query("foo"), Xapian::Query("bar"));
  188     tout << "XOR (\"foo\", \"bar\") checked" << endl;
  189     return true;
  190 }
  191 
  192 /** Check we no longer flatten subqueries combined with the same operator.
  193  *
  194  *  Prior to 1.3.0 we did flatten these, but it's simpler to just handle this
  195  *  when we convert the query to a PostList tree, and that works better with
  196  *  Query objects being immutable.
  197  */
  198 DEFINE_TESTCASE(dontflattensubqueries1, !backend) {
  199     Xapian::Query queries1[3] = {
  200     Xapian::Query("wibble"),
  201     Xapian::Query("wobble"),
  202     Xapian::Query(Xapian::Query::OP_OR, string("jelly"), string("belly"))
  203     };
  204 
  205     Xapian::Query queries2[3] = {
  206     Xapian::Query(Xapian::Query::OP_AND, string("jelly"), string("belly")),
  207     Xapian::Query("wibble"),
  208     Xapian::Query("wobble")
  209     };
  210 
  211     vector<Xapian::Query> vec1(queries1, queries1 + 3);
  212     Xapian::Query myquery1(Xapian::Query::OP_OR, vec1.begin(), vec1.end());
  213     TEST_EQUAL(myquery1.get_description(),
  214            "Query((wibble OR wobble OR (jelly OR belly)))");
  215 
  216     vector<Xapian::Query> vec2(queries2, queries2 + 3);
  217     Xapian::Query myquery2(Xapian::Query::OP_AND, vec2.begin(), vec2.end());
  218     TEST_EQUAL(myquery2.get_description(),
  219            "Query(((jelly AND belly) AND wibble AND wobble))");
  220 
  221     return true;
  222 }
  223 
  224 // test behaviour when creating a query from an empty vector
  225 DEFINE_TESTCASE(emptyquerypart1, !backend) {
  226     vector<string> emptyterms;
  227     Xapian::Query query(Xapian::Query::OP_OR, emptyterms.begin(), emptyterms.end());
  228     TEST(Xapian::Query(Xapian::Query::OP_AND, query, Xapian::Query("x")).empty());
  229     TEST(Xapian::Query(Xapian::Query::OP_AND, query, Xapian::Query("x")).get_length() == 0);
  230     TEST(!Xapian::Query(Xapian::Query::OP_OR, query, Xapian::Query("x")).empty());
  231     TEST(Xapian::Query(Xapian::Query::OP_OR, query, Xapian::Query("x")).get_length() == 1);
  232     return true;
  233 }
  234 
  235 DEFINE_TESTCASE(stemlangs1, !backend) {
  236     string langs = Xapian::Stem::get_available_languages();
  237     tout << "available languages '" << langs << "'" << endl;
  238     TEST(!langs.empty());
  239 
  240     // Also test the language codes.
  241     langs += " ar hy eu ca da nl en fi fr de hu id ga it lt ne nb nn no pt ro"
  242          " ru es sv ta tr";
  243 
  244     string::size_type i = 0;
  245     while (true) {
  246     string::size_type spc = langs.find(' ', i);
  247     // The only spaces in langs should be a single one between each pair
  248     // of language names.
  249     TEST_NOT_EQUAL(i, spc);
  250 
  251     // Try making a stemmer for this language.  We should be able to create
  252     // it without an exception being thrown.
  253     string language(langs, i, spc - i);
  254     tout << "checking language code '" << language << "' works" << endl;
  255     Xapian::Stem stemmer(language);
  256     TEST(!stemmer.is_none());
  257     if (language.size() > 2) {
  258         string expected("Xapian::Stem(");
  259         expected += language;
  260         expected += ')';
  261         TEST_EQUAL(stemmer.get_description(), expected);
  262     }
  263 
  264     if (spc == string::npos) break;
  265     i = spc + 1;
  266     }
  267 
  268     {
  269     // Stem("none") should give a no-op stemmer.
  270     Xapian::Stem stem_nothing = Xapian::Stem("none");
  271     TEST(stem_nothing.is_none());
  272     TEST_EQUAL(stem_nothing.get_description(), "Xapian::Stem(none)");
  273     }
  274 
  275     {
  276     // Stem("") should be equivalent.
  277     Xapian::Stem stem_nothing = Xapian::Stem("");
  278     TEST(stem_nothing.is_none());
  279     TEST_EQUAL(stem_nothing.get_description(), "Xapian::Stem(none)");
  280     }
  281 
  282     return true;
  283 }
  284 
  285 // Some simple tests of the built in weighting schemes.
  286 DEFINE_TESTCASE(weight1, !backend) {
  287     Xapian::Weight * wt;
  288 
  289     Xapian::BoolWeight boolweight;
  290     TEST_EQUAL(boolweight.name(), "Xapian::BoolWeight");
  291     wt = Xapian::BoolWeight().unserialise(boolweight.serialise());
  292     TEST_EQUAL(boolweight.serialise(), wt->serialise());
  293     delete wt;
  294 
  295     Xapian::CoordWeight coordweight;
  296     TEST_EQUAL(coordweight.name(), "Xapian::CoordWeight");
  297     wt = Xapian::CoordWeight().unserialise(coordweight.serialise());
  298     TEST_EQUAL(coordweight.serialise(), wt->serialise());
  299     delete wt;
  300 
  301     Xapian::TradWeight tradweight_dflt;
  302     Xapian::TradWeight tradweight(1.0);
  303     TEST_EQUAL(tradweight.name(), "Xapian::TradWeight");
  304     TEST_EQUAL(tradweight_dflt.serialise(), tradweight.serialise());
  305     wt = Xapian::TradWeight().unserialise(tradweight.serialise());
  306     TEST_EQUAL(tradweight.serialise(), wt->serialise());
  307     delete wt;
  308 
  309     Xapian::TradWeight tradweight2(2.0);
  310     TEST_NOT_EQUAL(tradweight.serialise(), tradweight2.serialise());
  311 
  312     Xapian::BM25Weight bm25weight_dflt;
  313     Xapian::BM25Weight bm25weight(1, 0, 1, 0.5, 0.5);
  314     TEST_EQUAL(bm25weight.name(), "Xapian::BM25Weight");
  315     TEST_EQUAL(bm25weight_dflt.serialise(), bm25weight.serialise());
  316     wt = Xapian::BM25Weight().unserialise(bm25weight.serialise());
  317     TEST_EQUAL(bm25weight.serialise(), wt->serialise());
  318     delete wt;
  319 
  320     Xapian::BM25Weight bm25weight2(1, 0.5, 1, 0.5, 0.5);
  321     TEST_NOT_EQUAL(bm25weight.serialise(), bm25weight2.serialise());
  322 
  323     Xapian::BM25PlusWeight bm25plusweight_dflt;
  324     Xapian::BM25PlusWeight bm25plusweight(1, 0, 1, 0.5, 0.5, 1.0);
  325     TEST_EQUAL(bm25plusweight.name(), "Xapian::BM25PlusWeight");
  326     TEST_EQUAL(bm25plusweight_dflt.serialise(), bm25plusweight.serialise());
  327     wt = Xapian::BM25PlusWeight().unserialise(bm25plusweight.serialise());
  328     TEST_EQUAL(bm25plusweight.serialise(), wt->serialise());
  329     delete wt;
  330 
  331     Xapian::BM25PlusWeight bm25plusweight2(1, 0, 1, 0.5, 0.5, 2.0);
  332     TEST_NOT_EQUAL(bm25plusweight.serialise(), bm25plusweight2.serialise());
  333 
  334     Xapian::TfIdfWeight tfidfweight_dflt;
  335     Xapian::TfIdfWeight tfidfweight("ntn");
  336     TEST_EQUAL(tfidfweight.name(), "Xapian::TfIdfWeight");
  337     TEST_EQUAL(tfidfweight_dflt.serialise(), tfidfweight.serialise());
  338     wt = Xapian::TfIdfWeight().unserialise(tfidfweight.serialise());
  339     TEST_EQUAL(tfidfweight.serialise(), wt->serialise());
  340     delete wt;
  341 
  342     Xapian::TfIdfWeight tfidfweight2("bpn");
  343     TEST_NOT_EQUAL(tfidfweight.serialise(), tfidfweight2.serialise());
  344 
  345     Xapian::InL2Weight inl2weight_dflt;
  346     Xapian::InL2Weight inl2weight(1.0);
  347     TEST_EQUAL(inl2weight.name(), "Xapian::InL2Weight");
  348     TEST_EQUAL(inl2weight_dflt.serialise(), inl2weight.serialise());
  349     wt = Xapian::InL2Weight().unserialise(inl2weight.serialise());
  350     TEST_EQUAL(inl2weight.serialise(), wt->serialise());
  351     delete wt;
  352 
  353     Xapian::InL2Weight inl2weight2(2.0);
  354     TEST_NOT_EQUAL(inl2weight.serialise(), inl2weight2.serialise());
  355 
  356     Xapian::IfB2Weight ifb2weight_dflt;
  357     Xapian::IfB2Weight ifb2weight(1.0);
  358     TEST_EQUAL(ifb2weight.name(), "Xapian::IfB2Weight");
  359     TEST_EQUAL(ifb2weight_dflt.serialise(), ifb2weight.serialise());
  360     wt = Xapian::IfB2Weight().unserialise(ifb2weight.serialise());
  361     TEST_EQUAL(ifb2weight.serialise(), wt->serialise());
  362     delete wt;
  363 
  364     Xapian::IfB2Weight ifb2weight2(2.0);
  365     TEST_NOT_EQUAL(ifb2weight.serialise(), ifb2weight2.serialise());
  366 
  367     Xapian::IneB2Weight ineb2weight_dflt;
  368     Xapian::IneB2Weight ineb2weight(1.0);
  369     TEST_EQUAL(ineb2weight.name(), "Xapian::IneB2Weight");
  370     TEST_EQUAL(ineb2weight_dflt.serialise(), ineb2weight.serialise());
  371     wt = Xapian::IneB2Weight().unserialise(ineb2weight.serialise());
  372     TEST_EQUAL(ineb2weight.serialise(), wt->serialise());
  373     delete wt;
  374 
  375     Xapian::IneB2Weight ineb2weight2(2.0);
  376     TEST_NOT_EQUAL(ineb2weight.serialise(), ineb2weight2.serialise());
  377 
  378     Xapian::BB2Weight bb2weight_dflt;
  379     Xapian::BB2Weight bb2weight(1.0);
  380     TEST_EQUAL(bb2weight.name(), "Xapian::BB2Weight");
  381     TEST_EQUAL(bb2weight_dflt.serialise(), bb2weight.serialise());
  382     wt = Xapian::BB2Weight().unserialise(bb2weight.serialise());
  383     TEST_EQUAL(bb2weight.serialise(), wt->serialise());
  384     delete wt;
  385 
  386     Xapian::BB2Weight bb2weight2(2.0);
  387     TEST_NOT_EQUAL(bb2weight.serialise(), bb2weight2.serialise());
  388 
  389     Xapian::DLHWeight dlhweight;
  390     TEST_EQUAL(dlhweight.name(), "Xapian::DLHWeight");
  391     wt = Xapian::DLHWeight().unserialise(dlhweight.serialise());
  392     TEST_EQUAL(dlhweight.serialise(), wt->serialise());
  393     delete wt;
  394 
  395     Xapian::PL2Weight pl2weight_dflt;
  396     Xapian::PL2Weight pl2weight(1.0);
  397     TEST_EQUAL(pl2weight.name(), "Xapian::PL2Weight");
  398     TEST_EQUAL(pl2weight_dflt.serialise(), pl2weight.serialise());
  399     wt = Xapian::PL2Weight().unserialise(pl2weight.serialise());
  400     TEST_EQUAL(pl2weight.serialise(), wt->serialise());
  401     delete wt;
  402 
  403     Xapian::PL2Weight pl2weight2(2.0);
  404     TEST_NOT_EQUAL(pl2weight.serialise(), pl2weight2.serialise());
  405 
  406     Xapian::PL2PlusWeight pl2plusweight_dflt;
  407     Xapian::PL2PlusWeight pl2plusweight(1.0, 0.8);
  408     TEST_EQUAL(pl2plusweight.name(), "Xapian::PL2PlusWeight");
  409     TEST_EQUAL(pl2plusweight_dflt.serialise(), pl2plusweight.serialise());
  410     wt = Xapian::PL2PlusWeight().unserialise(pl2plusweight.serialise());
  411     TEST_EQUAL(pl2plusweight.serialise(), wt->serialise());
  412     delete wt;
  413 
  414     Xapian::PL2PlusWeight pl2plusweight2(2.0, 0.9);
  415     TEST_NOT_EQUAL(pl2plusweight.serialise(), pl2plusweight2.serialise());
  416 
  417     Xapian::DPHWeight dphweight;
  418     TEST_EQUAL(dphweight.name(), "Xapian::DPHWeight");
  419     wt = Xapian::DPHWeight().unserialise(dphweight.serialise());
  420     TEST_EQUAL(dphweight.serialise(), wt->serialise());
  421     delete wt;
  422 
  423     Xapian::LMWeight unigramlmweight_dflt;
  424     Xapian::LMWeight unigramlmweight(32000, Xapian::Weight::DIRICHLET_SMOOTHING, 2034.0, 0.0);
  425     TEST_EQUAL(unigramlmweight.name(), "Xapian::LMWeight");
  426     TEST_NOT_EQUAL(unigramlmweight_dflt.serialise(), unigramlmweight.serialise());
  427     wt = Xapian::LMWeight().unserialise(unigramlmweight.serialise());
  428     TEST_EQUAL(unigramlmweight.serialise(), wt->serialise());
  429     delete wt;
  430 
  431     return true;
  432 }
  433 
  434 // Regression test.
  435 DEFINE_TESTCASE(nosuchdb1, !backend) {
  436     // This is a "nodb" test because it doesn't test a particular backend.
  437     try {
  438     Xapian::Database db("NOsuChdaTabASe");
  439     FAIL_TEST("Managed to open 'NOsuChdaTabASe'");
  440     } catch (const Xapian::DatabaseOpeningError & e) {
  441     // We don't really require this exact message, but in Xapian <= 1.1.0
  442     // this gave "Couldn't detect type of database".
  443     TEST_STRINGS_EQUAL(e.get_msg(), "Couldn't stat 'NOsuChdaTabASe'");
  444     }
  445 
  446     try {
  447     Xapian::Database::check("NOsuChdaTabASe");
  448     FAIL_TEST("Managed to check 'NOsuChdaTabASe'");
  449     } catch (const Xapian::DatabaseOpeningError & e) {
  450     // In 1.4.3 and earlier, this threw DatabaseError with the message:
  451     // "File is not a Xapian database or database table" (confusing as
  452     // there is no file).
  453     TEST_STRINGS_EQUAL(e.get_msg(),
  454                "Couldn't find Xapian database or table to check");
  455     }
  456 
  457     return true;
  458 }
  459 
  460 // Feature tests for value manipulations.
  461 DEFINE_TESTCASE(addvalue1, !backend) {
  462     // Regression test for add_value on an existing value (bug#82).
  463     Xapian::Document doc;
  464     doc.add_value(1, "original");
  465     doc.add_value(1, "replacement");
  466     TEST_EQUAL(doc.get_value(1), "replacement");
  467 
  468     doc.add_value(2, "too");
  469     doc.add_value(3, "free");
  470     doc.add_value(4, "for");
  471 
  472     doc.remove_value(2);
  473     doc.remove_value(4);
  474     TEST_EQUAL(doc.get_value(0), "");
  475     TEST_EQUAL(doc.get_value(1), "replacement");
  476     TEST_EQUAL(doc.get_value(2), "");
  477     TEST_EQUAL(doc.get_value(3), "free");
  478     TEST_EQUAL(doc.get_value(4), "");
  479 
  480     return true;
  481 }
  482 
  483 // tests that the collapsing on termpos optimisation gives correct query length
  484 DEFINE_TESTCASE(poscollapse2, !backend) {
  485     Xapian::Query q(Xapian::Query::OP_OR, Xapian::Query("this", 1, 1), Xapian::Query("this", 1, 1));
  486     TEST_EQUAL(q.get_length(), 2);
  487     return true;
  488 }
  489 
  490 // regression test of querying an uninitialised database: should report an
  491 // error; used to segfault with 1.0.0.
  492 DEFINE_TESTCASE(uninitdb1, !backend) {
  493     Xapian::Database db;
  494     TEST_EXCEPTION(Xapian::InvalidArgumentError,
  495            Xapian::Enquire enq(db));
  496     return true;
  497 }
  498 
  499 // Test a scaleweight query applied to a match nothing query
  500 DEFINE_TESTCASE(scaleweight3, !backend) {
  501     Xapian::Query matchnothing(Xapian::Query::MatchNothing);
  502     Xapian::Query query(Xapian::Query::OP_SCALE_WEIGHT, matchnothing, 3.0);
  503     TEST_EQUAL(query.get_description(), "Query()");
  504     return true;
  505 }
  506 
  507 // Regression test - before 1.1.0, you could add docid 0 to an RSet.
  508 DEFINE_TESTCASE(rset3, !backend) {
  509     Xapian::RSet rset;
  510     TEST_EXCEPTION(Xapian::InvalidArgumentError, rset.add_document(0));
  511     TEST(rset.empty());
  512     TEST_EQUAL(rset.size(), 0);
  513     rset.add_document(1);
  514     rset.add_document(static_cast<Xapian::docid>(-1));
  515     TEST_EXCEPTION(Xapian::InvalidArgumentError, rset.add_document(0));
  516     TEST(!rset.empty());
  517     TEST_EQUAL(rset.size(), 2);
  518     return true;
  519 }
  520 
  521 // Regression test - RSet::get_description() gave a malformed answer in 1.0.7.
  522 DEFINE_TESTCASE(rset4, !backend) {
  523     Xapian::RSet rset;
  524     rset.add_document(1);
  525     // In 1.0.7 this gave: RSet(RSet(RSet::Internal(, 1))
  526     TEST_STRINGS_EQUAL(rset.get_description(), "RSet(RSet::Internal(1))");
  527     return true;
  528 }
  529 
  530 // Direct test of ValueSetMatchDecider
  531 DEFINE_TESTCASE(valuesetmatchdecider1, !backend) {
  532     Xapian::ValueSetMatchDecider vsmd1(0, true);
  533     vsmd1.add_value("42");
  534     Xapian::ValueSetMatchDecider vsmd2(0, false);
  535     vsmd2.remove_value("nosuch"); // Test removing a value which isn't present.
  536     vsmd2.add_value("42");
  537     Xapian::ValueSetMatchDecider vsmd3(0, true);
  538     vsmd3.add_value("42");
  539     vsmd3.add_value("blah");
  540 
  541     Xapian::Document doc;
  542     TEST(!vsmd1(doc));
  543     TEST(vsmd2(doc));
  544     TEST(!vsmd3(doc));
  545     doc.add_value(0, "42");
  546     TEST(vsmd1(doc));
  547     TEST(!vsmd2(doc));
  548     TEST(vsmd3(doc));
  549     doc.add_value(0, "blah");
  550     TEST(!vsmd1(doc));
  551     TEST(vsmd2(doc));
  552     TEST(vsmd3(doc));
  553 
  554     vsmd3.remove_value("nosuch"); // Test removing a value which isn't present.
  555     vsmd3.remove_value("blah");
  556     TEST(!vsmd1(doc));
  557     TEST(vsmd2(doc));
  558     TEST(!vsmd3(doc));
  559     doc.add_value(0, "42");
  560     TEST(vsmd1(doc));
  561     TEST(!vsmd2(doc));
  562     TEST(vsmd3(doc));
  563 
  564     return true;
  565 }
  566 
  567 // Test that asking for the termfreq on an empty mset raises an exception.
  568 DEFINE_TESTCASE(emptymset1, !backend) {
  569     Xapian::MSet emptymset;
  570     TEST_EXCEPTION(Xapian::InvalidOperationError,
  571            emptymset.get_termfreq("foo"));
  572     return true;
  573 }
  574 
  575 DEFINE_TESTCASE(expanddeciderfilterprefix1, !backend) {
  576     string prefix = "tw";
  577     Xapian::ExpandDeciderFilterPrefix decider(prefix);
  578     TEST(!decider("one"));
  579     TEST(!decider("t"));
  580     TEST(!decider(""));
  581     TEST(!decider("Two"));
  582     TEST(decider("two"));
  583     TEST(decider("twitter"));
  584     TEST(decider(prefix));
  585 
  586     return true;
  587 }