]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testSBuf.cc
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 #include "base/CharacterSet.h"
12 #include "SBufFindTest.h"
13 #include "SBufStream.h"
14 #include "SquidString.h"
16 #include "unitTestMain.h"
21 CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf
);
23 /* let this test link sanely */
25 #include "MemObject.h"
27 eventAdd(const char *name
, EVH
* func
, void *arg
, double when
, int, bool cbdata
)
30 MemObject::endOffset() const
35 static char fox
[]="The quick brown fox jumped over the lazy dog";
36 static char fox1
[]="The quick brown fox ";
37 static char fox2
[]="jumped over the lazy dog";
39 // TEST: globals variables (default/empty and with contents) are
40 // created outside and before any unit tests and memory subsystem
41 // initialization. Check for correct constructor operation.
43 SBuf
literal("The quick brown fox jumped over the lazy dog");
46 testSBuf::testSBufConstructDestruct()
48 /* NOTE: Do not initialize memory here because we need
49 * to test correct operation before and after Mem::Init
52 // XXX: partial demo below of how to do constructor unit-test. use scope to ensure each test
53 // is working on local-scope variables constructed fresh for the test, and destructed when
54 // scope exists. use nested scopes to test destructor affects on copied data (MemBlob etc)
56 // TEST: default constructor (implicit destructor non-crash test)
57 // test accessors on empty SBuf.
60 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
61 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
62 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
63 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
66 // TEST: copy-construct NULL string (implicit destructor non-crash test)
69 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
70 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
71 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
72 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
75 // TEST: copy-construct empty string (implicit destructor non-crash test)
78 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
79 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
80 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
81 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
84 // TEST: copy-construct from a SBuf
87 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
88 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
89 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
90 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
93 CPPUNIT_ASSERT_EQUAL(literal
,s5
);
95 CPPUNIT_ASSERT_EQUAL(literal
,s6
);
96 // XXX: other state checks. expected result of calling any state accessor on s4 ?
99 // TEST: check that COW doesn't happen upon copy-construction
101 SBuf
s1(empty_sbuf
), s2(s1
);
102 CPPUNIT_ASSERT_EQUAL(s1
.rawContent(), s2
.rawContent());
103 SBuf
s3(literal
), s4(literal
);
104 CPPUNIT_ASSERT_EQUAL(s3
.rawContent(), s4
.rawContent());
107 // TEST: sub-string copy
109 SBuf s1
=SBuf(fox
+4), s2(fox
);
110 SBuf s3
=s2
.substr(4,s2
.length()); //n is out-of-bounds
111 CPPUNIT_ASSERT_EQUAL(s1
,s3
);
114 CPPUNIT_ASSERT_EQUAL(s4
,s3
);
117 // TEST: go via SquidString adapters.
121 CPPUNIT_ASSERT_EQUAL(literal
,s1
);
124 // TEST: go via std::string adapter.
126 std::string
str(fox
);
128 CPPUNIT_ASSERT_EQUAL(literal
,s1
);
133 testSBuf::testSBufConstructDestructAfterMemInit()
136 testSBufConstructDestruct();
140 testSBuf::testEqualityTest()
142 SBuf
s1(fox
),s2(fox
);
143 CPPUNIT_ASSERT_EQUAL(s1
,s1
); //self-equality
144 CPPUNIT_ASSERT_EQUAL(s1
,s2
); //same contents
145 s2
.assign("The quick brown fox jumped over the lazy doe");
146 CPPUNIT_ASSERT(!(s1
== s2
)); //same length, different contents
148 CPPUNIT_ASSERT(!(s1
== s2
)); //different length and contents
149 CPPUNIT_ASSERT(s1
!= s2
); //while we're ready, let's test inequality
151 CPPUNIT_ASSERT(!(s1
== s2
)); //null and not-null
152 CPPUNIT_ASSERT(s1
!= s2
); //while we're ready, let's test inequality
154 CPPUNIT_ASSERT_EQUAL(s1
,s2
); //null and null
158 testSBuf::testAppendSBuf()
160 SBuf
s1(fox1
),s2(fox2
);
162 CPPUNIT_ASSERT_EQUAL(s1
,literal
);
166 testSBuf::testPrintf()
169 s1
.Printf("%s:%d:%03.3f","fox",10,12345.67);
170 s2
.assign("fox:10:12345.670");
171 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
175 testSBuf::testAppendCString()
179 CPPUNIT_ASSERT_EQUAL(s1
,literal
);
183 testSBuf::testAppendStdString()
185 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
187 SBuf
alpha(alphabet
), s
;
188 s
.append(alphabet
,5).append(alphabet
+5);
189 CPPUNIT_ASSERT_EQUAL(alpha
,s
);
194 s
.append(alphabet
,5).append("\0",1).append(alphabet
+6,SBuf::npos
);
195 control
.append(alphabet
,5).append(1,'\0').append(alphabet
,6,std::string::npos
);
196 SBuf
scontrol(control
); // we need this to test the equality. sigh.
197 CPPUNIT_ASSERT_EQUAL(scontrol
,s
);
200 const char *alphazero
="abcdefghijk\0mnopqrstuvwxyz";
201 SBuf
s(alphazero
,26);
202 std::string
str(alphazero
,26);
203 CPPUNIT_ASSERT_EQUAL(0,memcmp(str
.data(),s
.rawContent(),26));
208 testSBuf::testAppendf()
211 s1
.appendf("%s:%d:%03.2f",fox
,1234,1234.56);
212 s2
.assign("The quick brown fox jumped over the lazy dog:1234:1234.56");
213 CPPUNIT_ASSERT_EQUAL(s2
,s1
);
217 testSBuf::testDumpStats()
219 SBuf::GetStats().dump(std::cout
);
220 MemBlob::GetStats().dump(std::cout
);
221 std::cout
<< "sizeof(SBuf): " << sizeof(SBuf
) << std::endl
;
222 std::cout
<< "sizeof(MemBlob): " << sizeof(MemBlob
) << std::endl
;
226 testSBuf::testSubscriptOp()
229 CPPUNIT_ASSERT_EQUAL(chg
[5],'u');
231 CPPUNIT_ASSERT_EQUAL(literal
[5],'u');
232 CPPUNIT_ASSERT_EQUAL(chg
[5],'e');
235 // note: can't use cppunit's CPPUNIT_TEST_EXCEPTION because TextException asserts, and
236 // so the test can't be properly completed.
238 testSBuf::testSubscriptOpFail()
241 c
=literal
.at(literal
.length()); //out of bounds by 1
243 std::cout
<< c
<< std::endl
;
246 static int sign(int v
)
256 testComparisonStdFull(const char *left
, const char *right
)
258 if (sign(strcmp(left
, right
)) != sign(SBuf(left
).cmp(SBuf(right
))))
259 std::cerr
<< std::endl
<< " cmp(SBuf) npos " << left
<< " ?= " << right
<< std::endl
;
260 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left
, right
)), sign(SBuf(left
).cmp(SBuf(right
))));
262 if (sign(strcmp(left
, right
)) != sign(SBuf(left
).cmp(right
)))
263 std::cerr
<< std::endl
<< " cmp(char*) npos " << left
<< " ?= " << right
<< std::endl
;
264 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left
, right
)), sign(SBuf(left
).cmp(right
)));
266 if (sign(strcasecmp(left
, right
)) != sign(SBuf(left
).caseCmp(SBuf(right
))))
267 std::cerr
<< std::endl
<< " caseCmp(SBuf) npos " << left
<< " ?= " << right
<< std::endl
;
268 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left
, right
)), sign(SBuf(left
).caseCmp(SBuf(right
))));
270 if (sign(strcasecmp(left
, right
)) != sign(SBuf(left
).caseCmp(right
)))
271 std::cerr
<< std::endl
<< " caseCmp(char*) npos " << left
<< " ?= " << right
<< std::endl
;
272 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left
, right
)), sign(SBuf(left
).caseCmp(right
)));
276 testComparisonStdN(const char *left
, const char *right
, const size_t n
)
278 if (sign(strncmp(left
, right
, n
)) != sign(SBuf(left
).cmp(SBuf(right
), n
)))
279 std::cerr
<< std::endl
<< " cmp(SBuf) " << n
<< ' ' << left
<< " ?= " << right
<< std::endl
;
280 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
, right
, n
)), sign(SBuf(left
).cmp(SBuf(right
), n
)));
282 if (sign(strncmp(left
, right
, n
)) != sign(SBuf(left
).cmp(right
, n
)))
283 std::cerr
<< std::endl
<< " cmp(char*) " << n
<< ' ' << SBuf(left
) << " ?= " << right
<< std::endl
;
284 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
, right
, n
)), sign(SBuf(left
).cmp(right
, n
)));
286 if (sign(strncasecmp(left
, right
, n
)) != sign(SBuf(left
).caseCmp(SBuf(right
), n
)))
287 std::cerr
<< std::endl
<< " caseCmp(SBuf) " << n
<< ' ' << left
<< " ?= " << right
<< std::endl
;
288 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
, right
, n
)), sign(SBuf(left
).caseCmp(SBuf(right
), n
)));
290 if (sign(strncasecmp(left
, right
, n
)) != sign(SBuf(left
).caseCmp(right
, n
)))
291 std::cerr
<< std::endl
<< " caseCmp(char*) " << n
<< ' ' << SBuf(left
) << " ?= " << right
<< std::endl
;
292 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
, right
, n
)), sign(SBuf(left
).caseCmp(right
, n
)));
296 testComparisonStdOneWay(const char *left
, const char *right
)
298 testComparisonStdFull(left
, right
);
299 const size_t maxN
= 2 + min(strlen(left
), strlen(right
));
300 for (size_t n
= 0; n
<= maxN
; ++n
) {
301 testComparisonStdN(left
, right
, n
);
306 testComparisonStd(const char *s1
, const char *s2
)
308 testComparisonStdOneWay(s1
, s2
);
309 testComparisonStdOneWay(s2
, s1
);
313 testSBuf::testComparisons()
316 SBuf
s1("foo"),s2("foe");
317 CPPUNIT_ASSERT(s1
.cmp(s2
)>0);
318 CPPUNIT_ASSERT(s1
.caseCmp(s2
)>0);
319 CPPUNIT_ASSERT(s2
.cmp(s1
)<0);
320 CPPUNIT_ASSERT_EQUAL(0,s1
.cmp(s2
,2));
321 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
322 CPPUNIT_ASSERT(s1
> s2
);
323 CPPUNIT_ASSERT(s2
< s1
);
324 CPPUNIT_ASSERT_EQUAL(sign(s1
.cmp(s2
)),sign(strcmp(s1
.c_str(),s2
.c_str())));
328 CPPUNIT_ASSERT(s1
.cmp(s2
)<0);
329 CPPUNIT_ASSERT_EQUAL(sign(s1
.cmp(s2
)),sign(strcmp(s1
.c_str(),s2
.c_str())));
330 CPPUNIT_ASSERT(s1
< s2
);
331 // specifying the max-length and overhanging size
332 CPPUNIT_ASSERT_EQUAL(1,SBuf("foolong").caseCmp(SBuf("foo"), 5));
333 // case-insensive comaprison
336 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
));
337 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
338 // \0-clenliness test
339 s1
.assign("f\0oo",4);
340 s2
.assign("f\0Oo",4);
341 CPPUNIT_ASSERT(s1
.cmp(s2
) > 0);
342 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
));
343 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,3));
344 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
345 CPPUNIT_ASSERT_EQUAL(0,s1
.cmp(s2
,2));
347 testComparisonStd("foo", "fooz");
348 testComparisonStd("foo", "foo");
349 testComparisonStd("foo", "f");
350 testComparisonStd("foo", "bar");
352 testComparisonStd("foo", "FOOZ");
353 testComparisonStd("foo", "FOO");
354 testComparisonStd("foo", "F");
356 testComparisonStdOneWay("", "");
358 // rare case C-string input matching SBuf with N>strlen(s)
360 char *right
= xstrdup("foo34567890123456789012345678");
361 SBuf
left("fooZYXWVUTSRQPONMLKJIHGFEDCBA");
362 // is 3 bytes in length. NEVER more.
366 // pick another spot to truncate at if something goes horribly wrong.
368 left
.setAt(14, '\0');
370 const SBuf::size_type maxN
= 20 + min(left
.length(), static_cast<SBuf::size_type
>(strlen(right
)));
371 for (SBuf::size_type n
= 0; n
<= maxN
; ++n
) {
372 if (sign(strncmp(left
.rawContent(), right
, n
)) != sign(left
.cmp(right
, n
)) )
373 std::cerr
<< std::endl
<< " cmp(char*) " << n
<< ' ' << left
<< " ?= " << right
;
374 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
.rawContent(), right
, n
)), sign(left
.cmp(right
, n
)));
375 if (sign(strncasecmp(left
.rawContent(), right
, n
)) != sign(left
.caseCmp(right
, n
)))
376 std::cerr
<< std::endl
<< " caseCmp(char*) " << n
<< ' ' << left
<< " ?= " << right
;
377 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
.rawContent(), right
, n
)), sign(left
.caseCmp(right
, n
)));
384 testSBuf::testConsume()
386 SBuf
s1(literal
),s2
,s3
;
389 CPPUNIT_ASSERT_EQUAL(s2
,s3
);
390 s3
.assign("quick brown fox jumped over the lazy dog");
391 CPPUNIT_ASSERT_EQUAL(s1
,s3
);
393 CPPUNIT_ASSERT_EQUAL(s1
,SBuf());
397 testSBuf::testRawContent()
403 foo
= s1
.rawContent();
404 CPPUNIT_ASSERT_EQUAL(0,strncmp(fox
,foo
,s1
.length()));
406 CPPUNIT_ASSERT(!strcmp(fox
,foo
));
410 testSBuf::testRawSpace()
414 SBuf::size_type sz
=s2
.length();
415 char *rb
=s2
.rawSpace(strlen(fox2
)+1);
417 s2
.forceSize(sz
+strlen(fox2
));
418 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
427 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
431 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
432 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
434 std::string
s(alphabet
); // TODO
439 CPPUNIT_ASSERT_EQUAL(ref
,b
);
443 b
.chop(b
.length()-3);
445 CPPUNIT_ASSERT_EQUAL(ref
,b
);
447 { // chop at beginning
451 CPPUNIT_ASSERT_EQUAL(ref
,b
);
453 { // chop to zero length
457 CPPUNIT_ASSERT_EQUAL(ref
,b
);
459 { // chop beyond end (at npos)
461 b
.chop(SBuf::npos
,4);
463 CPPUNIT_ASSERT_EQUAL(ref
,b
);
467 b
.chop(b
.length()+2,4);
469 CPPUNIT_ASSERT_EQUAL(ref
,b
);
473 b
.chop(0,b
.length());
475 CPPUNIT_ASSERT_EQUAL(ref
,b
);
477 { // overflow chopped area
479 b
.chop(b
.length()-3,b
.length());
481 CPPUNIT_ASSERT_EQUAL(ref
,b
);
486 testSBuf::testChomp()
488 SBuf
s1("complete string");
491 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
492 s2
.assign(" complete string ,");
494 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
495 s1
.assign(", complete string ,");
498 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
501 // inspired by SBufFindTest; to be expanded.
502 class SBufSubstrAutoTest
505 std::string fullReference
, str
;
507 void performEqualityTest() {
509 CPPUNIT_ASSERT_EQUAL(ref
,sb
);
511 SBufSubstrAutoTest() : fullString(fox
), fullReference(fox
) {
512 for (int offset
=fullString
.length()-1; offset
>= 0; --offset
) {
513 for (int length
=fullString
.length()-1-offset
; length
>= 0; --length
) {
514 sb
=fullString
.substr(offset
,length
);
515 str
=fullReference
.substr(offset
,length
);
516 performEqualityTest();
523 testSBuf::testSubstr()
525 SBuf
s1(literal
),s2
,s3
;
528 CPPUNIT_ASSERT_EQUAL(s2
,s3
);
530 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
531 SBufSubstrAutoTest sat
; // work done in the constructor
535 testSBuf::testFindChar()
537 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
540 SBuf::size_type nposResult
=SBuf::npos
;
543 // needle in haystack
545 CPPUNIT_ASSERT_EQUAL(3U,idx
);
546 CPPUNIT_ASSERT_EQUAL('d',s1
[idx
]);
548 // needle not present in haystack
549 idx
=s1
.find(' '); //fails
550 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
554 CPPUNIT_ASSERT_EQUAL(4U,idx
);
556 // char not in searched portion
558 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
560 // invalid start position
561 idx
=s1
.find('d',SBuf::npos
);
562 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
564 // search outside of haystack
565 idx
=s1
.find('d',s1
.length()+1);
566 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
569 // needle in haystack
571 CPPUNIT_ASSERT_EQUAL(3U, idx
);
572 CPPUNIT_ASSERT_EQUAL('d', s1
[idx
]);
574 // needle not present in haystack
575 idx
=s1
.rfind(' '); //fails
576 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
580 CPPUNIT_ASSERT_EQUAL(4U,idx
);
582 // char not in searched portion
584 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
586 // overlong haystack specification
587 idx
=s1
.rfind('d',s1
.length()+1);
588 CPPUNIT_ASSERT_EQUAL(3U,idx
);
592 testSBuf::testFindSBuf()
594 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
595 SBuf
haystack(alphabet
);
597 SBuf::size_type nposResult
=SBuf::npos
;
600 // needle in haystack
601 idx
= haystack
.find(SBuf("def"));
602 CPPUNIT_ASSERT_EQUAL(3U,idx
);
604 idx
= haystack
.find(SBuf("xyz"));
605 CPPUNIT_ASSERT_EQUAL(23U,idx
);
607 // needle not in haystack, no initial char match
608 idx
= haystack
.find(SBuf(" eq"));
609 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
611 // needle not in haystack, initial sequence match
612 idx
= haystack
.find(SBuf("deg"));
613 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
615 // needle past end of haystack
616 idx
= haystack
.find(SBuf("xyz1"));
617 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
619 // search in portion: needle not in searched part
620 idx
= haystack
.find(SBuf("def"),7);
621 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
623 // search in portion: overhang
624 idx
= haystack
.find(SBuf("def"),4);
625 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
627 // invalid start position
628 idx
= haystack
.find(SBuf("def"),SBuf::npos
);
629 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
631 // needle bigger than haystack
632 idx
= SBuf("def").find(haystack
);
633 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
635 // search in a double-matching haystack
640 idx
= h2
.find(SBuf("def"));
641 CPPUNIT_ASSERT_EQUAL(3U,idx
);
643 idx
= h2
.find(SBuf("xyzab"));
644 CPPUNIT_ASSERT_EQUAL(23U,idx
);
648 // needle in haystack
649 idx
= haystack
.rfind(SBuf("def"));
650 CPPUNIT_ASSERT_EQUAL(3U,idx
);
652 idx
= haystack
.rfind(SBuf("xyz"));
653 CPPUNIT_ASSERT_EQUAL(23U,idx
);
655 // needle not in haystack, no initial char match
656 idx
= haystack
.rfind(SBuf(" eq"));
657 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
659 // needle not in haystack, initial sequence match
660 idx
= haystack
.rfind(SBuf("deg"));
661 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
663 // needle past end of haystack
664 idx
= haystack
.rfind(SBuf("xyz1"));
665 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
667 // search in portion: needle in searched part
668 idx
= haystack
.rfind(SBuf("def"),7);
669 CPPUNIT_ASSERT_EQUAL(3U, idx
);
671 // search in portion: needle not in searched part
672 idx
= haystack
.rfind(SBuf("mno"),3);
673 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
675 // search in portion: overhang
676 idx
= haystack
.rfind(SBuf("def"),4);
677 CPPUNIT_ASSERT_EQUAL(3U, idx
);
679 // npos start position
680 idx
= haystack
.rfind(SBuf("def"),SBuf::npos
);
681 CPPUNIT_ASSERT_EQUAL(3U, idx
);
683 // needle bigger than haystack
684 idx
= SBuf("def").rfind(haystack
);
685 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
687 // search in a double-matching haystack
692 idx
= h2
.rfind(SBuf("def"));
693 CPPUNIT_ASSERT_EQUAL(29U,idx
);
695 idx
= h2
.find(SBuf("xyzab"));
696 CPPUNIT_ASSERT_EQUAL(23U,idx
);
701 testSBuf::testRFindChar()
706 CPPUNIT_ASSERT_EQUAL(40U,idx
);
707 CPPUNIT_ASSERT_EQUAL(' ',s1
[idx
]);
711 testSBuf::testRFindSBuf()
713 SBuf
haystack(literal
),afox("fox");
714 SBuf
goobar("goobar");
717 // corner case: search for a zero-length SBuf
718 idx
=haystack
.rfind(SBuf(""));
719 CPPUNIT_ASSERT_EQUAL(haystack
.length(),idx
);
721 // corner case: search for a needle longer than the haystack
722 idx
=afox
.rfind(SBuf(" "));
723 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
725 idx
=haystack
.rfind(SBuf("fox"));
726 CPPUNIT_ASSERT_EQUAL(16U,idx
);
728 // needle not found, no match for first char
729 idx
=goobar
.rfind(SBuf("foo"));
730 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
732 // needle not found, match for first char but no match for SBuf
733 idx
=haystack
.rfind(SBuf("foe"));
734 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
736 SBuf
g("g"); //match at the last char
737 idx
=haystack
.rfind(g
);
738 CPPUNIT_ASSERT_EQUAL(43U,idx
);
739 CPPUNIT_ASSERT_EQUAL('g',haystack
[idx
]);
741 idx
=haystack
.rfind(SBuf("The"));
742 CPPUNIT_ASSERT_EQUAL(0U,idx
);
744 haystack
.append("The");
745 idx
=haystack
.rfind(SBuf("The"));
746 CPPUNIT_ASSERT_EQUAL(44U,idx
);
749 haystack
="The quick brown fox";
750 SBuf
needle("foxy lady");
751 idx
=haystack
.rfind(needle
);
752 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
756 testSBuf::testSBufLength()
759 CPPUNIT_ASSERT_EQUAL(strlen(fox
),(size_t)s
.length());
763 testSBuf::testScanf()
770 s1
.assign("string , 123 , 123.50");
771 rv
=s1
.scanf("%s , %d , %f",s
,&i
,&f
);
772 CPPUNIT_ASSERT_EQUAL(3,rv
);
773 CPPUNIT_ASSERT_EQUAL(0,strcmp(s
,"string"));
774 CPPUNIT_ASSERT_EQUAL(123,i
);
775 CPPUNIT_ASSERT_EQUAL(static_cast<float>(123.5),f
);
781 char buf
[40]; //shorter than literal()
783 CPPUNIT_ASSERT_EQUAL(s
.length(),s
.copy(buf
,40));
784 CPPUNIT_ASSERT_EQUAL(0,strncmp(s
.rawContent(),buf
,s
.length()));
786 CPPUNIT_ASSERT_EQUAL(40U,s
.copy(buf
,40));
789 CPPUNIT_ASSERT_EQUAL(s2
,s
);
793 testSBuf::testStringOps()
795 SBuf
sng(ToLower(literal
)),
796 ref("the quick brown fox jumped over the lazy dog");
797 CPPUNIT_ASSERT_EQUAL(ref
,sng
);
799 CPPUNIT_ASSERT_EQUAL(0,sng
.compare(ref
,caseInsensitive
));
800 // max-size comparison
801 CPPUNIT_ASSERT_EQUAL(0,ref
.compare(SBuf("THE"),caseInsensitive
,3));
802 CPPUNIT_ASSERT_EQUAL(1,ref
.compare(SBuf("THE"),caseInsensitive
,6));
803 CPPUNIT_ASSERT_EQUAL(0,SBuf("the").compare(SBuf("THE"),caseInsensitive
,6));
811 const char *ref
=t
.rawContent();
812 t
.reserveCapacity(10240);
813 const char *match
=t
.rawContent();
814 CPPUNIT_ASSERT(match
!=ref
);
816 t
.append(literal
).append(literal
).append(literal
).append(literal
).append(literal
);
817 t
.append(t
).append(t
).append(t
).append(t
).append(t
);
818 CPPUNIT_ASSERT_EQUAL(ref
,match
);
822 testSBuf::testStartsWith()
824 static SBuf
casebuf("THE QUICK");
825 CPPUNIT_ASSERT(literal
.startsWith(SBuf(fox1
)));
826 CPPUNIT_ASSERT(!SBuf("The quick brown").startsWith(SBuf(fox1
))); //too short
827 CPPUNIT_ASSERT(!literal
.startsWith(SBuf(fox2
))); //different contents
829 // case-insensitive checks
830 CPPUNIT_ASSERT(literal
.startsWith(casebuf
,caseInsensitive
));
831 casebuf
=ToUpper(SBuf(fox1
));
832 CPPUNIT_ASSERT(literal
.startsWith(casebuf
,caseInsensitive
));
833 CPPUNIT_ASSERT(literal
.startsWith(SBuf(fox1
),caseInsensitive
));
834 casebuf
= "tha quick";
835 CPPUNIT_ASSERT_EQUAL(false,literal
.startsWith(casebuf
,caseInsensitive
));
839 testSBuf::testSBufStream()
841 SBuf
b("const.string, int 10 and a float 10.5");
843 ss
<< "const.string, int " << 10 << " and a float " << 10.5;
845 CPPUNIT_ASSERT_EQUAL(b
,o
);
848 CPPUNIT_ASSERT_EQUAL(SBuf(),o
);
852 CPPUNIT_ASSERT_EQUAL(ss2
.buf(),literal
);
853 CPPUNIT_ASSERT_EQUAL(f1
,SBuf(fox1
));
857 testSBuf::testFindFirstOf()
859 SBuf
haystack(literal
);
863 idx
=haystack
.findFirstOf(CharacterSet("t1","ADHRWYP"));
864 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
866 // found at beginning
867 idx
=haystack
.findFirstOf(CharacterSet("t2","THANDF"));
868 CPPUNIT_ASSERT_EQUAL(0U,idx
);
870 //found at end of haystack
871 idx
=haystack
.findFirstOf(CharacterSet("t3","QWERYVg"));
872 CPPUNIT_ASSERT_EQUAL(haystack
.length()-1,idx
);
874 //found in the middle of haystack
875 idx
=haystack
.findFirstOf(CharacterSet("t4","QWERqYV"));
876 CPPUNIT_ASSERT_EQUAL(4U,idx
);
880 testSBuf::testFindFirstNotOf()
882 SBuf
haystack(literal
);
885 // all chars from the set
886 idx
=haystack
.findFirstNotOf(CharacterSet("t1",literal
.c_str()));
887 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
889 // found at beginning
890 idx
=haystack
.findFirstNotOf(CharacterSet("t2","a"));
891 CPPUNIT_ASSERT_EQUAL(0U,idx
);
893 //found at end of haystack
894 idx
=haystack
.findFirstNotOf(CharacterSet("t3",literal
.substr(0,literal
.length()-1).c_str()));
895 CPPUNIT_ASSERT_EQUAL(haystack
.length()-1,idx
);
897 //found in the middle of haystack
898 idx
=haystack
.findFirstNotOf(CharacterSet("t4","The"));
899 CPPUNIT_ASSERT_EQUAL(3U,idx
);
903 testSBuf::testAutoFind()
910 testSBuf::testStdStringOps()
912 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
913 std::string
astr(alphabet
);
915 CPPUNIT_ASSERT_EQUAL(astr
,sb
.toStdString());