]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testSBuf.cc
2 * Copyright (C) 1996-2014 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"
20 CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf
);
22 /* let this test link sanely */
24 #include "MemObject.h"
26 eventAdd(const char *name
, EVH
* func
, void *arg
, double when
, int, bool cbdata
)
29 MemObject::endOffset() const
34 static char fox
[]="The quick brown fox jumped over the lazy dog";
35 static char fox1
[]="The quick brown fox ";
36 static char fox2
[]="jumped over the lazy dog";
38 // TEST: globals variables (default/empty and with contents) are
39 // created outside and before any unit tests and memory subsystem
40 // initialization. Check for correct constructor operation.
42 SBuf
literal("The quick brown fox jumped over the lazy dog");
45 testSBuf::testSBufConstructDestruct()
47 /* NOTE: Do not initialize memory here because we need
48 * to test correct operation before and after Mem::Init
51 // XXX: partial demo below of how to do constructor unit-test. use scope to ensure each test
52 // is working on local-scope variables constructed fresh for the test, and destructed when
53 // scope exists. use nested scopes to test destructor affects on copied data (MemBlob etc)
55 // TEST: default constructor (implicit destructor non-crash test)
56 // test accessors on empty SBuf.
59 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
60 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
61 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
62 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
65 // TEST: copy-construct NULL string (implicit destructor non-crash test)
68 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
69 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
70 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
71 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
74 // TEST: copy-construct empty string (implicit destructor non-crash test)
77 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
78 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
79 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
80 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
83 // TEST: copy-construct from a SBuf
86 CPPUNIT_ASSERT_EQUAL(0U,s1
.length());
87 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1
);
88 CPPUNIT_ASSERT_EQUAL(empty_sbuf
,s1
);
89 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1
.c_str()));
92 CPPUNIT_ASSERT_EQUAL(literal
,s5
);
94 CPPUNIT_ASSERT_EQUAL(literal
,s6
);
95 // XXX: other state checks. expected result of calling any state accessor on s4 ?
98 // TEST: check that COW doesn't happen upon copy-construction
100 SBuf
s1(empty_sbuf
), s2(s1
);
101 CPPUNIT_ASSERT_EQUAL(s1
.rawContent(), s2
.rawContent());
102 SBuf
s3(literal
), s4(literal
);
103 CPPUNIT_ASSERT_EQUAL(s3
.rawContent(), s4
.rawContent());
106 // TEST: sub-string copy
108 SBuf s1
=SBuf(fox
+4), s2(fox
);
109 SBuf s3
=s2
.substr(4,s2
.length()); //n is out-of-bounds
110 CPPUNIT_ASSERT_EQUAL(s1
,s3
);
113 CPPUNIT_ASSERT_EQUAL(s4
,s3
);
116 // TEST: go via SquidString adapters.
120 CPPUNIT_ASSERT_EQUAL(literal
,s1
);
123 // TEST: go via std::string adapter.
125 std::string
str(fox
);
127 CPPUNIT_ASSERT_EQUAL(literal
,s1
);
132 testSBuf::testSBufConstructDestructAfterMemInit()
135 testSBufConstructDestruct();
139 testSBuf::testEqualityTest()
141 SBuf
s1(fox
),s2(fox
);
142 CPPUNIT_ASSERT_EQUAL(s1
,s1
); //self-equality
143 CPPUNIT_ASSERT_EQUAL(s1
,s2
); //same contents
144 s2
.assign("The quick brown fox jumped over the lazy doe");
145 CPPUNIT_ASSERT(!(s1
== s2
)); //same length, different contents
147 CPPUNIT_ASSERT(!(s1
== s2
)); //different length and contents
148 CPPUNIT_ASSERT(s1
!= s2
); //while we're ready, let's test inequality
150 CPPUNIT_ASSERT(!(s1
== s2
)); //null and not-null
151 CPPUNIT_ASSERT(s1
!= s2
); //while we're ready, let's test inequality
153 CPPUNIT_ASSERT_EQUAL(s1
,s2
); //null and null
157 testSBuf::testAppendSBuf()
159 SBuf
s1(fox1
),s2(fox2
);
161 CPPUNIT_ASSERT_EQUAL(s1
,literal
);
165 testSBuf::testPrintf()
168 s1
.Printf("%s:%d:%03.3f","fox",10,12345.67);
169 s2
.assign("fox:10:12345.670");
170 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
174 testSBuf::testAppendCString()
178 CPPUNIT_ASSERT_EQUAL(s1
,literal
);
182 testSBuf::testAppendStdString()
184 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
186 SBuf
alpha(alphabet
), s
;
187 s
.append(alphabet
,5).append(alphabet
+5);
188 CPPUNIT_ASSERT_EQUAL(alpha
,s
);
193 s
.append(alphabet
,5).append("\0",1).append(alphabet
+6,SBuf::npos
);
194 control
.append(alphabet
,5).append(1,'\0').append(alphabet
,6,std::string::npos
);
195 SBuf
scontrol(control
); // we need this to test the equality. sigh.
196 CPPUNIT_ASSERT_EQUAL(scontrol
,s
);
199 const char *alphazero
="abcdefghijk\0mnopqrstuvwxyz";
200 SBuf
s(alphazero
,26);
201 std::string
str(alphazero
,26);
202 CPPUNIT_ASSERT_EQUAL(0,memcmp(str
.data(),s
.rawContent(),26));
207 testSBuf::testAppendf()
210 s1
.appendf("%s:%d:%03.2f",fox
,1234,1234.56);
211 s2
.assign("The quick brown fox jumped over the lazy dog:1234:1234.56");
212 CPPUNIT_ASSERT_EQUAL(s2
,s1
);
216 testSBuf::testDumpStats()
218 SBuf::GetStats().dump(std::cout
);
219 MemBlob::GetStats().dump(std::cout
);
220 std::cout
<< "sizeof(SBuf): " << sizeof(SBuf
) << std::endl
;
221 std::cout
<< "sizeof(MemBlob): " << sizeof(MemBlob
) << std::endl
;
225 testSBuf::testSubscriptOp()
228 CPPUNIT_ASSERT_EQUAL(chg
[5],'u');
230 CPPUNIT_ASSERT_EQUAL(literal
[5],'u');
231 CPPUNIT_ASSERT_EQUAL(chg
[5],'e');
234 // note: can't use cppunit's CPPUNIT_TEST_EXCEPTION because TextException asserts, and
235 // so the test can't be properly completed.
237 testSBuf::testSubscriptOpFail()
240 c
=literal
.at(literal
.length()); //out of bounds by 1
242 std::cout
<< c
<< std::endl
;
245 static int sign(int v
)
255 testComparisonStdFull(const char *left
, const char *right
)
257 if (sign(strcmp(left
, right
)) != sign(SBuf(left
).cmp(SBuf(right
))))
258 std::cerr
<< std::endl
<< " cmp(SBuf) npos " << left
<< " ?= " << right
<< std::endl
;
259 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left
, right
)), sign(SBuf(left
).cmp(SBuf(right
))));
261 if (sign(strcmp(left
, right
)) != sign(SBuf(left
).cmp(right
)))
262 std::cerr
<< std::endl
<< " cmp(char*) npos " << left
<< " ?= " << right
<< std::endl
;
263 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left
, right
)), sign(SBuf(left
).cmp(right
)));
265 if (sign(strcasecmp(left
, right
)) != sign(SBuf(left
).caseCmp(SBuf(right
))))
266 std::cerr
<< std::endl
<< " caseCmp(SBuf) npos " << left
<< " ?= " << right
<< std::endl
;
267 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left
, right
)), sign(SBuf(left
).caseCmp(SBuf(right
))));
269 if (sign(strcasecmp(left
, right
)) != sign(SBuf(left
).caseCmp(right
)))
270 std::cerr
<< std::endl
<< " caseCmp(char*) npos " << left
<< " ?= " << right
<< std::endl
;
271 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left
, right
)), sign(SBuf(left
).caseCmp(right
)));
275 testComparisonStdN(const char *left
, const char *right
, const size_t n
)
277 if (sign(strncmp(left
, right
, n
)) != sign(SBuf(left
).cmp(SBuf(right
), n
)))
278 std::cerr
<< std::endl
<< " cmp(SBuf) " << n
<< ' ' << left
<< " ?= " << right
<< std::endl
;
279 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
, right
, n
)), sign(SBuf(left
).cmp(SBuf(right
), n
)));
281 if (sign(strncmp(left
, right
, n
)) != sign(SBuf(left
).cmp(right
, n
)))
282 std::cerr
<< std::endl
<< " cmp(char*) " << n
<< ' ' << SBuf(left
) << " ?= " << right
<< std::endl
;
283 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
, right
, n
)), sign(SBuf(left
).cmp(right
, n
)));
285 if (sign(strncasecmp(left
, right
, n
)) != sign(SBuf(left
).caseCmp(SBuf(right
), n
)))
286 std::cerr
<< std::endl
<< " caseCmp(SBuf) " << n
<< ' ' << left
<< " ?= " << right
<< std::endl
;
287 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
, right
, n
)), sign(SBuf(left
).caseCmp(SBuf(right
), n
)));
289 if (sign(strncasecmp(left
, right
, n
)) != sign(SBuf(left
).caseCmp(right
, n
)))
290 std::cerr
<< std::endl
<< " caseCmp(char*) " << n
<< ' ' << SBuf(left
) << " ?= " << right
<< std::endl
;
291 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
, right
, n
)), sign(SBuf(left
).caseCmp(right
, n
)));
295 testComparisonStdOneWay(const char *left
, const char *right
)
297 testComparisonStdFull(left
, right
);
298 const size_t maxN
= 2 + min(strlen(left
), strlen(right
));
299 for (size_t n
= 0; n
<= maxN
; ++n
) {
300 testComparisonStdN(left
, right
, n
);
305 testComparisonStd(const char *s1
, const char *s2
)
307 testComparisonStdOneWay(s1
, s2
);
308 testComparisonStdOneWay(s2
, s1
);
312 testSBuf::testComparisons()
315 SBuf
s1("foo"),s2("foe");
316 CPPUNIT_ASSERT(s1
.cmp(s2
)>0);
317 CPPUNIT_ASSERT(s1
.caseCmp(s2
)>0);
318 CPPUNIT_ASSERT(s2
.cmp(s1
)<0);
319 CPPUNIT_ASSERT_EQUAL(0,s1
.cmp(s2
,2));
320 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
321 CPPUNIT_ASSERT(s1
> s2
);
322 CPPUNIT_ASSERT(s2
< s1
);
323 CPPUNIT_ASSERT_EQUAL(sign(s1
.cmp(s2
)),sign(strcmp(s1
.c_str(),s2
.c_str())));
327 CPPUNIT_ASSERT(s1
.cmp(s2
)<0);
328 CPPUNIT_ASSERT_EQUAL(sign(s1
.cmp(s2
)),sign(strcmp(s1
.c_str(),s2
.c_str())));
329 CPPUNIT_ASSERT(s1
< s2
);
330 // specifying the max-length and overhanging size
331 CPPUNIT_ASSERT_EQUAL(1,SBuf("foolong").caseCmp(SBuf("foo"), 5));
332 // case-insensive comaprison
335 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
));
336 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
337 // \0-clenliness test
338 s1
.assign("f\0oo",4);
339 s2
.assign("f\0Oo",4);
340 CPPUNIT_ASSERT(s1
.cmp(s2
) > 0);
341 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
));
342 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,3));
343 CPPUNIT_ASSERT_EQUAL(0,s1
.caseCmp(s2
,2));
344 CPPUNIT_ASSERT_EQUAL(0,s1
.cmp(s2
,2));
346 testComparisonStd("foo", "fooz");
347 testComparisonStd("foo", "foo");
348 testComparisonStd("foo", "f");
349 testComparisonStd("foo", "bar");
351 testComparisonStd("foo", "FOOZ");
352 testComparisonStd("foo", "FOO");
353 testComparisonStd("foo", "F");
355 testComparisonStdOneWay("", "");
357 // rare case C-string input matching SBuf with N>strlen(s)
359 char *right
= xstrdup("foo34567890123456789012345678");
360 SBuf
left("fooZYXWVUTSRQPONMLKJIHGFEDCBA");
361 // is 3 bytes in length. NEVER more.
365 // pick another spot to truncate at if something goes horribly wrong.
367 left
.setAt(14, '\0');
369 const SBuf::size_type maxN
= 20 + min(left
.length(), static_cast<SBuf::size_type
>(strlen(right
)));
370 for (SBuf::size_type n
= 0; n
<= maxN
; ++n
) {
371 if (sign(strncmp(left
.rawContent(), right
, n
)) != sign(left
.cmp(right
, n
)) )
372 std::cerr
<< std::endl
<< " cmp(char*) " << n
<< ' ' << left
<< " ?= " << right
;
373 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left
.rawContent(), right
, n
)), sign(left
.cmp(right
, n
)));
374 if (sign(strncasecmp(left
.rawContent(), right
, n
)) != sign(left
.caseCmp(right
, n
)))
375 std::cerr
<< std::endl
<< " caseCmp(char*) " << n
<< ' ' << left
<< " ?= " << right
;
376 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left
.rawContent(), right
, n
)), sign(left
.caseCmp(right
, n
)));
383 testSBuf::testConsume()
385 SBuf
s1(literal
),s2
,s3
;
388 CPPUNIT_ASSERT_EQUAL(s2
,s3
);
389 s3
.assign("quick brown fox jumped over the lazy dog");
390 CPPUNIT_ASSERT_EQUAL(s1
,s3
);
392 CPPUNIT_ASSERT_EQUAL(s1
,SBuf());
396 testSBuf::testRawContent()
402 foo
= s1
.rawContent();
403 CPPUNIT_ASSERT_EQUAL(0,strncmp(fox
,foo
,s1
.length()));
405 CPPUNIT_ASSERT(!strcmp(fox
,foo
));
409 testSBuf::testRawSpace()
413 SBuf::size_type sz
=s2
.length();
414 char *rb
=s2
.rawSpace(strlen(fox2
)+1);
416 s2
.forceSize(sz
+strlen(fox2
));
417 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
426 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
430 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
431 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
433 std::string
s(alphabet
); // TODO
438 CPPUNIT_ASSERT_EQUAL(ref
,b
);
442 b
.chop(b
.length()-3);
444 CPPUNIT_ASSERT_EQUAL(ref
,b
);
446 { // chop at beginning
450 CPPUNIT_ASSERT_EQUAL(ref
,b
);
452 { // chop to zero length
456 CPPUNIT_ASSERT_EQUAL(ref
,b
);
458 { // chop beyond end (at npos)
460 b
.chop(SBuf::npos
,4);
462 CPPUNIT_ASSERT_EQUAL(ref
,b
);
466 b
.chop(b
.length()+2,4);
468 CPPUNIT_ASSERT_EQUAL(ref
,b
);
472 b
.chop(0,b
.length());
474 CPPUNIT_ASSERT_EQUAL(ref
,b
);
476 { // overflow chopped area
478 b
.chop(b
.length()-3,b
.length());
480 CPPUNIT_ASSERT_EQUAL(ref
,b
);
485 testSBuf::testChomp()
487 SBuf
s1("complete string");
490 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
491 s2
.assign(" complete string ,");
493 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
494 s1
.assign(", complete string ,");
497 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
500 // inspired by SBufFindTest; to be expanded.
501 class SBufSubstrAutoTest
504 std::string fullReference
, str
;
506 void performEqualityTest() {
508 CPPUNIT_ASSERT_EQUAL(ref
,sb
);
510 SBufSubstrAutoTest() : fullString(fox
), fullReference(fox
) {
511 for (int offset
=fullString
.length()-1; offset
>= 0; --offset
) {
512 for (int length
=fullString
.length()-1-offset
; length
>= 0; --length
) {
513 sb
=fullString
.substr(offset
,length
);
514 str
=fullReference
.substr(offset
,length
);
515 performEqualityTest();
522 testSBuf::testSubstr()
524 SBuf
s1(literal
),s2
,s3
;
527 CPPUNIT_ASSERT_EQUAL(s2
,s3
);
529 CPPUNIT_ASSERT_EQUAL(s1
,s2
);
530 SBufSubstrAutoTest sat
; // work done in the constructor
534 testSBuf::testFindChar()
536 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
539 SBuf::size_type nposResult
=SBuf::npos
;
542 // needle in haystack
544 CPPUNIT_ASSERT_EQUAL(3U,idx
);
545 CPPUNIT_ASSERT_EQUAL('d',s1
[idx
]);
547 // needle not present in haystack
548 idx
=s1
.find(' '); //fails
549 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
553 CPPUNIT_ASSERT_EQUAL(4U,idx
);
555 // char not in searched portion
557 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
559 // invalid start position
560 idx
=s1
.find('d',SBuf::npos
);
561 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
563 // search outside of haystack
564 idx
=s1
.find('d',s1
.length()+1);
565 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
568 // needle in haystack
570 CPPUNIT_ASSERT_EQUAL(3U, idx
);
571 CPPUNIT_ASSERT_EQUAL('d', s1
[idx
]);
573 // needle not present in haystack
574 idx
=s1
.rfind(' '); //fails
575 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
579 CPPUNIT_ASSERT_EQUAL(4U,idx
);
581 // char not in searched portion
583 CPPUNIT_ASSERT_EQUAL(nposResult
,idx
);
585 // overlong haystack specification
586 idx
=s1
.rfind('d',s1
.length()+1);
587 CPPUNIT_ASSERT_EQUAL(3U,idx
);
591 testSBuf::testFindSBuf()
593 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
594 SBuf
haystack(alphabet
);
596 SBuf::size_type nposResult
=SBuf::npos
;
599 // needle in haystack
600 idx
= haystack
.find(SBuf("def"));
601 CPPUNIT_ASSERT_EQUAL(3U,idx
);
603 idx
= haystack
.find(SBuf("xyz"));
604 CPPUNIT_ASSERT_EQUAL(23U,idx
);
606 // needle not in haystack, no initial char match
607 idx
= haystack
.find(SBuf(" eq"));
608 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
610 // needle not in haystack, initial sequence match
611 idx
= haystack
.find(SBuf("deg"));
612 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
614 // needle past end of haystack
615 idx
= haystack
.find(SBuf("xyz1"));
616 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
618 // search in portion: needle not in searched part
619 idx
= haystack
.find(SBuf("def"),7);
620 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
622 // search in portion: overhang
623 idx
= haystack
.find(SBuf("def"),4);
624 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
626 // invalid start position
627 idx
= haystack
.find(SBuf("def"),SBuf::npos
);
628 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
630 // needle bigger than haystack
631 idx
= SBuf("def").find(haystack
);
632 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
634 // search in a double-matching haystack
639 idx
= h2
.find(SBuf("def"));
640 CPPUNIT_ASSERT_EQUAL(3U,idx
);
642 idx
= h2
.find(SBuf("xyzab"));
643 CPPUNIT_ASSERT_EQUAL(23U,idx
);
647 // needle in haystack
648 idx
= haystack
.rfind(SBuf("def"));
649 CPPUNIT_ASSERT_EQUAL(3U,idx
);
651 idx
= haystack
.rfind(SBuf("xyz"));
652 CPPUNIT_ASSERT_EQUAL(23U,idx
);
654 // needle not in haystack, no initial char match
655 idx
= haystack
.rfind(SBuf(" eq"));
656 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
658 // needle not in haystack, initial sequence match
659 idx
= haystack
.rfind(SBuf("deg"));
660 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
662 // needle past end of haystack
663 idx
= haystack
.rfind(SBuf("xyz1"));
664 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
666 // search in portion: needle in searched part
667 idx
= haystack
.rfind(SBuf("def"),7);
668 CPPUNIT_ASSERT_EQUAL(3U, idx
);
670 // search in portion: needle not in searched part
671 idx
= haystack
.rfind(SBuf("mno"),3);
672 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
674 // search in portion: overhang
675 idx
= haystack
.rfind(SBuf("def"),4);
676 CPPUNIT_ASSERT_EQUAL(3U, idx
);
678 // npos start position
679 idx
= haystack
.rfind(SBuf("def"),SBuf::npos
);
680 CPPUNIT_ASSERT_EQUAL(3U, idx
);
682 // needle bigger than haystack
683 idx
= SBuf("def").rfind(haystack
);
684 CPPUNIT_ASSERT_EQUAL(nposResult
, idx
);
686 // search in a double-matching haystack
691 idx
= h2
.rfind(SBuf("def"));
692 CPPUNIT_ASSERT_EQUAL(29U,idx
);
694 idx
= h2
.find(SBuf("xyzab"));
695 CPPUNIT_ASSERT_EQUAL(23U,idx
);
700 testSBuf::testRFindChar()
705 CPPUNIT_ASSERT_EQUAL(40U,idx
);
706 CPPUNIT_ASSERT_EQUAL(' ',s1
[idx
]);
710 testSBuf::testRFindSBuf()
712 SBuf
haystack(literal
),afox("fox");
713 SBuf
goobar("goobar");
716 // corner case: search for a zero-length SBuf
717 idx
=haystack
.rfind(SBuf(""));
718 CPPUNIT_ASSERT_EQUAL(haystack
.length(),idx
);
720 // corner case: search for a needle longer than the haystack
721 idx
=afox
.rfind(SBuf(" "));
722 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
724 idx
=haystack
.rfind(SBuf("fox"));
725 CPPUNIT_ASSERT_EQUAL(16U,idx
);
727 // needle not found, no match for first char
728 idx
=goobar
.rfind(SBuf("foo"));
729 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
731 // needle not found, match for first char but no match for SBuf
732 idx
=haystack
.rfind(SBuf("foe"));
733 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
735 SBuf
g("g"); //match at the last char
736 idx
=haystack
.rfind(g
);
737 CPPUNIT_ASSERT_EQUAL(43U,idx
);
738 CPPUNIT_ASSERT_EQUAL('g',haystack
[idx
]);
740 idx
=haystack
.rfind(SBuf("The"));
741 CPPUNIT_ASSERT_EQUAL(0U,idx
);
743 haystack
.append("The");
744 idx
=haystack
.rfind(SBuf("The"));
745 CPPUNIT_ASSERT_EQUAL(44U,idx
);
748 haystack
="The quick brown fox";
749 SBuf
needle("foxy lady");
750 idx
=haystack
.rfind(needle
);
751 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
755 testSBuf::testSBufLength()
758 CPPUNIT_ASSERT_EQUAL(strlen(fox
),(size_t)s
.length());
762 testSBuf::testScanf()
769 s1
.assign("string , 123 , 123.50");
770 rv
=s1
.scanf("%s , %d , %f",s
,&i
,&f
);
771 CPPUNIT_ASSERT_EQUAL(3,rv
);
772 CPPUNIT_ASSERT_EQUAL(0,strcmp(s
,"string"));
773 CPPUNIT_ASSERT_EQUAL(123,i
);
774 CPPUNIT_ASSERT_EQUAL(static_cast<float>(123.5),f
);
780 char buf
[40]; //shorter than literal()
782 CPPUNIT_ASSERT_EQUAL(s
.length(),s
.copy(buf
,40));
783 CPPUNIT_ASSERT_EQUAL(0,strncmp(s
.rawContent(),buf
,s
.length()));
785 CPPUNIT_ASSERT_EQUAL(40U,s
.copy(buf
,40));
788 CPPUNIT_ASSERT_EQUAL(s2
,s
);
792 testSBuf::testStringOps()
794 SBuf
sng(ToLower(literal
)),
795 ref("the quick brown fox jumped over the lazy dog");
796 CPPUNIT_ASSERT_EQUAL(ref
,sng
);
798 CPPUNIT_ASSERT_EQUAL(0,sng
.compare(ref
,caseInsensitive
));
799 // max-size comparison
800 CPPUNIT_ASSERT_EQUAL(0,ref
.compare(SBuf("THE"),caseInsensitive
,3));
801 CPPUNIT_ASSERT_EQUAL(1,ref
.compare(SBuf("THE"),caseInsensitive
,6));
802 CPPUNIT_ASSERT_EQUAL(0,SBuf("the").compare(SBuf("THE"),caseInsensitive
,6));
810 const char *ref
=t
.rawContent();
811 t
.reserveCapacity(10240);
812 const char *match
=t
.rawContent();
813 CPPUNIT_ASSERT(match
!=ref
);
815 t
.append(literal
).append(literal
).append(literal
).append(literal
).append(literal
);
816 t
.append(t
).append(t
).append(t
).append(t
).append(t
);
817 CPPUNIT_ASSERT_EQUAL(ref
,match
);
821 testSBuf::testStartsWith()
823 static SBuf
casebuf("THE QUICK");
824 CPPUNIT_ASSERT(literal
.startsWith(SBuf(fox1
)));
825 CPPUNIT_ASSERT(!SBuf("The quick brown").startsWith(SBuf(fox1
))); //too short
826 CPPUNIT_ASSERT(!literal
.startsWith(SBuf(fox2
))); //different contents
828 // case-insensitive checks
829 CPPUNIT_ASSERT(literal
.startsWith(casebuf
,caseInsensitive
));
830 casebuf
=ToUpper(SBuf(fox1
));
831 CPPUNIT_ASSERT(literal
.startsWith(casebuf
,caseInsensitive
));
832 CPPUNIT_ASSERT(literal
.startsWith(SBuf(fox1
),caseInsensitive
));
833 casebuf
= "tha quick";
834 CPPUNIT_ASSERT_EQUAL(false,literal
.startsWith(casebuf
,caseInsensitive
));
838 testSBuf::testSBufStream()
840 SBuf
b("const.string, int 10 and a float 10.5");
842 ss
<< "const.string, int " << 10 << " and a float " << 10.5;
844 CPPUNIT_ASSERT_EQUAL(b
,o
);
847 CPPUNIT_ASSERT_EQUAL(SBuf(),o
);
851 CPPUNIT_ASSERT_EQUAL(ss2
.buf(),literal
);
852 CPPUNIT_ASSERT_EQUAL(f1
,SBuf(fox1
));
856 testSBuf::testFindFirstOf()
858 SBuf
haystack(literal
);
862 idx
=haystack
.findFirstOf(CharacterSet("t1","ADHRWYP"));
863 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
865 // found at beginning
866 idx
=haystack
.findFirstOf(CharacterSet("t2","THANDF"));
867 CPPUNIT_ASSERT_EQUAL(0U,idx
);
869 //found at end of haystack
870 idx
=haystack
.findFirstOf(CharacterSet("t3","QWERYVg"));
871 CPPUNIT_ASSERT_EQUAL(haystack
.length()-1,idx
);
873 //found in the middle of haystack
874 idx
=haystack
.findFirstOf(CharacterSet("t4","QWERqYV"));
875 CPPUNIT_ASSERT_EQUAL(4U,idx
);
879 testSBuf::testFindFirstNotOf()
881 SBuf
haystack(literal
);
884 // all chars from the set
885 idx
=haystack
.findFirstNotOf(CharacterSet("t1",literal
.c_str()));
886 CPPUNIT_ASSERT_EQUAL(SBuf::npos
,idx
);
888 // found at beginning
889 idx
=haystack
.findFirstNotOf(CharacterSet("t2","a"));
890 CPPUNIT_ASSERT_EQUAL(0U,idx
);
892 //found at end of haystack
893 idx
=haystack
.findFirstNotOf(CharacterSet("t3",literal
.substr(0,literal
.length()-1).c_str()));
894 CPPUNIT_ASSERT_EQUAL(haystack
.length()-1,idx
);
896 //found in the middle of haystack
897 idx
=haystack
.findFirstNotOf(CharacterSet("t4","The"));
898 CPPUNIT_ASSERT_EQUAL(3U,idx
);
902 testSBuf::testAutoFind()
909 testSBuf::testStdStringOps()
911 const char *alphabet
="abcdefghijklmnopqrstuvwxyz";
912 std::string
astr(alphabet
);
914 CPPUNIT_ASSERT_EQUAL(astr
,sb
.toStdString());