]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testSBuf.cc
2 #include "base/CharacterSet.h"
5 #include "SBufFindTest.h"
6 #include "SBufStream.h"
7 #include "SquidString.h"
13 CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf
);
15 /* let this test link sanely */
17 #include "MemObject.h"
19 eventAdd(const char *name
, EVH
* func
, void *arg
, double when
, int, bool cbdata
)
22 MemObject::endOffset() const
27 static char fox
[]="The quick brown fox jumped over the lazy dog";
28 static char fox1
[]="The quick brown fox ";
29 static char fox2
[]="jumped over the lazy dog";
31 // TEST: globals variables (default/empty and with contents) are
32 // created outside and before any unit tests and memory subsystem
33 // initialization. Check for correct constructor operation.
35 SBuf
literal("The quick brown fox jumped over the lazy dog");
38 testSBuf::testSBufConstructDestruct()
40 /* NOTE: Do not initialize memory here because we need
41 * to test correct operation before and after Mem::Init
44 // XXX: partial demo below of how to do constructor unit-test. use scope to ensure each test
45 // is working on local-scope variables constructed fresh for the test, and destructed when
46 // scope exists. use nested scopes to test destructor affects on copied data (MemBlob etc)
48 // TEST: default constructor (implicit destructor non-crash test)
49 // test accessors on empty SBuf.
52 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
53 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
54 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
55 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
58 // TEST: copy-construct NULL string (implicit destructor non-crash test)
61 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
62 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
63 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
64 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
67 // TEST: copy-construct empty string (implicit destructor non-crash test)
70 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
71 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
72 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
73 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
76 // TEST: copy-construct from a SBuf
79 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
80 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
81 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
82 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
85 CPPUNIT_ASSERT_EQUAL(literal
,s5
);
87 CPPUNIT_ASSERT_EQUAL(literal
,s6
);
88 // XXX: other state checks. expected result of calling any state accessor on s4 ?
91 // TEST: check that COW doesn't happen upon copy-construction
93 SBuf
s1(empty_sbuf
), s2(s1
);
94 CPPUNIT_ASSERT_EQUAL(s1
.rawContent(), s2
.rawContent());
95 SBuf
s3(literal
), s4(literal
);
96 CPPUNIT_ASSERT_EQUAL(s3
.rawContent(), s4
.rawContent());
99 // TEST: sub-string copy
101 SBuf s1
=SBuf(fox
+4), s2(fox
);
102 SBuf s3
=s2
.substr(4,s2
.length()); //n is out-of-bounds
103 CPPUNIT_ASSERT_EQUAL(s1
,s3
);
106 CPPUNIT_ASSERT_EQUAL(s4
,s3
);
109 // TEST: go via SquidString adapters.
113 CPPUNIT_ASSERT_EQUAL(literal
,s1
);
116 // TEST: go via std::string adapter.
118 std::string
str(fox
);
120 CPPUNIT_ASSERT_EQUAL(literal
,s1
);
125 testSBuf::testSBufConstructDestructAfterMemInit()
128 testSBufConstructDestruct();
132 testSBuf::testEqualityTest()
134 SBuf
s1(fox
),s2(fox
);
135 CPPUNIT_ASSERT_EQUAL(s1
,s1
); //self-equality
136 CPPUNIT_ASSERT_EQUAL(s1
,s2
); //same contents
137 s2
.assign("The quick brown fox jumped over the lazy doe");
138 CPPUNIT_ASSERT(!(s1
== s2
)); //same length, different contents
140 CPPUNIT_ASSERT(!(s1
== s2
)); //different length and contents
141 CPPUNIT_ASSERT(s1
!= s2
); //while we're ready, let's test inequality
143 CPPUNIT_ASSERT(!(s1
== s2
)); //null and not-null
144 CPPUNIT_ASSERT(s1
!= s2
); //while we're ready, let's test inequality
146 CPPUNIT_ASSERT_EQUAL(s1
,s2
); //null and null
150 testSBuf::testAppendSBuf()
152 SBuf
s1(fox1
),s2(fox2
);
154 CPPUNIT_ASSERT_EQUAL(s1
,literal
);
158 testSBuf::testPrintf()
161 s1
.Printf("%s:%d:%03.3f","fox",10,12345.67);
162 s2
.assign("fox:10:12345.670");
163 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
167 testSBuf::testAppendCString()
171 CPPUNIT_ASSERT_EQUAL(s1
,literal
);
175 testSBuf::testAppendStdString()
177 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
179 SBuf
alpha(alphabet
), s
;
180 s
.append(alphabet
,5).append(alphabet
+5);
181 CPPUNIT_ASSERT_EQUAL(alpha
,s
);
186 s
.append(alphabet
,5).append("\0",1).append(alphabet
+6,SBuf::npos
);
187 control
.append(alphabet
,5).append(1,'\0').append(alphabet
,6,std::string::npos
);
188 SBuf
scontrol(control
); // we need this to test the equality. sigh.
189 CPPUNIT_ASSERT_EQUAL(scontrol
,s
);
192 const char *alphazero
="abcdefghijk\0mnopqrstuvwxyz";
193 SBuf
s(alphazero
,26);
194 std::string
str(alphazero
,26);
195 CPPUNIT_ASSERT_EQUAL(0,memcmp(str
.data(),s
.rawContent(),26));
200 testSBuf::testAppendf()
203 s1
.appendf("%s:%d:%03.2f",fox
,1234,1234.56);
204 s2
.assign("The quick brown fox jumped over the lazy dog:1234:1234.56");
205 CPPUNIT_ASSERT_EQUAL(s2
,s1
);
209 testSBuf::testDumpStats()
211 SBuf::GetStats().dump(std::cout
);
212 MemBlob::GetStats().dump(std::cout
);
213 std::cout
<< "sizeof(SBuf): " << sizeof(SBuf
) << std::endl
;
214 std::cout
<< "sizeof(MemBlob): " << sizeof(MemBlob
) << std::endl
;
218 testSBuf::testSubscriptOp()
221 CPPUNIT_ASSERT_EQUAL(chg
[5],'u');
223 CPPUNIT_ASSERT_EQUAL(literal
[5],'u');
224 CPPUNIT_ASSERT_EQUAL(chg
[5],'e');
227 // note: can't use cppunit's CPPUNIT_TEST_EXCEPTION because TextException asserts, and
228 // so the test can't be properly completed.
230 testSBuf::testSubscriptOpFail()
233 c
=literal
.at(literal
.length()); //out of bounds by 1
235 std::cout
<< c
<< std::endl
;
238 static int sign(int v
)
248 testComparisonStdFull(const char *left
, const char *right
)
250 if (sign(strcmp(left
, right
)) != sign(SBuf(left
).cmp(SBuf(right
))))
251 std::cerr
<< std::endl
<< " cmp(SBuf) npos " << left
<< " ?= " << right
<< std::endl
;
252 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left
, right
)), sign(SBuf(left
).cmp(SBuf(right
))));
254 if (sign(strcmp(left
, right
)) != sign(SBuf(left
).cmp(right
)))
255 std::cerr
<< std::endl
<< " cmp(char*) npos " << left
<< " ?= " << right
<< std::endl
;
256 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left
, right
)), sign(SBuf(left
).cmp(right
)));
258 if (sign(strcasecmp(left
, right
)) != sign(SBuf(left
).caseCmp(SBuf(right
))))
259 std::cerr
<< std::endl
<< " caseCmp(SBuf) npos " << left
<< " ?= " << right
<< std::endl
;
260 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left
, right
)), sign(SBuf(left
).caseCmp(SBuf(right
))));
262 if (sign(strcasecmp(left
, right
)) != sign(SBuf(left
).caseCmp(right
)))
263 std::cerr
<< std::endl
<< " caseCmp(char*) npos " << left
<< " ?= " << right
<< std::endl
;
264 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left
, right
)), sign(SBuf(left
).caseCmp(right
)));
268 testComparisonStdN(const char *left
, const char *right
, const size_t n
)
270 if (sign(strncmp(left
, right
, n
)) != sign(SBuf(left
).cmp(SBuf(right
), n
)))
271 std::cerr
<< std::endl
<< " cmp(SBuf) " << n
<< ' ' << left
<< " ?= " << right
<< std::endl
;
272 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
, right
, n
)), sign(SBuf(left
).cmp(SBuf(right
), n
)));
274 if (sign(strncmp(left
, right
, n
)) != sign(SBuf(left
).cmp(right
, n
)))
275 std::cerr
<< std::endl
<< " cmp(char*) " << n
<< ' ' << SBuf(left
) << " ?= " << right
<< std::endl
;
276 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
, right
, n
)), sign(SBuf(left
).cmp(right
, n
)));
278 if (sign(strncasecmp(left
, right
, n
)) != sign(SBuf(left
).caseCmp(SBuf(right
), n
)))
279 std::cerr
<< std::endl
<< " caseCmp(SBuf) " << n
<< ' ' << left
<< " ?= " << right
<< std::endl
;
280 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
, right
, n
)), sign(SBuf(left
).caseCmp(SBuf(right
), n
)));
282 if (sign(strncasecmp(left
, right
, n
)) != sign(SBuf(left
).caseCmp(right
, n
)))
283 std::cerr
<< std::endl
<< " caseCmp(char*) " << n
<< ' ' << SBuf(left
) << " ?= " << right
<< std::endl
;
284 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
, right
, n
)), sign(SBuf(left
).caseCmp(right
, n
)));
288 testComparisonStdOneWay(const char *left
, const char *right
)
290 testComparisonStdFull(left
, right
);
291 const size_t maxN
= 2 + min(strlen(left
), strlen(right
));
292 for (size_t n
= 0; n
<= maxN
; ++n
) {
293 testComparisonStdN(left
, right
, n
);
298 testComparisonStd(const char *s1
, const char *s2
)
300 testComparisonStdOneWay(s1
, s2
);
301 testComparisonStdOneWay(s2
, s1
);
305 testSBuf::testComparisons()
308 SBuf
s1("foo"),s2("foe");
309 CPPUNIT_ASSERT(s1
.cmp(s2
)>0);
310 CPPUNIT_ASSERT(s1
.caseCmp(s2
)>0);
311 CPPUNIT_ASSERT(s2
.cmp(s1
)<0);
312 CPPUNIT_ASSERT_EQUAL(0,s1
.cmp(s2
,2));
313 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
314 CPPUNIT_ASSERT(s1
> s2
);
315 CPPUNIT_ASSERT(s2
< s1
);
316 CPPUNIT_ASSERT_EQUAL(sign(s1
.cmp(s2
)),sign(strcmp(s1
.c_str(),s2
.c_str())));
320 CPPUNIT_ASSERT(s1
.cmp(s2
)<0);
321 CPPUNIT_ASSERT_EQUAL(sign(s1
.cmp(s2
)),sign(strcmp(s1
.c_str(),s2
.c_str())));
322 CPPUNIT_ASSERT(s1
< s2
);
323 // specifying the max-length and overhanging size
324 CPPUNIT_ASSERT_EQUAL(1,SBuf("foolong").caseCmp(SBuf("foo"), 5));
325 // case-insensive comaprison
328 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
));
329 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
330 // \0-clenliness test
331 s1
.assign("f\0oo",4);
332 s2
.assign("f\0Oo",4);
333 CPPUNIT_ASSERT(s1
.cmp(s2
) > 0);
334 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
));
335 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,3));
336 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
337 CPPUNIT_ASSERT_EQUAL(0,s1
.cmp(s2
,2));
339 testComparisonStd("foo", "fooz");
340 testComparisonStd("foo", "foo");
341 testComparisonStd("foo", "f");
342 testComparisonStd("foo", "bar");
344 testComparisonStd("foo", "FOOZ");
345 testComparisonStd("foo", "FOO");
346 testComparisonStd("foo", "F");
348 testComparisonStdOneWay("", "");
350 // rare case C-string input matching SBuf with N>strlen(s)
352 char *right
= xstrdup("foo34567890123456789012345678");
353 SBuf
left("fooZYXWVUTSRQPONMLKJIHGFEDCBA");
354 // is 3 bytes in length. NEVER more.
358 // pick another spot to truncate at if something goes horribly wrong.
360 left
.setAt(14, '\0');
362 const SBuf::size_type maxN
= 20 + min(left
.length(), static_cast<SBuf::size_type
>(strlen(right
)));
363 for (SBuf::size_type n
= 0; n
<= maxN
; ++n
) {
364 if (sign(strncmp(left
.rawContent(), right
, n
)) != sign(left
.cmp(right
, n
)) )
365 std::cerr
<< std::endl
<< " cmp(char*) " << n
<< ' ' << left
<< " ?= " << right
;
366 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
.rawContent(), right
, n
)), sign(left
.cmp(right
, n
)));
367 if (sign(strncasecmp(left
.rawContent(), right
, n
)) != sign(left
.caseCmp(right
, n
)))
368 std::cerr
<< std::endl
<< " caseCmp(char*) " << n
<< ' ' << left
<< " ?= " << right
;
369 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
.rawContent(), right
, n
)), sign(left
.caseCmp(right
, n
)));
376 testSBuf::testConsume()
378 SBuf
s1(literal
),s2
,s3
;
381 CPPUNIT_ASSERT_EQUAL(s2
,s3
);
382 s3
.assign("quick brown fox jumped over the lazy dog");
383 CPPUNIT_ASSERT_EQUAL(s1
,s3
);
385 CPPUNIT_ASSERT_EQUAL(s1
,SBuf());
389 testSBuf::testRawContent()
395 foo
= s1
.rawContent();
396 CPPUNIT_ASSERT_EQUAL(0,strncmp(fox
,foo
,s1
.length()));
398 CPPUNIT_ASSERT(!strcmp(fox
,foo
));
402 testSBuf::testRawSpace()
406 SBuf::size_type sz
=s2
.length();
407 char *rb
=s2
.rawSpace(strlen(fox2
)+1);
409 s2
.forceSize(sz
+strlen(fox2
));
410 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
419 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
423 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
424 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
426 std::string
s(alphabet
); // TODO
431 CPPUNIT_ASSERT_EQUAL(ref
,b
);
435 b
.chop(b
.length()-3);
437 CPPUNIT_ASSERT_EQUAL(ref
,b
);
439 { // chop at beginning
443 CPPUNIT_ASSERT_EQUAL(ref
,b
);
445 { // chop to zero length
449 CPPUNIT_ASSERT_EQUAL(ref
,b
);
451 { // chop beyond end (at npos)
453 b
.chop(SBuf::npos
,4);
455 CPPUNIT_ASSERT_EQUAL(ref
,b
);
459 b
.chop(b
.length()+2,4);
461 CPPUNIT_ASSERT_EQUAL(ref
,b
);
465 b
.chop(0,b
.length());
467 CPPUNIT_ASSERT_EQUAL(ref
,b
);
469 { // overflow chopped area
471 b
.chop(b
.length()-3,b
.length());
473 CPPUNIT_ASSERT_EQUAL(ref
,b
);
478 testSBuf::testChomp()
480 SBuf
s1("complete string");
483 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
484 s2
.assign(" complete string ,");
486 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
487 s1
.assign(", complete string ,");
490 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
493 // inspired by SBufFindTest; to be expanded.
494 class SBufSubstrAutoTest
497 std::string fullReference
, str
;
499 void performEqualityTest() {
501 CPPUNIT_ASSERT_EQUAL(ref
,sb
);
503 SBufSubstrAutoTest() : fullString(fox
), fullReference(fox
) {
504 for (int offset
=fullString
.length()-1; offset
>= 0; --offset
) {
505 for (int length
=fullString
.length()-1-offset
; length
>= 0; --length
) {
506 sb
=fullString
.substr(offset
,length
);
507 str
=fullReference
.substr(offset
,length
);
508 performEqualityTest();
515 testSBuf::testSubstr()
517 SBuf
s1(literal
),s2
,s3
;
520 CPPUNIT_ASSERT_EQUAL(s2
,s3
);
522 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
523 SBufSubstrAutoTest sat
; // work done in the constructor
527 testSBuf::testFindChar()
529 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
532 SBuf::size_type nposResult
=SBuf::npos
;
535 // needle in haystack
537 CPPUNIT_ASSERT_EQUAL(3U,idx
);
538 CPPUNIT_ASSERT_EQUAL('d',s1
[idx
]);
540 // needle not present in haystack
541 idx
=s1
.find(' '); //fails
542 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
546 CPPUNIT_ASSERT_EQUAL(4U,idx
);
548 // char not in searched portion
550 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
552 // invalid start position
553 idx
=s1
.find('d',SBuf::npos
);
554 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
556 // search outside of haystack
557 idx
=s1
.find('d',s1
.length()+1);
558 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
561 // needle in haystack
563 CPPUNIT_ASSERT_EQUAL(3U, idx
);
564 CPPUNIT_ASSERT_EQUAL('d', s1
[idx
]);
566 // needle not present in haystack
567 idx
=s1
.rfind(' '); //fails
568 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
572 CPPUNIT_ASSERT_EQUAL(4U,idx
);
574 // char not in searched portion
576 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
578 // overlong haystack specification
579 idx
=s1
.rfind('d',s1
.length()+1);
580 CPPUNIT_ASSERT_EQUAL(3U,idx
);
584 testSBuf::testFindSBuf()
586 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
587 SBuf
haystack(alphabet
);
589 SBuf::size_type nposResult
=SBuf::npos
;
592 // needle in haystack
593 idx
= haystack
.find(SBuf("def"));
594 CPPUNIT_ASSERT_EQUAL(3U,idx
);
596 idx
= haystack
.find(SBuf("xyz"));
597 CPPUNIT_ASSERT_EQUAL(23U,idx
);
599 // needle not in haystack, no initial char match
600 idx
= haystack
.find(SBuf(" eq"));
601 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
603 // needle not in haystack, initial sequence match
604 idx
= haystack
.find(SBuf("deg"));
605 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
607 // needle past end of haystack
608 idx
= haystack
.find(SBuf("xyz1"));
609 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
611 // search in portion: needle not in searched part
612 idx
= haystack
.find(SBuf("def"),7);
613 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
615 // search in portion: overhang
616 idx
= haystack
.find(SBuf("def"),4);
617 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
619 // invalid start position
620 idx
= haystack
.find(SBuf("def"),SBuf::npos
);
621 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
623 // needle bigger than haystack
624 idx
= SBuf("def").find(haystack
);
625 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
627 // search in a double-matching haystack
632 idx
= h2
.find(SBuf("def"));
633 CPPUNIT_ASSERT_EQUAL(3U,idx
);
635 idx
= h2
.find(SBuf("xyzab"));
636 CPPUNIT_ASSERT_EQUAL(23U,idx
);
640 // needle in haystack
641 idx
= haystack
.rfind(SBuf("def"));
642 CPPUNIT_ASSERT_EQUAL(3U,idx
);
644 idx
= haystack
.rfind(SBuf("xyz"));
645 CPPUNIT_ASSERT_EQUAL(23U,idx
);
647 // needle not in haystack, no initial char match
648 idx
= haystack
.rfind(SBuf(" eq"));
649 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
651 // needle not in haystack, initial sequence match
652 idx
= haystack
.rfind(SBuf("deg"));
653 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
655 // needle past end of haystack
656 idx
= haystack
.rfind(SBuf("xyz1"));
657 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
659 // search in portion: needle in searched part
660 idx
= haystack
.rfind(SBuf("def"),7);
661 CPPUNIT_ASSERT_EQUAL(3U, idx
);
663 // search in portion: needle not in searched part
664 idx
= haystack
.rfind(SBuf("mno"),3);
665 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
667 // search in portion: overhang
668 idx
= haystack
.rfind(SBuf("def"),4);
669 CPPUNIT_ASSERT_EQUAL(3U, idx
);
671 // npos start position
672 idx
= haystack
.rfind(SBuf("def"),SBuf::npos
);
673 CPPUNIT_ASSERT_EQUAL(3U, idx
);
675 // needle bigger than haystack
676 idx
= SBuf("def").rfind(haystack
);
677 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
679 // search in a double-matching haystack
684 idx
= h2
.rfind(SBuf("def"));
685 CPPUNIT_ASSERT_EQUAL(29U,idx
);
687 idx
= h2
.find(SBuf("xyzab"));
688 CPPUNIT_ASSERT_EQUAL(23U,idx
);
693 testSBuf::testRFindChar()
698 CPPUNIT_ASSERT_EQUAL(40U,idx
);
699 CPPUNIT_ASSERT_EQUAL(' ',s1
[idx
]);
703 testSBuf::testRFindSBuf()
705 SBuf
haystack(literal
),afox("fox");
706 SBuf
goobar("goobar");
709 // corner case: search for a zero-length SBuf
710 idx
=haystack
.rfind(SBuf(""));
711 CPPUNIT_ASSERT_EQUAL(haystack
.length(),idx
);
713 // corner case: search for a needle longer than the haystack
714 idx
=afox
.rfind(SBuf(" "));
715 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
717 idx
=haystack
.rfind(SBuf("fox"));
718 CPPUNIT_ASSERT_EQUAL(16U,idx
);
720 // needle not found, no match for first char
721 idx
=goobar
.rfind(SBuf("foo"));
722 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
724 // needle not found, match for first char but no match for SBuf
725 idx
=haystack
.rfind(SBuf("foe"));
726 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
728 SBuf
g("g"); //match at the last char
729 idx
=haystack
.rfind(g
);
730 CPPUNIT_ASSERT_EQUAL(43U,idx
);
731 CPPUNIT_ASSERT_EQUAL('g',haystack
[idx
]);
733 idx
=haystack
.rfind(SBuf("The"));
734 CPPUNIT_ASSERT_EQUAL(0U,idx
);
736 haystack
.append("The");
737 idx
=haystack
.rfind(SBuf("The"));
738 CPPUNIT_ASSERT_EQUAL(44U,idx
);
741 haystack
="The quick brown fox";
742 SBuf
needle("foxy lady");
743 idx
=haystack
.rfind(needle
);
744 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
748 testSBuf::testSBufLength()
751 CPPUNIT_ASSERT_EQUAL(strlen(fox
),(size_t)s
.length());
755 testSBuf::testScanf()
762 s1
.assign("string , 123 , 123.50");
763 rv
=s1
.scanf("%s , %d , %f",s
,&i
,&f
);
764 CPPUNIT_ASSERT_EQUAL(3,rv
);
765 CPPUNIT_ASSERT_EQUAL(0,strcmp(s
,"string"));
766 CPPUNIT_ASSERT_EQUAL(123,i
);
767 CPPUNIT_ASSERT_EQUAL(static_cast<float>(123.5),f
);
773 char buf
[40]; //shorter than literal()
775 CPPUNIT_ASSERT_EQUAL(s
.length(),s
.copy(buf
,40));
776 CPPUNIT_ASSERT_EQUAL(0,strncmp(s
.rawContent(),buf
,s
.length()));
778 CPPUNIT_ASSERT_EQUAL(40U,s
.copy(buf
,40));
781 CPPUNIT_ASSERT_EQUAL(s2
,s
);
785 testSBuf::testStringOps()
787 SBuf
sng(ToLower(literal
)),
788 ref("the quick brown fox jumped over the lazy dog");
789 CPPUNIT_ASSERT_EQUAL(ref
,sng
);
791 CPPUNIT_ASSERT_EQUAL(0,sng
.compare(ref
,caseInsensitive
));
792 // max-size comparison
793 CPPUNIT_ASSERT_EQUAL(0,ref
.compare(SBuf("THE"),caseInsensitive
,3));
794 CPPUNIT_ASSERT_EQUAL(1,ref
.compare(SBuf("THE"),caseInsensitive
,6));
795 CPPUNIT_ASSERT_EQUAL(0,SBuf("the").compare(SBuf("THE"),caseInsensitive
,6));
803 const char *ref
=t
.rawContent();
804 t
.reserveCapacity(10240);
805 const char *match
=t
.rawContent();
806 CPPUNIT_ASSERT(match
!=ref
);
808 t
.append(literal
).append(literal
).append(literal
).append(literal
).append(literal
);
809 t
.append(t
).append(t
).append(t
).append(t
).append(t
);
810 CPPUNIT_ASSERT_EQUAL(ref
,match
);
814 testSBuf::testStartsWith()
816 static SBuf
casebuf("THE QUICK");
817 CPPUNIT_ASSERT(literal
.startsWith(SBuf(fox1
)));
818 CPPUNIT_ASSERT(!SBuf("The quick brown").startsWith(SBuf(fox1
))); //too short
819 CPPUNIT_ASSERT(!literal
.startsWith(SBuf(fox2
))); //different contents
821 // case-insensitive checks
822 CPPUNIT_ASSERT(literal
.startsWith(casebuf
,caseInsensitive
));
823 casebuf
=ToUpper(SBuf(fox1
));
824 CPPUNIT_ASSERT(literal
.startsWith(casebuf
,caseInsensitive
));
825 CPPUNIT_ASSERT(literal
.startsWith(SBuf(fox1
),caseInsensitive
));
826 casebuf
= "tha quick";
827 CPPUNIT_ASSERT_EQUAL(false,literal
.startsWith(casebuf
,caseInsensitive
));
831 testSBuf::testSBufStream()
833 SBuf
b("const.string, int 10 and a float 10.5");
835 ss
<< "const.string, int " << 10 << " and a float " << 10.5;
837 CPPUNIT_ASSERT_EQUAL(b
,o
);
840 CPPUNIT_ASSERT_EQUAL(SBuf(),o
);
844 CPPUNIT_ASSERT_EQUAL(ss2
.buf(),literal
);
845 CPPUNIT_ASSERT_EQUAL(f1
,SBuf(fox1
));
849 testSBuf::testFindFirstOf()
851 SBuf
haystack(literal
);
855 idx
=haystack
.findFirstOf(CharacterSet("t1","ADHRWYP"));
856 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
858 // found at beginning
859 idx
=haystack
.findFirstOf(CharacterSet("t2","THANDF"));
860 CPPUNIT_ASSERT_EQUAL(0U,idx
);
862 //found at end of haystack
863 idx
=haystack
.findFirstOf(CharacterSet("t3","QWERYVg"));
864 CPPUNIT_ASSERT_EQUAL(haystack
.length()-1,idx
);
866 //found in the middle of haystack
867 idx
=haystack
.findFirstOf(CharacterSet("t4","QWERqYV"));
868 CPPUNIT_ASSERT_EQUAL(4U,idx
);
872 testSBuf::testFindFirstNotOf()
874 SBuf
haystack(literal
);
877 // all chars from the set
878 idx
=haystack
.findFirstNotOf(CharacterSet("t1",literal
.c_str()));
879 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
881 // found at beginning
882 idx
=haystack
.findFirstNotOf(CharacterSet("t2","a"));
883 CPPUNIT_ASSERT_EQUAL(0U,idx
);
885 //found at end of haystack
886 idx
=haystack
.findFirstNotOf(CharacterSet("t3",literal
.substr(0,literal
.length()-1).c_str()));
887 CPPUNIT_ASSERT_EQUAL(haystack
.length()-1,idx
);
889 //found in the middle of haystack
890 idx
=haystack
.findFirstNotOf(CharacterSet("t4","The"));
891 CPPUNIT_ASSERT_EQUAL(3U,idx
);
895 testSBuf::testAutoFind()
902 testSBuf::testStdStringOps()
904 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
905 std::string
astr(alphabet
);
907 CPPUNIT_ASSERT_EQUAL(astr
,sb
.toStdString());