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