00001
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_matchspy.h"
00027
00028 #include <xapian.h>
00029
00030 #include "str.h"
00031 #include <cmath>
00032 #include <map>
00033 #include <vector>
00034
00035 #include "backendmanager.h"
00036 #include "testsuite.h"
00037 #include "testutils.h"
00038 #include "apitest.h"
00039
00040 using namespace std;
00041
00042
00043
00044
00045 class SimpleMatchSpy : public Xapian::MatchSpy {
00046 public:
00047
00048 std::vector<std::string> seen;
00049
00050 void operator()(const Xapian::Document &doc,
00051 Xapian::weight) {
00052
00053
00054
00055 seen.push_back(doc.get_data());
00056 }
00057 };
00058
00059
00060 DEFINE_TESTCASE(matchspy1, backend && !remote) {
00061 Xapian::Database db(get_database("apitest_simpledata"));
00062 Xapian::Enquire enquire(db);
00063 enquire.set_query(Xapian::Query("this"));
00064
00065 SimpleMatchSpy myspy;
00066
00067 Xapian::MSet nospymset = enquire.get_mset(0, 100);
00068 enquire.add_matchspy(&myspy);
00069 Xapian::MSet spymset = enquire.get_mset(0, 100);
00070
00071
00072 TEST_EQUAL(nospymset, spymset);
00073
00074 vector<bool> docid_checked(db.get_lastdocid());
00075
00076
00077
00078 Xapian::MSetIterator i = spymset.begin();
00079 TEST(i != spymset.end());
00080 TEST_EQUAL(spymset.size(), 6);
00081 TEST_EQUAL(myspy.seen.size(), spymset.size());
00082
00083 std::sort(myspy.seen.begin(), myspy.seen.end());
00084
00085 std::vector<std::string> seen2;
00086 for ( ; i != spymset.end(); ++i) {
00087 const Xapian::Document doc(i.get_document());
00088 seen2.push_back(doc.get_data());
00089 }
00090 std::sort(seen2.begin(), seen2.end());
00091
00092 TEST_EQUAL(myspy.seen.size(), seen2.size());
00093 std::vector<std::string>::const_iterator j = myspy.seen.begin();
00094 std::vector<std::string>::const_iterator j2 = seen2.begin();
00095 for (; j != myspy.seen.end(); ++j, ++j2) {
00096 TEST_EQUAL(*j, *j2);
00097 }
00098
00099 return true;
00100 }
00101
00102 static string values_to_repr(const Xapian::ValueCountMatchSpy & spy) {
00103 string resultrepr("|");
00104 for (Xapian::TermIterator i = spy.values_begin();
00105 i != spy.values_end();
00106 ++i) {
00107 resultrepr += *i;
00108 resultrepr += ':';
00109 resultrepr += str(i.get_termfreq());
00110 resultrepr += '|';
00111 }
00112 return resultrepr;
00113 }
00114
00115 DEFINE_TESTCASE(matchspy2, writable)
00116 {
00117 Xapian::WritableDatabase db = get_writable_database();
00118 for (int c = 1; c <= 25; ++c) {
00119 Xapian::Document doc;
00120 doc.set_data("Document " + str(c));
00121 int factors = 0;
00122 for (int factor = 1; factor <= c; ++factor) {
00123 doc.add_term("all");
00124 if (c % factor == 0) {
00125 doc.add_term("XFACT" + str(factor));
00126 ++factors;
00127 }
00128 }
00129
00130
00131 doc.add_value(0, str(factors));
00132
00133 doc.add_value(1, str(c % 10));
00134
00135 doc.add_value(2, "fish");
00136
00137 doc.add_value(3, str(str(c).size()));
00138
00139 db.add_document(doc);
00140 }
00141
00142 Xapian::ValueCountMatchSpy spy0(0);
00143 Xapian::ValueCountMatchSpy spy1(1);
00144 Xapian::ValueCountMatchSpy spy3(3);
00145
00146 Xapian::Enquire enq(db);
00147
00148 enq.set_query(Xapian::Query("all"));
00149
00150 enq.add_matchspy(&spy0);
00151 enq.add_matchspy(&spy1);
00152 enq.add_matchspy(&spy3);
00153 Xapian::MSet mset = enq.get_mset(0, 10);
00154
00155 TEST_EQUAL(spy0.get_total(), 25);
00156 TEST_EQUAL(spy1.get_total(), 25);
00157 TEST_EQUAL(spy3.get_total(), 25);
00158
00159 static const char * results[] = {
00160 "|1:1|2:9|3:3|4:7|5:1|6:3|8:1|",
00161 "|0:2|1:3|2:3|3:3|4:3|5:3|6:2|7:2|8:2|9:2|",
00162 "|1:9|2:16|",
00163 };
00164 TEST_STRINGS_EQUAL(values_to_repr(spy0), results[0]);
00165 TEST_STRINGS_EQUAL(values_to_repr(spy1), results[1]);
00166 TEST_STRINGS_EQUAL(values_to_repr(spy3), results[2]);
00167
00168 return true;
00169 }
00170
00171 DEFINE_TESTCASE(matchspy4, writable)
00172 {
00173 Xapian::WritableDatabase db = get_writable_database();
00174 for (int c = 1; c <= 25; ++c) {
00175 Xapian::Document doc;
00176 doc.set_data("Document " + str(c));
00177 int factors = 0;
00178 for (int factor = 1; factor <= c; ++factor) {
00179 doc.add_term("all");
00180 if (c % factor == 0) {
00181 doc.add_term("XFACT" + str(factor));
00182 ++factors;
00183 }
00184 }
00185
00186
00187 doc.add_value(0, str(factors));
00188
00189 doc.add_value(1, str(c % 10));
00190
00191 doc.add_value(2, "fish");
00192
00193 doc.add_value(3, str(str(c).size()));
00194
00195 db.add_document(doc);
00196 }
00197
00198
00199
00200
00201 Xapian::ValueCountMatchSpy spya0(0);
00202 Xapian::ValueCountMatchSpy spya1(1);
00203 Xapian::ValueCountMatchSpy spya3(3);
00204 Xapian::ValueCountMatchSpy spyb0(0);
00205 Xapian::ValueCountMatchSpy spyb1(1);
00206 Xapian::ValueCountMatchSpy spyb3(3);
00207
00208 Xapian::Enquire enqa(db);
00209 Xapian::Enquire enqb(db);
00210
00211 enqa.set_query(Xapian::Query("all"));
00212 enqb.set_query(Xapian::Query("all"));
00213
00214 enqa.add_matchspy(&spya0);
00215 enqa.add_matchspy(&spya1);
00216 enqa.add_matchspy(&spya3);
00217 enqb.add_matchspy(&spyb0);
00218 enqb.add_matchspy(&spyb1);
00219 enqb.add_matchspy(&spyb3);
00220
00221 Xapian::MSet mseta = enqa.get_mset(0, 10);
00222 enqb.set_sort_by_value(0, false);
00223 Xapian::MSet msetb = enqb.get_mset(0, 10, 100);
00224
00225 TEST_EQUAL(spya0.get_total(), 25);
00226 TEST_EQUAL(spya1.get_total(), 25);
00227 TEST_EQUAL(spya3.get_total(), 25);
00228 TEST_EQUAL(spyb0.get_total(), 25);
00229 TEST_EQUAL(spyb1.get_total(), 25);
00230 TEST_EQUAL(spyb3.get_total(), 25);
00231
00232 static const char * results[] = {
00233 "|2:9|4:7|3:3|6:3|1:1|5:1|8:1|",
00234 "|1:3|2:3|3:3|4:3|5:3|0:2|6:2|7:2|8:2|9:2|",
00235 "|",
00236 "|2:16|1:9|",
00237 "|2:9|4:7|3:3|6:3|1:1|5:1|8:1|",
00238 "|1:3|2:3|3:3|4:3|5:3|0:2|6:2|7:2|8:2|9:2|",
00239 "|",
00240 "|2:16|1:9|",
00241 NULL
00242 };
00243 std::vector<Xapian::ValueCountMatchSpy *> spies;
00244 spies.push_back(&spya0);
00245 spies.push_back(&spya1);
00246 spies.push_back(NULL);
00247 spies.push_back(&spya3);
00248 spies.push_back(&spyb0);
00249 spies.push_back(&spyb1);
00250 spies.push_back(NULL);
00251 spies.push_back(&spyb3);
00252 for (Xapian::valueno v = 0; results[v]; ++v) {
00253 tout << "value " << v << endl;
00254 Xapian::ValueCountMatchSpy * spy = spies[v];
00255 string allvals_str("|");
00256 if (spy != NULL) {
00257 size_t allvals_size = 0;
00258 for (Xapian::TermIterator i = spy->top_values_begin(100);
00259 i != spy->top_values_end(100);
00260 ++i, ++allvals_size) {
00261 allvals_str += *i;
00262 allvals_str += ':';
00263 allvals_str += str(i.get_termfreq());
00264 allvals_str += '|';
00265 }
00266 tout << allvals_str << endl;
00267 TEST_STRINGS_EQUAL(allvals_str, results[v]);
00268
00269 for (size_t count = 0; count < allvals_size; ++count) {
00270 tout << "count " << count << endl;
00271 for (Xapian::TermIterator i = spy->top_values_begin(100),
00272 j = spy->top_values_begin(count);
00273 i != spy->top_values_end(100) &&
00274 j != spy->top_values_end(count);
00275 ++i, ++j) {
00276 tout << "j " << j << endl;
00277 TEST_EQUAL(*i, *j);
00278 TEST_EQUAL(i.get_termfreq(), j.get_termfreq());
00279 }
00280 }
00281 }
00282 }
00283
00284 return true;
00285 }
00286
00287
00288 DEFINE_TESTCASE(matchspy5, backend)
00289 {
00290 Xapian::Database db(get_database("apitest_simpledata"));
00291 Xapian::Enquire enquire(db);
00292 enquire.set_query(Xapian::Query("this"));
00293
00294 Xapian::ValueCountMatchSpy myspy1(1);
00295 Xapian::ValueCountMatchSpy myspy2(1);
00296
00297 enquire.add_matchspy(&myspy1);
00298 enquire.add_matchspy(&myspy2);
00299 Xapian::MSet mymset = enquire.get_mset(0, 100);
00300 TEST_EQUAL(mymset.size(), 6);
00301
00302 Xapian::TermIterator i = myspy1.values_begin();
00303 TEST(i != myspy1.values_end());
00304 TEST(*i == "h");
00305 TEST_EQUAL(i.get_termfreq(), 5);
00306 ++i;
00307 TEST(i != myspy1.values_end());
00308 TEST(*i == "n");
00309 TEST_EQUAL(i.get_termfreq(), 1);
00310 ++i;
00311 TEST(i == myspy1.values_end());
00312
00313 i = myspy2.values_begin();
00314 TEST(i != myspy2.values_end());
00315 TEST(*i == "h");
00316 TEST_EQUAL(i.get_termfreq(), 5);
00317 ++i;
00318 TEST(i != myspy2.values_end());
00319 TEST(*i == "n");
00320 TEST_EQUAL(i.get_termfreq(), 1);
00321 ++i;
00322 TEST(i == myspy2.values_end());
00323
00324 return true;
00325 }
00326
00327 class MySpy : public Xapian::MatchSpy {
00328 void operator()(const Xapian::Document &, Xapian::weight) {
00329 }
00330 };
00331
00332
00333 DEFINE_TESTCASE(matchspy6, !backend)
00334 {
00335 MySpy spy;
00336
00337 TEST_EXCEPTION(Xapian::UnimplementedError, spy.clone());
00338 TEST_EXCEPTION(Xapian::UnimplementedError, spy.name());
00339 TEST_EXCEPTION(Xapian::UnimplementedError, spy.serialise());
00340 TEST_EXCEPTION(Xapian::UnimplementedError,
00341 spy.unserialise(std::string(), Xapian::Registry()));
00342 TEST_EXCEPTION(Xapian::UnimplementedError, spy.serialise_results());
00343 TEST_EXCEPTION(Xapian::UnimplementedError,
00344 spy.merge_results(std::string()));
00345 TEST_EQUAL(spy.get_description(), "Xapian::MatchSpy()");
00346
00347 return true;
00348 }