2 * @brief test of the Xapian internals
4 /* Copyright 1999,2000,2001 BrightStation PLC
5 * Copyright 2002 Ananova Ltd
6 * Copyright 2002,2003,2006,2007,2008,2009,2010,2011,2012,2015 Olly Betts
7 * Copyright 2006 Lemur Consulting Ltd
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
35 #include "testsuite.h"
36 #include "testutils.h"
41 class Test_Exception
{
44 Test_Exception(int value_
) : value(value_
) {}
47 // test that nested exceptions work correctly.
48 static void test_exception1()
52 throw Test_Exception(1);
55 throw Test_Exception(2);
60 } catch (const Test_Exception
& e
) {
61 TEST_EQUAL(e
.value
, 1);
65 // ###########################################
66 // # Tests of the reference counted pointers #
67 // ###########################################
69 class test_refcnt
: public Xapian::Internal::intrusive_base
{
73 test_refcnt(bool &deleted_
) : deleted(deleted_
) {
74 tout
<< "constructor\n";
77 Xapian::Internal::intrusive_ptr
<const test_refcnt
> test() {
78 return Xapian::Internal::intrusive_ptr
<const test_refcnt
>(this);
83 tout
<< "destructor\n";
87 static void test_refcnt1()
91 test_refcnt
*p
= new test_refcnt(deleted
);
93 TEST_EQUAL(p
->_refs
, 0);
96 Xapian::Internal::intrusive_ptr
<test_refcnt
> rcp(p
);
98 TEST_EQUAL(rcp
->_refs
, 1);
101 Xapian::Internal::intrusive_ptr
<test_refcnt
> rcp2
;
103 TEST_EQUAL(rcp
->_refs
, 2);
104 // rcp2 goes out of scope here
107 TEST_AND_EXPLAIN(!deleted
, "Object prematurely deleted!");
108 TEST_EQUAL(rcp
->_refs
, 1);
109 // rcp goes out of scope here
112 TEST_AND_EXPLAIN(deleted
, "Object not properly deleted");
115 // This is a regression test - our home-made equivalent of intrusive_ptr
116 // (which was called RefCntPtr) used to delete the object pointed to if you
117 // assigned it to itself and the reference count was 1.
118 static void test_refcnt2()
120 bool deleted
= false;
122 test_refcnt
*p
= new test_refcnt(deleted
);
124 Xapian::Internal::intrusive_ptr
<test_refcnt
> rcp(p
);
127 # if __has_warning("-Wself-assign-overloaded")
128 // Suppress warning from newer clang about self-assignment so we can
129 // test that self-assignment works!
130 # pragma clang diagnostic push
131 # pragma clang diagnostic ignored "-Wself-assign-overloaded"
136 # if __has_warning("-Wself-assign-overloaded")
137 # pragma clang diagnostic pop
141 TEST_AND_EXPLAIN(!deleted
, "Object deleted by self-assignment");
144 // Class for testing AutoPtr<>.
148 test_autoptr(bool &deleted_
) : deleted(deleted_
) {
149 tout
<< "test_autoptr constructor\n";
153 tout
<< "test_autoptr destructor\n";
157 // Test autoptr self-assignment.
158 static void test_autoptr1()
160 bool deleted
= false;
162 test_autoptr
* raw_ptr
= new test_autoptr(deleted
);
164 AutoPtr
<test_autoptr
> ptr(raw_ptr
);
166 TEST_EQUAL(ptr
.get(), raw_ptr
);
169 ptr
.reset(ptr
.release());
171 TEST_EQUAL(ptr
.get(), raw_ptr
);
176 TEST_EQUAL(ptr
.get(), raw_ptr
);
181 TEST_EQUAL(ptr
.get(), raw_ptr
);
188 raw_ptr
= new test_autoptr(deleted
);
190 bool deleted2
= false;
191 test_autoptr
* raw_ptr2
= new test_autoptr(deleted2
);
192 AutoPtr
<test_autoptr
> ptr(raw_ptr2
);
194 TEST_EQUAL(ptr
.get(), raw_ptr2
);
199 TEST_EQUAL(ptr
.get(), raw_ptr
);
204 TEST_EQUAL(ptr
.get(), static_cast<test_autoptr
*>(0));
208 // test string comparisons
209 static void test_stringcomp1()
217 if ((s1
!= s2
) || (s1
> s2
)) {
218 FAIL_TEST("String comparisons BADLY wrong");
223 if ((s1
== s2
) || (s1
< s2
)) {
224 FAIL_TEST("String comparisons don't cope with extra nulls");
232 if ((s1
.length() != 5) || (s2
.length() != 5)) {
233 FAIL_TEST("Lengths with added nulls wrong");
236 if ((s1
== s2
) || !(s1
< s2
)) {
237 FAIL_TEST("Characters after a null ignored in comparisons");
241 // By default Sun's C++ compiler doesn't call the destructor on a
242 // temporary object until the end of the block (contrary to what
243 // ISO C++ requires). This is done in the name of "compatibility".
244 // Passing -features=tmplife to CC fixes this. This check ensures
245 // that this actually works for Sun's C++ and any other compilers
246 // that might have this problem.
247 struct TempDtorTest
{
249 static TempDtorTest
factory() { return TempDtorTest(); }
250 TempDtorTest() { ++count
; }
251 ~TempDtorTest() { --count
; }
254 int TempDtorTest::count
= 0;
256 static void test_temporarydtor1()
258 TEST_EQUAL(TempDtorTest::count
, 0);
259 TempDtorTest::factory();
260 TEST_EQUAL(TempDtorTest::count
, 0);
263 /// Test pack_uint_preserving_sort()
264 static void test_pack_uint_preserving_sort1()
267 for (unsigned int i
= 0; i
!= 1000; ++i
) {
269 pack_uint_preserving_sort(packed
, i
);
270 const char * ptr
= packed
.data();
271 const char * end
= ptr
+ packed
.size();
273 TEST(unpack_uint_preserving_sort(&ptr
, end
, &result
));
274 TEST_EQUAL(result
, i
);
276 TEST_REL(prev_packed
, <, packed
);
277 swap(prev_packed
, packed
);
279 for (unsigned int i
= 2345; i
< 65000; i
+= 113) {
281 pack_uint_preserving_sort(packed
, i
);
282 const char * ptr
= packed
.data();
283 const char * end
= ptr
+ packed
.size();
285 TEST(unpack_uint_preserving_sort(&ptr
, end
, &result
));
286 TEST_EQUAL(result
, i
);
288 TEST_REL(prev_packed
, <, packed
);
289 swap(prev_packed
, packed
);
291 unsigned int prev
= 64999;
292 for (unsigned int i
= 65000; i
> prev
; prev
= i
, i
= (i
<< 1) ^ 1337) {
294 pack_uint_preserving_sort(packed
, i
);
295 const char * ptr
= packed
.data();
296 const char * end
= ptr
+ packed
.size();
298 TEST(unpack_uint_preserving_sort(&ptr
, end
, &result
));
299 TEST_EQUAL(result
, i
);
301 TEST_REL(prev_packed
, <, packed
);
302 swap(prev_packed
, packed
);
305 /* Test packing multiple numbers to one string. */
307 for (unsigned int i
= 23456; i
< 765432; i
+= 1131) {
308 pack_uint_preserving_sort(packed
, i
);
310 const char * ptr
= packed
.data();
311 const char * end
= ptr
+ packed
.size();
312 for (unsigned int i
= 23456; i
< 765432; i
+= 1131) {
314 TEST(unpack_uint_preserving_sort(&ptr
, end
, &result
));
315 TEST_EQUAL(result
, i
);
320 /// Test C_pack_uint_preserving_sort()
321 static void test_pack_uint_preserving_sort2()
324 for (unsigned int i
= 0; i
!= 1000; ++i
) {
326 C_pack_uint_preserving_sort(packed
, i
);
327 const char * ptr
= packed
.data();
328 const char * end
= ptr
+ packed
.size();
330 TEST(C_unpack_uint_preserving_sort(&ptr
, end
, &result
));
331 TEST_EQUAL(result
, i
);
333 TEST_REL(prev_packed
, <, packed
);
334 swap(prev_packed
, packed
);
336 for (unsigned int i
= 2345; i
< 65000; i
+= 113) {
338 C_pack_uint_preserving_sort(packed
, i
);
339 const char * ptr
= packed
.data();
340 const char * end
= ptr
+ packed
.size();
342 TEST(C_unpack_uint_preserving_sort(&ptr
, end
, &result
));
343 TEST_EQUAL(result
, i
);
345 TEST_REL(prev_packed
, <, packed
);
346 swap(prev_packed
, packed
);
348 unsigned int prev
= 64999;
349 for (unsigned int i
= 65000; i
> prev
; prev
= i
, i
= (i
<< 1) ^ 1337) {
351 C_pack_uint_preserving_sort(packed
, i
);
352 const char * ptr
= packed
.data();
353 const char * end
= ptr
+ packed
.size();
355 TEST(C_unpack_uint_preserving_sort(&ptr
, end
, &result
));
356 TEST_EQUAL(result
, i
);
358 TEST_REL(prev_packed
, <, packed
);
359 swap(prev_packed
, packed
);
362 /* Test packing multiple numbers to one string. */
364 for (unsigned int i
= 23456; i
< 765432; i
+= 1131) {
365 C_pack_uint_preserving_sort(packed
, i
);
367 const char * ptr
= packed
.data();
368 const char * end
= ptr
+ packed
.size();
369 for (unsigned int i
= 23456; i
< 765432; i
+= 1131) {
371 TEST(C_unpack_uint_preserving_sort(&ptr
, end
, &result
));
372 TEST_EQUAL(result
, i
);
377 /// Test C_isupper() etc.
378 static void test_chartype1()
381 memset(tested
, 0, sizeof(tested
));
382 for (int ch
= '0'; ch
!= '9' + 1; ++ch
) {
384 TEST(!C_isupper(ch
));
385 TEST(!C_islower(ch
));
386 TEST(!C_isalpha(ch
));
389 TEST(C_isxdigit(ch
));
390 TEST(!C_isspace(ch
));
391 TEST(C_isnotupper(ch
));
392 TEST(C_isnotlower(ch
));
393 TEST(C_isnotalpha(ch
));
394 TEST(!C_isnotalnum(ch
));
395 TEST(!C_isnotdigit(ch
));
396 TEST(!C_isnotxdigit(ch
));
397 TEST(C_isnotspace(ch
));
398 TEST_EQUAL(hex_digit(ch
), ch
- '0');
401 for (int ch
= 'A'; ch
!= 'F' + 1; ++ch
) {
404 TEST(!C_islower(ch
));
407 TEST(!C_isdigit(ch
));
408 TEST(C_isxdigit(ch
));
409 TEST(!C_isspace(ch
));
410 TEST(!C_isnotupper(ch
));
411 TEST(C_isnotlower(ch
));
412 TEST(!C_isnotalpha(ch
));
413 TEST(!C_isnotalnum(ch
));
414 TEST(C_isnotdigit(ch
));
415 TEST(!C_isnotxdigit(ch
));
416 TEST(C_isnotspace(ch
));
417 TEST_EQUAL(hex_digit(ch
), ch
- 'A' + 10);
420 for (int ch
= 'G'; ch
!= 'Z' + 1; ++ch
) {
423 TEST(!C_islower(ch
));
426 TEST(!C_isdigit(ch
));
427 TEST(!C_isxdigit(ch
));
428 TEST(!C_isspace(ch
));
429 TEST(!C_isnotupper(ch
));
430 TEST(C_isnotlower(ch
));
431 TEST(!C_isnotalpha(ch
));
432 TEST(!C_isnotalnum(ch
));
433 TEST(C_isnotdigit(ch
));
434 TEST(C_isnotxdigit(ch
));
435 TEST(C_isnotspace(ch
));
438 for (int ch
= 'a'; ch
!= 'f' + 1; ++ch
) {
440 TEST(!C_isupper(ch
));
444 TEST(!C_isdigit(ch
));
445 TEST(C_isxdigit(ch
));
446 TEST(!C_isspace(ch
));
447 TEST(C_isnotupper(ch
));
448 TEST(!C_isnotlower(ch
));
449 TEST(!C_isnotalpha(ch
));
450 TEST(!C_isnotalnum(ch
));
451 TEST(C_isnotdigit(ch
));
452 TEST(!C_isnotxdigit(ch
));
453 TEST(C_isnotspace(ch
));
454 TEST_EQUAL(hex_digit(ch
), ch
- 'a' + 10);
457 for (int ch
= 'g'; ch
!= 'z' + 1; ++ch
) {
459 TEST(!C_isupper(ch
));
463 TEST(!C_isdigit(ch
));
464 TEST(!C_isxdigit(ch
));
465 TEST(!C_isspace(ch
));
466 TEST(C_isnotupper(ch
));
467 TEST(!C_isnotlower(ch
));
468 TEST(!C_isnotalpha(ch
));
469 TEST(!C_isnotalnum(ch
));
470 TEST(C_isnotdigit(ch
));
471 TEST(C_isnotxdigit(ch
));
472 TEST(C_isnotspace(ch
));
475 for (const char *p
= "\t\n\f\r "; *p
; ++p
) {
478 TEST(!C_isupper(ch
));
479 TEST(!C_islower(ch
));
480 TEST(!C_isalpha(ch
));
481 TEST(!C_isalnum(ch
));
482 TEST(!C_isdigit(ch
));
483 TEST(!C_isxdigit(ch
));
485 TEST(C_isnotupper(ch
));
486 TEST(C_isnotlower(ch
));
487 TEST(C_isnotalpha(ch
));
488 TEST(C_isnotalnum(ch
));
489 TEST(C_isnotdigit(ch
));
490 TEST(C_isnotxdigit(ch
));
491 TEST(!C_isnotspace(ch
));
494 // Check remaining non-top-bit-set characters aren't anything.
495 for (int ch
= 0; ch
!= 128; ++ch
) {
496 if (tested
[ch
]) continue;
497 TEST(!C_isupper(ch
));
498 TEST(!C_islower(ch
));
499 TEST(!C_isalpha(ch
));
500 TEST(!C_isalnum(ch
));
501 TEST(!C_isdigit(ch
));
502 TEST(!C_isxdigit(ch
));
503 TEST(!C_isspace(ch
));
504 TEST(C_isnotupper(ch
));
505 TEST(C_isnotlower(ch
));
506 TEST(C_isnotalpha(ch
));
507 TEST(C_isnotalnum(ch
));
508 TEST(C_isnotdigit(ch
));
509 TEST(C_isnotxdigit(ch
));
510 TEST(C_isnotspace(ch
));
513 // Non-ASCII characters aren't anything for these functions.
514 for (unsigned char ch
= 128; ch
!= 0; ++ch
) {
515 TEST(!C_isupper(ch
));
516 TEST(!C_islower(ch
));
517 TEST(!C_isalpha(ch
));
518 TEST(!C_isalnum(ch
));
519 TEST(!C_isdigit(ch
));
520 TEST(!C_isxdigit(ch
));
521 TEST(!C_isspace(ch
));
522 TEST(C_isnotupper(ch
));
523 TEST(C_isnotlower(ch
));
524 TEST(C_isnotalpha(ch
));
525 TEST(C_isnotalnum(ch
));
526 TEST(C_isnotdigit(ch
));
527 TEST(C_isnotxdigit(ch
));
528 TEST(C_isnotspace(ch
));
531 // Check signed char values work the same way.
532 for (signed char ch
= -128; ch
!= 0; ++ch
) {
533 TEST(!C_isupper(ch
));
534 TEST(!C_islower(ch
));
535 TEST(!C_isalpha(ch
));
536 TEST(!C_isalnum(ch
));
537 TEST(!C_isdigit(ch
));
538 TEST(!C_isxdigit(ch
));
539 TEST(!C_isspace(ch
));
540 TEST(C_isnotupper(ch
));
541 TEST(C_isnotlower(ch
));
542 TEST(C_isnotalpha(ch
));
543 TEST(C_isnotalnum(ch
));
544 TEST(C_isnotdigit(ch
));
545 TEST(C_isnotxdigit(ch
));
546 TEST(C_isnotspace(ch
));
550 // ##################################################################
551 // # End of actual tests #
552 // ##################################################################
554 /// The lists of tests to perform
555 static const test_desc tests
[] = {
556 TESTCASE(exception1
),
560 TESTCASE(stringcomp1
),
561 TESTCASE(temporarydtor1
),
562 TESTCASE(pack_uint_preserving_sort1
),
563 TESTCASE(pack_uint_preserving_sort2
),
568 int main(int argc
, char **argv
)
570 test_driver::parse_command_line(argc
, argv
);
571 return test_driver::run(tests
);
572 } catch (const char * e
) {