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