xapian-core  1.4.27
testutils.cc
Go to the documentation of this file.
1 
4 /* Copyright 1999,2000,2001 BrightStation PLC
5  * Copyright 2003,2004,2007,2008,2009,2015 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 "testutils.h"
26 
27 #include "testsuite.h"
28 
29 #include <fstream>
30 #include <vector>
31 
32 using namespace std;
33 
34 ostream &
35 operator<<(ostream &os, const vector<Xapian::docid> &ints)
36 {
37  copy(ints.begin(), ints.end(),
38  ostream_iterator<Xapian::docid>(os, ", "));
39  return os;
40 }
41 
42 // ######################################################################
43 // Useful comparison operators
44 
45 bool
46 mset_range_is_same(const Xapian::MSet &mset1, unsigned int first1,
47  const Xapian::MSet &mset2, unsigned int first2,
48  unsigned int count)
49 {
50  TEST_AND_EXPLAIN(mset1.size() >= first1 + count,
51  "mset1 is too small: expected at least " <<
52  (first1 + count) << " items, got " <<
53  mset1.size());
54 
55  TEST_AND_EXPLAIN(mset2.size() >= first2 + count,
56  "mset2 is too small: expected at least " <<
57  (first2 + count) << " items, got " <<
58  mset2.size());
59 
60  Xapian::MSetIterator i = mset1[first1];
61  Xapian::MSetIterator j = mset2[first2];
62 
63  for (unsigned int l = 0; l < count; ++l) {
64  if (*i != *j) {
65  tout << "docids differ at item " << (l + 1) << " in range: "
66  << *i << " != " << *j << "\n";
67  return false;
68  }
69  // FIXME: don't use internal macro here...
70  if (!TEST_EQUAL_DOUBLE_(i.get_weight(), j.get_weight())) {
71  tout << "weights differ at item " << (l + 1) << " in range: "
72  << i.get_weight() << " != " << j.get_weight() << "\n";
73  return false;
74  }
75  ++i;
76  ++j;
77  }
78  return true;
79 }
80 
81 bool
82 mset_range_is_same(const Xapian::MSet& mset, unsigned int first,
83  const pair<Xapian::docid, double> to_compare[],
84  unsigned int count)
85 {
86  TEST_AND_EXPLAIN(mset.size() >= first + count - 1,
87  "mset is too small: expected at least " <<
88  (first + count - 1) << " items, got " <<
89  mset.size() << ".");
90 
91  Xapian::MSetIterator i = mset[first];
92 
93  for (unsigned int l = 0; l < count; ++l) {
94  if (*i != to_compare[l].first) {
95  tout << "docids differ at item " << (l + 1) << " in range: "
96  << *i << " != " << to_compare[l].first << "\n";
97  return false;
98  }
99  // FIXME: don't use internal macro here...
100  if (!TEST_EQUAL_DOUBLE_(i.get_weight(), to_compare[l].second)) {
101  tout << "weights differ at item " << (l + 1) << " in range: "
102  << i.get_weight() << " != " << to_compare[l].second << "\n";
103  return false;
104  }
105  ++i;
106  }
107  return true;
108 }
109 
110 bool
111 mset_range_is_same_weights(const Xapian::MSet &mset1, unsigned int first1,
112  const Xapian::MSet &mset2, unsigned int first2,
113  unsigned int count)
114 {
115  TEST_AND_EXPLAIN(mset1.size() >= first1 + count - 1,
116  "mset1 is too small: expected at least " <<
117  (first1 + count - 1) << " items, got " <<
118  mset1.size() << ".");
119 
120  TEST_AND_EXPLAIN(mset2.size() >= first2 + count - 1,
121  "mset2 is too small: expected at least " <<
122  (first2 + count - 1) << " items, got " <<
123  mset2.size() << ".");
124 
125  Xapian::MSetIterator i = mset1[first1];
126  Xapian::MSetIterator j = mset2[first2];
127 
128  for (unsigned int l = 0; l < count; ++l) {
129  // FIXME: don't use internal macro here...
130  if (!TEST_EQUAL_DOUBLE_(i.get_weight(), j.get_weight())) {
131  tout << "weights differ at item " << (l + 1) << " in range: "
132  << i.get_weight() << " != " << j.get_weight() << "\n";
133  return false;
134  }
135  ++i;
136  ++j;
137  }
138  return true;
139 }
140 
141 bool operator==(const Xapian::MSet &first, const Xapian::MSet &second)
142 {
143  if ((first.get_matches_lower_bound() != second.get_matches_lower_bound()) ||
144  (first.get_matches_upper_bound() != second.get_matches_upper_bound()) ||
145  (first.get_matches_estimated() != second.get_matches_estimated()) ||
146  (first.get_max_possible() != second.get_max_possible()) ||
147  (first.size() != second.size())) {
148  return false;
149  }
150  if (first.empty()) return true;
151  return mset_range_is_same(first, 0, second, 0, first.size());
152 }
153 
154 static void
155 mset_expect_order_(const Xapian::MSet &A, bool beginning,
159 {
160  vector<Xapian::docid> expect;
161  if (d1) {
162  expect.push_back(d1);
163  if (d2) {
164  expect.push_back(d2);
165  if (d3) {
166  expect.push_back(d3);
167  if (d4) {
168  expect.push_back(d4);
169  if (d5) {
170  expect.push_back(d5);
171  if (d6) {
172  expect.push_back(d6);
173  if (d7) {
174  expect.push_back(d7);
175  if (d8) {
176  expect.push_back(d8);
177  if (d9) {
178  expect.push_back(d9);
179  if (d10) {
180  expect.push_back(d10);
181  if (d11) {
182  expect.push_back(d11);
183  if (d12) {
184  expect.push_back(d12);
185  }
186  }
187  }
188  }
189  }
190  }
191  }
192  }
193  }
194  }
195  }
196  }
197  // Wheeee!
198 
199  if (beginning) {
200  TEST_AND_EXPLAIN(A.size() >= expect.size(),
201  "Mset is of wrong size (" << A.size()
202  << " < " << expect.size() << "):\n"
203  "Full mset was: " << A << "\n"
204  "Expected order to start: {" << expect << "}");
205  } else {
206  TEST_AND_EXPLAIN(A.size() == expect.size(),
207  "Mset is of wrong size (" << A.size()
208  << " != " << expect.size() << "):\n"
209  "Full mset was: " << A << "\n"
210  "Expected order: {" << expect << "}");
211  }
212 
213  Xapian::MSetIterator j = A.begin();
214  for (size_t i = 0; i < expect.size(); ++i, ++j) {
215  TEST_AND_EXPLAIN(*j == expect[i],
216  "Mset didn't contain expected result:\n"
217  << "Item " << i << " was " << *j
218  << ", expected " << expect[i] << "\n"
219  "Full mset was: " << A << "\n"
220  "Expected: {" << expect << "}");
221  }
222 }
223 
224 void
229 {
230  mset_expect_order_(A, false, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12);
231 }
232 
233 void
235 {
236  TEST_AND_EXPLAIN(mset1.size() == mset2.size(),
237  "Msets not the same size - "
238  << mset1.size() << " != " << mset2.size());
239  Xapian::MSetIterator i = mset1.begin();
240  Xapian::MSetIterator j = mset2.begin();
241  for (; i != mset1.end(); ++i, ++j) {
242  TEST_AND_EXPLAIN(*i == *j,
243  "Msets have different contents -\n" <<
244  mset1 << "\n !=\n" << mset2);
245  }
246 }
Xapian::doccount size() const
Return number of items in this MSet object.
Definition: omenquire.cc:318
double get_max_possible() const
The maximum possible weight any document could achieve.
Definition: omenquire.cc:290
bool mset_range_is_same(const Xapian::MSet &mset1, unsigned int first1, const Xapian::MSet &mset2, unsigned int first2, unsigned int count)
Definition: testutils.cc:46
#define TEST_AND_EXPLAIN(a, b)
Test a condition, and display the test with an extra explanation if the condition fails...
Definition: testsuite.h:267
bool empty() const
Return true if this MSet object is empty.
Definition: mset.h:300
Xapian::doccount get_matches_lower_bound() const
Lower bound on the total number of matching documents.
Definition: omenquire.cc:246
a generic test suite engine
Class representing a list of search results.
Definition: mset.h:44
STL namespace.
Definition: unittest.cc:668
Xapian::doccount get_matches_upper_bound() const
Upper bound on the total number of matching documents.
Definition: omenquire.cc:262
void test_mset_order_equal(const Xapian::MSet &mset1, const Xapian::MSet &mset2)
Definition: testutils.cc:234
std::ostringstream tout
The debug printing stream.
Definition: testsuite.cc:104
Iterator over a Xapian::MSet.
Definition: mset.h:368
MSetIterator begin() const
Return iterator pointing to the first item in this MSet.
Definition: mset.h:624
MSetIterator end() const
Return iterator pointing to just after the last item in this MSet.
Definition: mset.h:629
bool operator==(const Xapian::MSet &first, const Xapian::MSet &second)
Definition: testutils.cc:141
bool TEST_EQUAL_DOUBLE_(double a, double b)
Helper function for TEST_EQUAL_DOUBLE macro.
Definition: testsuite.cc:928
double get_weight() const
Get the weight for the current position.
Definition: omenquire.cc:460
Xapian::doccount get_matches_estimated() const
Estimate of the total number of matching documents.
Definition: omenquire.cc:253
Xapian-specific test helper functions and macros.
bool mset_range_is_same_weights(const Xapian::MSet &mset1, unsigned int first1, const Xapian::MSet &mset2, unsigned int first2, unsigned int count)
Definition: testutils.cc:111
void mset_expect_order(const Xapian::MSet &A, Xapian::docid d1, Xapian::docid d2, Xapian::docid d3, Xapian::docid d4, Xapian::docid d5, Xapian::docid d6, Xapian::docid d7, Xapian::docid d8, Xapian::docid d9, Xapian::docid d10, Xapian::docid d11, Xapian::docid d12)
Definition: testutils.cc:225
static void mset_expect_order_(const Xapian::MSet &A, bool beginning, Xapian::docid d1, Xapian::docid d2, Xapian::docid d3, Xapian::docid d4, Xapian::docid d5, Xapian::docid d6, Xapian::docid d7, Xapian::docid d8, Xapian::docid d9, Xapian::docid d10, Xapian::docid d11, Xapian::docid d12)
Definition: testutils.cc:155
unsigned XAPIAN_DOCID_BASE_TYPE docid
A unique identifier for a document.
Definition: types.h:52