2 * @brief tests which don't need a backend
4 /* Copyright (C) 2009 Richard Boulton
5 * Copyright (C) 2009,2010,2011,2013,2014,2015,2016,2017 Olly Betts
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.
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.
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
27 #define XAPIAN_DEPRECATED(D) D
32 #include "testsuite.h"
33 #include "testutils.h"
37 // Check the version functions give consistent results.
38 DEFINE_TESTCASE(version1
, !backend
) {
39 string version
= str(Xapian::major_version());
41 version
+= str(Xapian::minor_version());
43 version
+= str(Xapian::revision());
44 TEST_EQUAL(Xapian::version_string(), version
);
48 // Regression test: various methods on Database() used to segfault or cause
49 // division by 0. Fixed in 1.1.4 and 1.0.18. Ticket#415.
50 DEFINE_TESTCASE(nosubdatabases1
, !backend
) {
52 TEST(db
.get_metadata("foo").empty());
53 TEST_EQUAL(db
.metadata_keys_begin(), db
.metadata_keys_end());
54 TEST_EXCEPTION(Xapian::InvalidOperationError
, db
.termlist_begin(1));
55 TEST_EQUAL(db
.allterms_begin(), db
.allterms_end());
56 TEST_EQUAL(db
.allterms_begin("foo"), db
.allterms_end("foo"));
57 TEST_EXCEPTION(Xapian::InvalidOperationError
, db
.positionlist_begin(1, "foo"));
58 TEST_EQUAL(db
.get_lastdocid(), 0);
59 TEST_EQUAL(db
.valuestream_begin(7), db
.valuestream_end(7));
60 TEST_EXCEPTION(Xapian::InvalidOperationError
, db
.get_doclength(1));
61 TEST_EXCEPTION(Xapian::InvalidOperationError
, db
.get_unique_terms(1));
62 TEST_EXCEPTION(Xapian::InvalidOperationError
, db
.get_document(1));
66 /// Feature test for Document::add_boolean_term(), new in 1.0.18/1.1.4.
67 DEFINE_TESTCASE(document1
, !backend
) {
69 doc
.add_boolean_term("Hxapian.org");
70 TEST_EQUAL(doc
.termlist_count(), 1);
71 Xapian::TermIterator t
= doc
.termlist_begin();
72 TEST(t
!= doc
.termlist_end());
73 TEST_EQUAL(*t
, "Hxapian.org");
74 TEST_EQUAL(t
.get_wdf(), 0);
75 TEST(++t
== doc
.termlist_end());
76 doc
.remove_term("Hxapian.org");
77 TEST_EQUAL(doc
.termlist_count(), 0);
78 TEST(doc
.termlist_begin() == doc
.termlist_end());
82 /// Regression test - the docid wasn't initialised prior to 1.0.22/1.2.4.
83 DEFINE_TESTCASE(document2
, !backend
) {
85 // The return value is uninitialised, so running under valgrind this
86 // will fail reliably prior to the fix.
87 TEST_EQUAL(doc
.get_docid(), 0);
91 /// Feature tests for Document::clear_terms().
92 DEFINE_TESTCASE(documentclearterms1
, !backend
) {
95 doc
.add_boolean_term("Hlocalhost");
96 doc
.add_term("hello");
97 doc
.add_term("there", 2);
98 doc
.add_posting("positional", 1);
99 doc
.add_posting("information", 2, 3);
100 TEST_EQUAL(doc
.termlist_count(), 5);
101 TEST(doc
.termlist_begin() != doc
.termlist_end());
103 TEST_EQUAL(doc
.termlist_count(), 0);
104 TEST(doc
.termlist_begin() == doc
.termlist_end());
105 // Test clear_terms() when there are no terms.
107 TEST_EQUAL(doc
.termlist_count(), 0);
108 TEST(doc
.termlist_begin() == doc
.termlist_end());
112 // Test clear_terms() when there have never been any terms.
113 Xapian::Document doc
;
115 TEST_EQUAL(doc
.termlist_count(), 0);
116 TEST(doc
.termlist_begin() == doc
.termlist_end());
122 /// Feature tests for Document::clear_values().
123 DEFINE_TESTCASE(documentclearvalues1
, !backend
) {
125 Xapian::Document doc
;
126 doc
.add_value(37, "hello");
127 doc
.add_value(42, "world");
128 TEST_EQUAL(doc
.values_count(), 2);
129 TEST(doc
.values_begin() != doc
.values_end());
131 TEST_EQUAL(doc
.values_count(), 0);
132 TEST(doc
.values_begin() == doc
.values_end());
133 // Test clear_values() when there are no values.
135 TEST_EQUAL(doc
.values_count(), 0);
136 TEST(doc
.values_begin() == doc
.values_end());
140 // Test clear_values() when there have never been any values.
141 Xapian::Document doc
;
143 TEST_EQUAL(doc
.values_count(), 0);
144 TEST(doc
.termlist_begin() == doc
.termlist_end());
150 /// Feature tests for errors for empty terms.
151 DEFINE_TESTCASE(documentemptyterm1
, !backend
) {
152 Xapian::Document doc
;
153 TEST_EXCEPTION(Xapian::InvalidArgumentError
,
154 doc
.add_boolean_term(string()));
155 TEST_EXCEPTION(Xapian::InvalidArgumentError
,
156 doc
.add_term(string()));
157 TEST_EXCEPTION(Xapian::InvalidArgumentError
,
158 doc
.add_posting(string(), 1));
159 TEST_EXCEPTION(Xapian::InvalidArgumentError
,
160 doc
.add_posting(string(), 2, 3));
161 TEST_EXCEPTION(Xapian::InvalidArgumentError
,
162 doc
.remove_term(string()));
163 TEST_EXCEPTION(Xapian::InvalidArgumentError
,
164 doc
.remove_posting(string(), 1));
165 TEST_EXCEPTION(Xapian::InvalidArgumentError
,
166 doc
.remove_posting(string(), 2, 3));
170 DEFINE_TESTCASE(emptyquery4
, !backend
) {
171 // Test we get an empty query from applying any of the following ops to
172 // an empty list of subqueries.
174 TEST(Xapian::Query(q
.OP_AND
, &q
, &q
).empty());
175 TEST(Xapian::Query(q
.OP_OR
, &q
, &q
).empty());
176 TEST(Xapian::Query(q
.OP_AND_NOT
, &q
, &q
).empty());
177 TEST(Xapian::Query(q
.OP_XOR
, &q
, &q
).empty());
178 TEST(Xapian::Query(q
.OP_AND_MAYBE
, &q
, &q
).empty());
179 TEST(Xapian::Query(q
.OP_FILTER
, &q
, &q
).empty());
180 TEST(Xapian::Query(q
.OP_NEAR
, &q
, &q
).empty());
181 TEST(Xapian::Query(q
.OP_PHRASE
, &q
, &q
).empty());
182 TEST(Xapian::Query(q
.OP_ELITE_SET
, &q
, &q
).empty());
183 TEST(Xapian::Query(q
.OP_SYNONYM
, &q
, &q
).empty());
184 TEST(Xapian::Query(q
.OP_MAX
, &q
, &q
).empty());
188 DEFINE_TESTCASE(singlesubquery1
, !backend
) {
189 // Test that we get just the subquery if we apply any of the following
190 // ops to just that subquery.
191 #define singlesubquery1_(OP) \
192 TEST_STRINGS_EQUAL(Xapian::Query(q->OP, q, q + 1).get_description(),\
194 Xapian::Query q
[1] = { Xapian::Query("test") };
195 singlesubquery1_(OP_AND
);
196 singlesubquery1_(OP_OR
);
197 singlesubquery1_(OP_AND_NOT
);
198 singlesubquery1_(OP_XOR
);
199 singlesubquery1_(OP_AND_MAYBE
);
200 singlesubquery1_(OP_FILTER
);
201 singlesubquery1_(OP_NEAR
);
202 singlesubquery1_(OP_PHRASE
);
203 singlesubquery1_(OP_ELITE_SET
);
204 singlesubquery1_(OP_SYNONYM
);
205 singlesubquery1_(OP_MAX
);
209 DEFINE_TESTCASE(singlesubquery2
, !backend
) {
210 // Like the previous test, but using MatchNothing as the subquery.
211 #define singlesubquery2_(OP) \
212 TEST_STRINGS_EQUAL(Xapian::Query(q->OP, q, q + 1).get_description(),\
214 Xapian::Query q
[1] = { Xapian::Query::MatchNothing
};
215 singlesubquery2_(OP_AND
);
216 singlesubquery2_(OP_OR
);
217 singlesubquery2_(OP_AND_NOT
);
218 singlesubquery2_(OP_XOR
);
219 singlesubquery2_(OP_AND_MAYBE
);
220 singlesubquery2_(OP_FILTER
);
221 singlesubquery2_(OP_NEAR
);
222 singlesubquery2_(OP_PHRASE
);
223 singlesubquery2_(OP_ELITE_SET
);
224 singlesubquery2_(OP_SYNONYM
);
225 singlesubquery2_(OP_MAX
);
229 DEFINE_TESTCASE(singlesubquery3
, !backend
) {
230 // Like the previous test, but using MatchAll as the subquery.
231 #define singlesubquery3_(OP) \
232 TEST_STRINGS_EQUAL(Xapian::Query(q->OP, q, q + 1).get_description(),\
233 "Query(<alldocuments>)")
234 Xapian::Query q
[1] = { Xapian::Query::MatchAll
};
235 singlesubquery3_(OP_AND
);
236 singlesubquery3_(OP_OR
);
237 singlesubquery3_(OP_AND_NOT
);
238 singlesubquery3_(OP_XOR
);
239 singlesubquery3_(OP_AND_MAYBE
);
240 singlesubquery3_(OP_FILTER
);
241 // OP_NEAR and OP_PHRASE over MatchAll doesn't really make sense.
242 singlesubquery3_(OP_ELITE_SET
);
243 singlesubquery3_(OP_SYNONYM
);
244 singlesubquery3_(OP_MAX
);
248 /// Check we no longer combine wqf for same term at the same position.
249 DEFINE_TESTCASE(combinewqfnomore1
, !backend
) {
250 Xapian::Query
q(Xapian::Query::OP_OR
,
251 Xapian::Query("beer", 1, 1),
252 Xapian::Query("beer", 1, 1));
253 // Prior to 1.3.0, we would have given beer@2, but we decided that wasn't
254 // really useful or helpful.
255 TEST_EQUAL(q
.get_description(), "Query((beer@1 OR beer@1))");
259 class DestroyedFlag
{
263 DestroyedFlag(bool & destroyed_
) : destroyed(destroyed_
) {
272 class TestRangeProcessor
: public Xapian::RangeProcessor
{
273 DestroyedFlag destroyed
;
276 TestRangeProcessor(bool & destroyed_
)
277 : Xapian::RangeProcessor(0), destroyed(destroyed_
) { }
279 Xapian::Query
operator()(const std::string
&, const std::string
&)
281 return Xapian::Query::MatchAll
;
285 /// Check reference counting of user-subclassable classes.
286 DEFINE_TESTCASE(subclassablerefcount1
, !backend
) {
287 bool gone_auto
, gone
;
289 // Simple test of release().
291 Xapian::RangeProcessor
* rp
= new TestRangeProcessor(gone
);
293 Xapian::QueryParser qp
;
294 qp
.add_rangeprocessor(rp
->release());
299 // Check a second call to release() has no effect.
301 Xapian::RangeProcessor
* rp
= new TestRangeProcessor(gone
);
303 Xapian::QueryParser qp
;
304 qp
.add_rangeprocessor(rp
->release());
310 // Test reference counting works, and that a RangeProcessor with automatic
313 TestRangeProcessor
rp_auto(gone_auto
);
316 Xapian::QueryParser qp1
;
318 Xapian::QueryParser qp2
;
319 Xapian::RangeProcessor
* rp
;
320 rp
= new TestRangeProcessor(gone
);
322 qp1
.add_rangeprocessor(rp
->release());
324 qp2
.add_rangeprocessor(rp
);
326 qp2
.add_rangeprocessor(&rp_auto
);
337 // Regression test for initial implementation, where ~opt_intrusive_ptr()
338 // checked the reference of the object, which may have already been deleted
339 // if it wasn't been reference counted.
341 Xapian::QueryParser qp
;
343 Xapian::RangeProcessor
* rp
= new TestRangeProcessor(gone
);
345 qp
.add_rangeprocessor(rp
);
349 // At the end of this block, qp is destroyed, but mustn't dereference
350 // the pointer it has to rp. If it does, that should get caught
351 // when tests are run under valgrind.
357 class TestFieldProcessor
: public Xapian::FieldProcessor
{
358 DestroyedFlag destroyed
;
361 TestFieldProcessor(bool & destroyed_
) : destroyed(destroyed_
) { }
363 Xapian::Query
operator()(const string
&str
) {
364 return Xapian::Query(str
);
368 /// Check reference counting of user-subclassable classes.
369 DEFINE_TESTCASE(subclassablerefcount2
, !backend
) {
370 bool gone_auto
, gone
;
372 // Simple test of release().
374 Xapian::FieldProcessor
* proc
= new TestFieldProcessor(gone
);
376 Xapian::QueryParser qp
;
377 qp
.add_prefix("foo", proc
->release());
382 // Check a second call to release() has no effect.
384 Xapian::FieldProcessor
* proc
= new TestFieldProcessor(gone
);
386 Xapian::QueryParser qp
;
387 qp
.add_prefix("foo", proc
->release());
393 // Test reference counting works, and that a FieldProcessor with automatic
396 TestFieldProcessor
proc_auto(gone_auto
);
399 Xapian::QueryParser qp1
;
401 Xapian::QueryParser qp2
;
402 Xapian::FieldProcessor
* proc
;
403 proc
= new TestFieldProcessor(gone
);
405 qp1
.add_prefix("foo", proc
->release());
407 qp2
.add_prefix("foo", proc
);
409 qp2
.add_prefix("bar", &proc_auto
);
423 class TestMatchSpy
: public Xapian::MatchSpy
{
424 DestroyedFlag destroyed
;
427 TestMatchSpy(bool & destroyed_
) : destroyed(destroyed_
) { }
429 void operator()(const Xapian::Document
&, double) { }
432 /// Check reference counting of MatchSpy.
433 DEFINE_TESTCASE(subclassablerefcount3
, backend
) {
434 Xapian::Database db
= get_database("apitest_simpledata");
436 bool gone_auto
, gone
;
438 // Simple test of release().
440 Xapian::MatchSpy
* spy
= new TestMatchSpy(gone
);
442 Xapian::Enquire
enquire(db
);
443 enquire
.add_matchspy(spy
->release());
448 // Check a second call to release() has no effect.
450 Xapian::MatchSpy
* spy
= new TestMatchSpy(gone
);
452 Xapian::Enquire
enquire(db
);
453 enquire
.add_matchspy(spy
->release());
459 // Test reference counting works, and that a MatchSpy with automatic
462 TestMatchSpy
spy_auto(gone_auto
);
465 Xapian::Enquire
enq1(db
);
467 Xapian::Enquire
enq2(db
);
468 Xapian::MatchSpy
* spy
;
469 spy
= new TestMatchSpy(gone
);
471 enq1
.add_matchspy(spy
->release());
473 enq2
.add_matchspy(spy
);
475 enq2
.add_matchspy(&spy_auto
);
489 class TestStopper
: public Xapian::Stopper
{
490 DestroyedFlag destroyed
;
493 TestStopper(bool & destroyed_
) : destroyed(destroyed_
) { }
495 bool operator()(const std::string
&) const { return true; }
498 /// Check reference counting of Stopper with QueryParser.
499 DEFINE_TESTCASE(subclassablerefcount4
, !backend
) {
500 bool gone_auto
, gone
;
502 // Simple test of release().
504 Xapian::Stopper
* stopper
= new TestStopper(gone
);
506 Xapian::QueryParser qp
;
507 qp
.set_stopper(stopper
->release());
512 // Test that setting a new stopper causes the previous one to be released.
515 Xapian::Stopper
* stopper0
= new TestStopper(gone0
);
517 Xapian::QueryParser qp
;
518 qp
.set_stopper(stopper0
->release());
521 Xapian::Stopper
* stopper
= new TestStopper(gone
);
523 qp
.set_stopper(stopper
->release());
529 // Check a second call to release() has no effect.
531 Xapian::Stopper
* stopper
= new TestStopper(gone
);
533 Xapian::QueryParser qp
;
534 qp
.set_stopper(stopper
->release());
540 // Test reference counting works, and that a Stopper with automatic
543 TestStopper
stopper_auto(gone_auto
);
546 Xapian::QueryParser qp1
;
548 Xapian::QueryParser qp2
;
549 Xapian::Stopper
* stopper
;
550 stopper
= new TestStopper(gone
);
552 qp1
.set_stopper(stopper
->release());
554 qp2
.set_stopper(stopper
);
556 qp2
.set_stopper(&stopper_auto
);
570 /// Check reference counting of Stopper with TermGenerator.
571 DEFINE_TESTCASE(subclassablerefcount5
, !backend
) {
572 bool gone_auto
, gone
;
574 // Simple test of release().
576 Xapian::Stopper
* stopper
= new TestStopper(gone
);
578 Xapian::TermGenerator indexer
;
579 indexer
.set_stopper(stopper
->release());
584 // Test that setting a new stopper causes the previous one to be released.
587 Xapian::Stopper
* stopper0
= new TestStopper(gone0
);
589 Xapian::TermGenerator indexer
;
590 indexer
.set_stopper(stopper0
->release());
593 Xapian::Stopper
* stopper
= new TestStopper(gone
);
595 indexer
.set_stopper(stopper
->release());
601 // Check a second call to release() has no effect.
603 Xapian::Stopper
* stopper
= new TestStopper(gone
);
605 Xapian::TermGenerator indexer
;
606 indexer
.set_stopper(stopper
->release());
612 // Test reference counting works, and that a Stopper with automatic
615 TestStopper
stopper_auto(gone_auto
);
618 Xapian::TermGenerator indexer1
;
620 Xapian::TermGenerator indexer2
;
621 Xapian::Stopper
* stopper
;
622 stopper
= new TestStopper(gone
);
624 indexer1
.set_stopper(stopper
->release());
626 indexer2
.set_stopper(stopper
);
628 indexer2
.set_stopper(&stopper_auto
);
642 class TestKeyMaker
: public Xapian::KeyMaker
{
643 DestroyedFlag destroyed
;
646 TestKeyMaker(bool & destroyed_
) : destroyed(destroyed_
) { }
648 string
operator()(const Xapian::Document
&) const { return string(); }
651 /// Check reference counting of KeyMaker.
652 DEFINE_TESTCASE(subclassablerefcount6
, backend
) {
653 Xapian::Database db
= get_database("apitest_simpledata");
655 bool gone_auto
, gone
;
657 // Simple test of release().
659 Xapian::KeyMaker
* keymaker
= new TestKeyMaker(gone
);
661 Xapian::Enquire
enq(db
);
662 enq
.set_sort_by_key(keymaker
->release(), false);
667 // Test that setting a new keymaker causes the previous one to be released.
670 Xapian::KeyMaker
* keymaker0
= new TestKeyMaker(gone0
);
672 Xapian::Enquire
enq(db
);
673 enq
.set_sort_by_key(keymaker0
->release(), false);
676 Xapian::KeyMaker
* keymaker
= new TestKeyMaker(gone
);
678 enq
.set_sort_by_key_then_relevance(keymaker
->release(), false);
684 // Check a second call to release() has no effect.
686 Xapian::KeyMaker
* keymaker
= new TestKeyMaker(gone
);
688 Xapian::Enquire
enq(db
);
689 enq
.set_sort_by_key(keymaker
->release(), false);
695 // Test reference counting works, and that a KeyMaker with automatic
698 TestKeyMaker
keymaker_auto(gone_auto
);
701 Xapian::Enquire
enq1(db
);
703 Xapian::Enquire
enq2(db
);
704 Xapian::KeyMaker
* keymaker
;
705 keymaker
= new TestKeyMaker(gone
);
707 enq1
.set_sort_by_key(keymaker
->release(), false);
709 enq2
.set_sort_by_relevance_then_key(keymaker
, false);
711 enq2
.set_sort_by_key_then_relevance(&keymaker_auto
, false);
725 class TestExpandDecider
: public Xapian::ExpandDecider
{
726 DestroyedFlag destroyed
;
729 TestExpandDecider(bool & destroyed_
) : destroyed(destroyed_
) { }
731 bool operator()(const string
&) const { return true; }
734 /// Check reference counting of ExpandDecider.
735 DEFINE_TESTCASE(subclassablerefcount7
, backend
) {
736 Xapian::Database db
= get_database("apitest_simpledata");
737 Xapian::Enquire
enq(db
);
739 rset
.add_document(1);
741 bool gone_auto
, gone
;
744 flags
<= Xapian::Enquire::INCLUDE_QUERY_TERMS
;
745 flags
+= Xapian::Enquire::INCLUDE_QUERY_TERMS
) {
746 // Test of auto lifetime ExpandDecider.
748 TestExpandDecider
edecider_auto(gone_auto
);
750 (void)enq
.get_eset(5, rset
, 0, &edecider_auto
);
755 // Simple test of release().
757 Xapian::ExpandDecider
* edecider
= new TestExpandDecider(gone
);
759 (void)enq
.get_eset(5, rset
, 0, edecider
);
765 // Test that a released ExpandDecider gets cleaned up by get_eset().
767 Xapian::ExpandDecider
* edecider
= new TestExpandDecider(gone
);
769 (void)enq
.get_eset(5, rset
, 0, edecider
->release());
773 // Check a second call to release() has no effect.
775 Xapian::ExpandDecider
* edecider
= new TestExpandDecider(gone
);
779 (void)enq
.get_eset(5, rset
, 0, edecider
->release());
784 // Test combinations of released/non-released with ExpandDeciderAnd.
786 TestExpandDecider
edecider_auto(gone_auto
);
788 Xapian::ExpandDecider
* edecider
= new TestExpandDecider(gone
);
790 (void)enq
.get_eset(5, rset
, 0,
791 (new Xapian::ExpandDeciderAnd(
793 edecider
->release()))->release());
799 TestExpandDecider
edecider_auto(gone_auto
);
801 Xapian::ExpandDecider
* edecider
= new TestExpandDecider(gone
);
803 (void)enq
.get_eset(5, rset
, 0,
804 (new Xapian::ExpandDeciderAnd(
806 &edecider_auto
))->release());
815 class TestValueRangeProcessor
: public Xapian::ValueRangeProcessor
{
816 DestroyedFlag destroyed
;
819 TestValueRangeProcessor(bool & destroyed_
) : destroyed(destroyed_
) { }
821 Xapian::valueno
operator()(std::string
&, std::string
&) {
826 /// Check reference counting of user-subclassable classes.
827 DEFINE_TESTCASE(subclassablerefcount8
, !backend
) {
828 bool gone_auto
, gone
;
830 // Simple test of release().
832 Xapian::ValueRangeProcessor
* vrp
= new TestValueRangeProcessor(gone
);
834 Xapian::QueryParser qp
;
835 qp
.add_valuerangeprocessor(vrp
->release());
840 // Check a second call to release() has no effect.
842 Xapian::ValueRangeProcessor
* vrp
= new TestValueRangeProcessor(gone
);
844 Xapian::QueryParser qp
;
845 qp
.add_valuerangeprocessor(vrp
->release());
851 // Test reference counting works, and that a VRP with automatic storage
854 TestValueRangeProcessor
vrp_auto(gone_auto
);
857 Xapian::QueryParser qp1
;
859 Xapian::QueryParser qp2
;
860 Xapian::ValueRangeProcessor
* vrp
;
861 vrp
= new TestValueRangeProcessor(gone
);
863 qp1
.add_valuerangeprocessor(vrp
->release());
865 qp2
.add_valuerangeprocessor(vrp
);
867 qp2
.add_valuerangeprocessor(&vrp_auto
);
878 // Regression test for initial implementation, where ~opt_intrusive_ptr()
879 // checked the reference of the object, which may have already been deleted
880 // if it wasn't been reference counted.
882 Xapian::QueryParser qp
;
884 Xapian::ValueRangeProcessor
* vrp
=
885 new TestValueRangeProcessor(gone
);
887 qp
.add_valuerangeprocessor(vrp
);
891 // At the end of this block, qp is destroyed, but mustn't dereference
892 // the pointer it has to vrp. If it does, that should get caught
893 // when tests are run under valgrind.
899 /// Check encoding of non-UTF8 document data.
900 DEFINE_TESTCASE(nonutf8docdesc1
, !backend
) {
901 Xapian::Document doc
;
902 doc
.set_data("\xc0\x80\xf5\x80\x80\x80\xfe\xff");
903 TEST_EQUAL(doc
.get_description(),
904 "Document(docid=0, data=\\xc0\\x80\\xf5\\x80\\x80\\x80\\xfe\\xff)");
905 doc
.set_data(string("\x00\x1f", 2));
906 TEST_EQUAL(doc
.get_description(),
907 "Document(docid=0, data=\\x00\\x1f)");
908 // Check that backslashes are encoded so output isn't ambiguous.
909 doc
.set_data("back\\slash");
910 TEST_EQUAL(doc
.get_description(),
911 "Document(docid=0, data=back\\x5cslash)");
915 DEFINE_TESTCASE(orphaneddoctermitor1
, !backend
) {
916 Xapian::TermIterator t
;
918 Xapian::Document doc
;
920 t
= doc
.termlist_begin();
922 TEST_EQUAL(*t
, "foo");