]> git.ipfire.org Git - thirdparty/squid.git/blame - src/tests/testSBuf.cc
Merged from trunk
[thirdparty/squid.git] / src / tests / testSBuf.cc
CommitLineData
412da427
FC
1#include "squid.h"
2#include "Mem.h"
3#include "SBuf.h"
412da427 4#include "SBufStream.h"
412da427
FC
5#include "SquidString.h"
6#include "testSBuf.h"
7#include "SBufFindTest.h"
8
9#include <iostream>
10#include <stdexcept>
11
12CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf );
13
14/* let this test link sanely */
15#include "event.h"
16#include "MemObject.h"
17void
18eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata)
19{}
20int64_t
21MemObject::endOffset() const
22{ return 0; }
23/* end of stubs */
24
25// test string
26static char fox[]="The quick brown fox jumped over the lazy dog";
27static char fox1[]="The quick brown fox ";
28static char fox2[]="jumped over the lazy dog";
29
30// TEST: globals variables (default/empty and with contents) are
31// created outside and before any unit tests and memory subsystem
32// initialization. Check for correct constructor operation.
33SBuf empty_sbuf;
34SBuf literal("The quick brown fox jumped over the lazy dog");
35
36void
37testSBuf::testSBufConstructDestruct()
38{
39 /* NOTE: Do not initialize memory here because we need
40 * to test correct operation before and after Mem::Init
41 */
42
43 // XXX: partial demo below of how to do constructor unit-test. use scope to ensure each test
44 // is working on local-scope variables constructed fresh for the test, and destructed when
45 // scope exists. use nested scopes to test destructor affects on copied data (MemBlob etc)
46
47 // TEST: default constructor (implicit destructor non-crash test)
48 // test accessors on empty SBuf.
49 {
50 SBuf s1;
51 CPPUNIT_ASSERT_EQUAL(s1.length(),0);
52 CPPUNIT_ASSERT_EQUAL(s1,SBuf(""));
53 CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf);
54 CPPUNIT_ASSERT(0==strcmp("",s1.c_str()));
55 }
56
57 // TEST: copy-construct NULL string (implicit destructor non-crash test)
58 {
59 SBuf s1(NULL);
60 CPPUNIT_ASSERT_EQUAL(s1.length(),0);
61 CPPUNIT_ASSERT_EQUAL(s1,SBuf(""));
62 CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf);
63 CPPUNIT_ASSERT(0==strcmp("",s1.c_str()));
64 }
65
66 // TEST: copy-construct empty string (implicit destructor non-crash test)
67 {
68 SBuf s1("");
69 CPPUNIT_ASSERT_EQUAL(s1.length(),0);
70 CPPUNIT_ASSERT_EQUAL(s1,SBuf(""));
71 CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf);
72 CPPUNIT_ASSERT(0==strcmp("",s1.c_str()));
73 }
74
a1fb178b
AJ
75 // TEST: copy-construct from a char*
76 {
77 SBuf s1(fox);
b64e98d2 78 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(s1.length()),strlen(fox));
a1fb178b
AJ
79 CPPUNIT_ASSERT(0==strcmp(fox,s1.c_str()));
80 }
81
412da427
FC
82 // TEST: copy-construct from a SBuf
83 {
84 SBuf s1(empty_sbuf);
85 CPPUNIT_ASSERT_EQUAL(s1.length(),0);
86 CPPUNIT_ASSERT_EQUAL(s1,SBuf(""));
87 CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf);
88 CPPUNIT_ASSERT(0==strcmp("",s1.c_str()));
89
90 SBuf s5(literal);
91 CPPUNIT_ASSERT_EQUAL(s5,literal);
92 SBuf s6(fox);
93 CPPUNIT_ASSERT_EQUAL(s6,literal);
94 // XXX: other state checks. expected result of calling any state accessor on s4 ?
95 }
96
97 // TEST: check that COW doesn't happen upon copy-construction
98 {
99 SBuf s1(empty_sbuf), s2(s1);
100 CPPUNIT_ASSERT_EQUAL(s1.rawContent(), s2.rawContent());
101 SBuf s3(literal), s4(literal);
102 CPPUNIT_ASSERT_EQUAL(s3.rawContent(), s4.rawContent());
103 }
104
105 // TEST: sub-string copy
106 {
107 SBuf s1=SBuf(fox,4), s2(fox);
108 SBuf s3=s2.substr(4,s2.length()); //n is out-of-bounds
109 CPPUNIT_ASSERT_EQUAL(s1,s3);
110 SBuf s4=SBuf(fox,0,4);
111 s3=s2.substr(0,4);
112 CPPUNIT_ASSERT_EQUAL(s4,s3);
113 }
114
115 // TEST: go via SquidString adapters.
116 {
117 String str(fox);
118 SBuf s1(str);
119 CPPUNIT_ASSERT_EQUAL(s1,literal);
120 }
496a9e97
FC
121
122 // TEST: go via std::string adapter.
123 {
124 std::string str(fox);
125 SBuf s1(str);
126 CPPUNIT_ASSERT_EQUAL(s1,literal);
127 }
128
412da427
FC
129}
130
131void
132testSBuf::testSBufConstructDestructAfterMemInit()
133{
134 Mem::Init();
135 testSBufConstructDestruct();
136
412da427
FC
137}
138
139void
140testSBuf::testEqualityTest()
141{
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
147 s2.assign("foo");
148 CPPUNIT_ASSERT(!(s1 == s2)); //different length and contents
149 CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality
150 s2.clear();
151 CPPUNIT_ASSERT(!(s1 == s2)); //null and not-null
152 CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality
153 s1.clear();
154 CPPUNIT_ASSERT_EQUAL(s1,s2); //null and null
155}
156
157void
158testSBuf::testAppendSBuf()
159{
160 SBuf s1(fox1),s2(fox2);
161 s1.append(s2);
162 CPPUNIT_ASSERT_EQUAL(s1,literal);
163}
164
165void
166testSBuf::testPrintf()
167{
168 SBuf s1,s2;
169 s1.Printf("%s:%d:%03.3f","fox",10,12345.67);
170 s2.assign("fox:10:12345.670");
171 CPPUNIT_ASSERT_EQUAL(s1,s2);
172}
173
174void
175testSBuf::testAppendCString()
176{
177 SBuf s1(fox1);
178 s1.append(fox2);
179 CPPUNIT_ASSERT_EQUAL(s1,literal);
180}
181
182void
183testSBuf::testAppendStdString()
184{
185 SBuf s1(fox1);
186 std::string str(fox2);
187 s1.append(str);
188 CPPUNIT_ASSERT_EQUAL(s1,literal);
189}
190
191void
192testSBuf::testAppendf()
193{
194 SBuf s1,s2;
195 s1.appendf("%s:%d:%03.2f",fox,1234,1234.56);
196 s2.assign("The quick brown fox jumped over the lazy dog:1234:1234.56");
197 CPPUNIT_ASSERT_EQUAL(s1,s2);
198}
199
200void
201testSBuf::testDumpStats()
202{
203 SBuf::GetStats().dump(std::cout);
204 MemBlob::GetStats().dump(std::cout);
205 std::cout << "sizeof(SBuf): " << sizeof(SBuf) << std::endl;
206 std::cout << "sizeof(MemBlob): " << sizeof(MemBlob) << std::endl;
207}
208
209void
210testSBuf::testSubscriptOp()
211{
212 SBuf chg(literal);
213 CPPUNIT_ASSERT_EQUAL(chg[5],'u');
214 chg.setAt(5,'e');
215 CPPUNIT_ASSERT_EQUAL(literal[5],'u');
216 CPPUNIT_ASSERT_EQUAL(chg[5],'e');
412da427
FC
217}
218
219// note: can't use cppunit's CPPUNIT_TEST_EXCEPTION because TextException asserts, and
220// so the test can't be properly completed.
221void
222testSBuf::testSubscriptOpFail()
223{
224 char c;
496a9e97 225 c=literal.at(literal.length()); //out of bounds by 1
412da427
FC
226 //notreached
227 std::cout << c << std::endl;
228}
229
230static int sign(int v)
231{
232 if (v < 0)
233 return -1;
234 if (v>0)
235 return 1;
236 return 0;
237}
238
239void
240testSBuf::testComparisons()
241{
242 //same length
243 SBuf s1("foo"),s2("foe");
244 CPPUNIT_ASSERT(s1.compare(s2)>0);
245 CPPUNIT_ASSERT(s1.compare(s2,caseInsensitive,2)==0);
246 CPPUNIT_ASSERT(s1 > s2);
247 CPPUNIT_ASSERT(s2 < s1);
248 CPPUNIT_ASSERT_EQUAL(sign(s1.compare(s2)),sign(strcmp(s1.c_str(),s2.c_str())));
249 //different lengths
250 s1.assign("foo");
251 s2.assign("foof");
252 CPPUNIT_ASSERT(s1.compare(s2)<0);
253 CPPUNIT_ASSERT_EQUAL(sign(s1.compare(s2)),sign(strcmp(s1.c_str(),s2.c_str())));
254 CPPUNIT_ASSERT(s1 < s2);
255}
256
257void
258testSBuf::testConsume()
259{
260 SBuf s1(literal),s2,s3;
261 s2=s1.consume(4);
262 s3.assign("The ");
263 CPPUNIT_ASSERT_EQUAL(s2,s3);
264 s3.assign("quick brown fox jumped over the lazy dog");
265 CPPUNIT_ASSERT_EQUAL(s1,s3);
266 s1.consume(40);
267 CPPUNIT_ASSERT_EQUAL(s1,SBuf());
268}
269
270void
271testSBuf::testRawContent()
272{
273 SBuf s1(literal);
274 SBuf s2(s1);
275 s2.append("foo");
276 const char *foo;
277 foo = s1.rawContent();
278 CPPUNIT_ASSERT(strncmp(fox,foo,s1.length())==0);
279 foo = s1.c_str();
280 CPPUNIT_ASSERT(!strcmp(fox,foo));
281}
282
283void
284testSBuf::testRawSpace()
285{
286 SBuf s1(literal);
287 SBuf s2(fox1);
496a9e97 288 SBuf::size_type sz=s2.length();
412da427 289 char *rb=s2.rawSpace(strlen(fox2)+1);
496a9e97
FC
290 strcpy(rb,fox2);
291 s2.forceSize(sz+strlen(fox2));
412da427
FC
292 CPPUNIT_ASSERT_EQUAL(s1,s2);
293}
294
295void
296testSBuf::testChop()
297{
298 SBuf s1(literal),s2;
299 s1.chop(4,5);
300 s2.assign("quick");
301 CPPUNIT_ASSERT_EQUAL(s1,s2);
302 s1=literal;
303 s2.clear();
304 s1.chop(5,0);
305 CPPUNIT_ASSERT_EQUAL(s1,s2);
496a9e97
FC
306 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
307 SBuf a(alphabet);
308 std::string s(alphabet); // TODO
309 { //regular chopping
310 SBuf b(a);
311 b.chop(3,3);
312 SBuf ref("def");
313 CPPUNIT_ASSERT_EQUAL(ref,b);
314 }
315 { // chop at end
316 SBuf b(a);
317 b.chop(b.length()-3);
318 SBuf ref("xyz");
319 CPPUNIT_ASSERT_EQUAL(ref,b);
320 }
321 { // chop at beginning
322 SBuf b(a);
323 b.chop(0,3);
324 SBuf ref("abc");
325 CPPUNIT_ASSERT_EQUAL(ref,b);
326 }
327 { // chop to zero length
328 SBuf b(a);
329 b.chop(5,0);
330 SBuf ref("");
331 CPPUNIT_ASSERT_EQUAL(ref,b);
332 }
333 { // chop beyond end (at npos)
334 SBuf b(a);
335 b.chop(SBuf::npos,4);
336 SBuf ref("");
337 CPPUNIT_ASSERT_EQUAL(ref,b);
338 }
339 { // chop beyond end
340 SBuf b(a);
341 b.chop(b.length()+2,4);
342 SBuf ref("");
343 CPPUNIT_ASSERT_EQUAL(ref,b);
344 }
345 { // null-chop
346 SBuf b(a);
347 b.chop(0,b.length());
348 SBuf ref(a);
349 CPPUNIT_ASSERT_EQUAL(ref,b);
350 }
351 { // overflow chopped area
352 SBuf b(a);
353 b.chop(b.length()-3,b.length());
354 SBuf ref("xyz");
355 CPPUNIT_ASSERT_EQUAL(ref,b);
356 }
412da427
FC
357}
358
359void
360testSBuf::testChomp()
361{
362 SBuf s1("complete string");
363 SBuf s2(s1);
364 s2.trim(SBuf(" ,"));
365 CPPUNIT_ASSERT_EQUAL(s1,s2);
366 s2.assign(" complete string ,");
367 s2.trim(SBuf(" ,"));
368 CPPUNIT_ASSERT_EQUAL(s1,s2);
369 s1.assign(", complete string ,");
370 s2=s1;
371 s2.trim(SBuf(" "));
372 CPPUNIT_ASSERT_EQUAL(s1,s2);
373}
374
496a9e97
FC
375// inspired to SBufFindTest; to be expanded.
376class SBufSubstrAutoTest
377{
378 SBuf fullString, sb;
379 std::string fullReference, str;
62842d40
FC
380public:
381 void performEqualityTest() {
496a9e97
FC
382 SBuf ref(str);
383 CPPUNIT_ASSERT_EQUAL(ref,sb);
384 }
62842d40 385 SBufSubstrAutoTest() : fullString(fox), fullReference(fox) {
496a9e97
FC
386 for (int offset=fullString.length()-1; offset >= 0; --offset ) {
387 for (int length=fullString.length()-1-offset; length >= 0; --length) {
388 sb=fullString.substr(offset,length);
389 str=fullReference.substr(offset,length);
390 performEqualityTest();
391 }
392 }
393 }
394};
395
412da427
FC
396void
397testSBuf::testSubstr()
398{
399 SBuf s1(literal),s2,s3;
400 s2=s1.substr(4,5);
401 s3.assign("quick");
402 CPPUNIT_ASSERT_EQUAL(s2,s3);
403 s1.chop(4,5);
404 CPPUNIT_ASSERT_EQUAL(s1,s2);
496a9e97 405 SBufSubstrAutoTest sat; // work done in the constructor
412da427
FC
406}
407
408void
409testSBuf::testFindChar()
410{
411 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
412 SBuf s1(alphabet);
413 SBuf::size_type idx;
414 SBuf::size_type nposResult=SBuf::npos;
415
416 // FORWARD SEARCH
417 // needle in haystack
418 idx=s1.find('d');
419 CPPUNIT_ASSERT(idx == 3);
420 CPPUNIT_ASSERT(s1[idx]=='d');
421
422 // needle not present in haystack
423 idx=s1.find(' '); //fails
424 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
425
426 // search in portion
427 idx=s1.find('e',3);
428 CPPUNIT_ASSERT_EQUAL(4,idx);
429
430 // char not in searched portion
431 idx=s1.find('e',5);
432 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
433
434 // invalid start position
435 idx=s1.find('d',SBuf::npos);
436 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
437
438 // invalid start position
439 idx=s1.find('d', -5);
440 CPPUNIT_ASSERT_EQUAL(3, idx);
441
442 // search outside of haystack
443 idx=s1.find('d',s1.length()+1);
444 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
445
446 // REVERSE SEARCH
447 // needle in haystack
448 idx=s1.rfind('d');
449 CPPUNIT_ASSERT_EQUAL(3, idx);
450 CPPUNIT_ASSERT_EQUAL('d', s1[idx]);
451
452 // needle not present in haystack
453 idx=s1.rfind(' '); //fails
454 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
455
456 // search in portion
457 idx=s1.rfind('e',5);
458 CPPUNIT_ASSERT_EQUAL(4,idx);
459
460 // char not in searched portion
461 idx=s1.rfind('e',3);
462 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
463
464 // invalid start position
465 idx=s1.rfind('d', -5);
466 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
467
468 // overlong haystack specification
469 idx=s1.rfind('d',s1.length()+1);
470 CPPUNIT_ASSERT_EQUAL(3,idx);
471}
472
473void
474testSBuf::testFindSBuf()
475{
476 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
477 SBuf haystack(alphabet);
478 SBuf::size_type idx;
479 SBuf::size_type nposResult=SBuf::npos;
480
481 // FORWARD search
482 // needle in haystack
483 idx = haystack.find(SBuf("def"));
484 CPPUNIT_ASSERT_EQUAL(3,idx);
485
486 idx = haystack.find(SBuf("xyz"));
487 CPPUNIT_ASSERT_EQUAL(23,idx);
488
489 // needle not in haystack, no initial char match
490 idx = haystack.find(SBuf(" eq"));
491 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
492
493 // needle not in haystack, initial sequence match
494 idx = haystack.find(SBuf("deg"));
495 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
496
497 // needle past end of haystack
498 idx = haystack.find(SBuf("xyz1"));
499 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
500
501 // search in portion: needle not in searched part
502 idx = haystack.find(SBuf("def"),7);
503 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
504
505 // search in portion: overhang
506 idx = haystack.find(SBuf("def"),4);
507 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
508
509 // invalid start position
510 idx = haystack.find(SBuf("def"),SBuf::npos);
511 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
512
513 // invalid start position: negative
514 idx = haystack.find(SBuf("def"),-5);
515 CPPUNIT_ASSERT_EQUAL(3, idx);
516
517 // needle bigger than haystack
518 idx = SBuf("def").find(haystack);
519 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
520
521 // search in a double-matching haystack
522 {
523 SBuf h2=haystack;
524 h2.append(haystack);
525
526 idx = h2.find(SBuf("def"));
527 CPPUNIT_ASSERT_EQUAL(3,idx);
528
529 idx = h2.find(SBuf("xyzab"));
530 CPPUNIT_ASSERT_EQUAL(23,idx);
531 }
532
412da427
FC
533 // REVERSE search
534 // needle in haystack
535 idx = haystack.rfind(SBuf("def"));
536 CPPUNIT_ASSERT_EQUAL(3,idx);
537
538 idx = haystack.rfind(SBuf("xyz"));
539 CPPUNIT_ASSERT_EQUAL(23,idx);
540
541 // needle not in haystack, no initial char match
542 idx = haystack.rfind(SBuf(" eq"));
543 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
544
545 // needle not in haystack, initial sequence match
546 idx = haystack.rfind(SBuf("deg"));
547 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
548
549 // needle past end of haystack
550 idx = haystack.rfind(SBuf("xyz1"));
551 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
552
553 // search in portion: needle in searched part
554 idx = haystack.rfind(SBuf("def"),7);
555 CPPUNIT_ASSERT_EQUAL(3, idx);
556
557 // search in portion: needle not in searched part
558 idx = haystack.rfind(SBuf("mno"),3);
559 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
560
561 // search in portion: overhang
562 idx = haystack.rfind(SBuf("def"),4);
563 CPPUNIT_ASSERT_EQUAL(3, idx);
564
565 // npos start position
566 idx = haystack.rfind(SBuf("def"),SBuf::npos);
567 CPPUNIT_ASSERT_EQUAL(3, idx);
568
569 // invalid start position: negative
570 idx = haystack.rfind(SBuf("def"),-5);
571 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
572
573 // needle bigger than haystack
574 idx = SBuf("def").rfind(haystack);
575 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
576
577 // search in a double-matching haystack
578 {
579 SBuf h2=haystack;
580 h2.append(haystack);
581
582 idx = h2.rfind(SBuf("def"));
583 CPPUNIT_ASSERT_EQUAL(29,idx);
584
585 idx = h2.find(SBuf("xyzab"));
586 CPPUNIT_ASSERT_EQUAL(23,idx);
587 }
588}
589
590void
591testSBuf::testRFindChar()
592{
593 SBuf s1(literal);
594 SBuf::size_type idx;
595 idx=s1.rfind(' ');
596 CPPUNIT_ASSERT_EQUAL(40,idx);
597 CPPUNIT_ASSERT_EQUAL(' ',s1[idx]);
598}
599
600void
601testSBuf::testRFindSBuf()
602{
603 SBuf haystack(literal),afox("fox");
604 SBuf goobar("goobar");
605 SBuf::size_type idx;
606
607 // corner case: search for a zero-length SBuf
608 idx=haystack.rfind(SBuf(""));
609 CPPUNIT_ASSERT_EQUAL(haystack.length(),idx);
610
611 // corner case: search for a needle longer than the haystack
612 idx=afox.rfind(SBuf(" "));
613 CPPUNIT_ASSERT(idx==SBuf::npos);
614
615 idx=haystack.rfind(SBuf("fox"));
616 CPPUNIT_ASSERT_EQUAL(16,idx);
617
618 // needle not found, no match for first char
619 idx=goobar.rfind(SBuf("foo"));
620 CPPUNIT_ASSERT(idx==SBuf::npos);
621
622 // needle not found, match for first char but no match for SBuf
623 idx=haystack.rfind(SBuf("foe"));
624 CPPUNIT_ASSERT(idx==SBuf::npos);
625
626 SBuf g("g"); //match at the last char
627 idx=haystack.rfind(g);
628 CPPUNIT_ASSERT_EQUAL(43,idx);
629 CPPUNIT_ASSERT_EQUAL('g',haystack[idx]);
630
631 idx=haystack.rfind(SBuf("The"));
632 CPPUNIT_ASSERT_EQUAL(0,idx);
633
634 haystack.append("The");
635 idx=haystack.rfind(SBuf("The"));
636 CPPUNIT_ASSERT_EQUAL(44,idx);
637
638 //partial match
639 haystack="The quick brown fox";
640 SBuf needle("foxy lady");
641 idx=haystack.rfind(needle);
642 CPPUNIT_ASSERT(idx==SBuf::npos);
643}
644
645void
646testSBuf::testSBufLength()
647{
648 SBuf s(fox);
649 CPPUNIT_ASSERT((size_t)s.length()==strlen(fox));
650}
651
652void
653testSBuf::testScanf()
654{
655 SBuf s1;
656 char s[128];
657 int i;
658 float f;
659 int rv;
660 s1.assign("string , 123 , 123.50");
661 rv=s1.scanf("%s , %d , %f",s,&i,&f);
662 CPPUNIT_ASSERT(3 == rv);
663 CPPUNIT_ASSERT(0 == strcmp(s,"string"));
664 CPPUNIT_ASSERT(i == 123);
665 CPPUNIT_ASSERT(f == 123.5);
666}
667
668void testSBuf::testCopy()
669{
670 char buf[40]; //shorter than literal()
671 SBuf s(fox1),s2;
672 CPPUNIT_ASSERT(s.copy(buf,40)==s.length());
673 CPPUNIT_ASSERT(strncmp(s.rawContent(),buf,s.length())==0);
674 s=literal;
675 CPPUNIT_ASSERT(s.copy(buf,40)==40);
676 s2.assign(buf,0,40);
677 s.chop(0,40);
678 CPPUNIT_ASSERT(s==s2);
679}
680
412da427
FC
681void testSBuf::testStringOps()
682{
683 SBuf sng(literal),
684 ref("the quick brown fox jumped over the lazy dog");
685 sng=sng.toLower();
686 CPPUNIT_ASSERT_EQUAL(ref,sng);
687 sng=literal;
688 CPPUNIT_ASSERT(0==sng.compare(ref,caseInsensitive));
689}
690
691void testSBuf::testGrow()
692{
693 SBuf t;
694 t.assign("foo");
695 const char *ref=t.rawContent();
696 t.reserveCapacity(10240);
697 const char *match=t.rawContent();
698 CPPUNIT_ASSERT(match!=ref);
699 ref=match;
700 t.append(literal).append(literal).append(literal).append(literal).append(literal);
701 t.append(t).append(t).append(t).append(t).append(t);
702 CPPUNIT_ASSERT(match==ref);
703}
704
705void testSBuf::testStartsWith()
706{
707 static SBuf casebuf("THE QUICK");
708 CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1)));
709 CPPUNIT_ASSERT(!SBuf("The quick brown").startsWith(SBuf(fox1))); //too short
710 CPPUNIT_ASSERT(!literal.startsWith(SBuf(fox2))); //wrong contents
711
712 CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive));
713 casebuf=SBuf(fox1).toUpper();
714 CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive));
715 CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1),caseInsensitive));
716 casebuf = "tha quick";
717 CPPUNIT_ASSERT(!literal.startsWith(casebuf,caseInsensitive));
718}
719
412da427
FC
720void testSBuf::testSBufStream()
721{
722 SBuf b("const.string, int 10 and a float 10.5");
723 SBufStream ss;
724 ss << "const.string, int " << 10 << " and a float " << 10.5;
725 SBuf o=ss.buf();
726 CPPUNIT_ASSERT_EQUAL(b,o);
727 ss.clearBuf();
728 o=ss.buf();
729 CPPUNIT_ASSERT_EQUAL(SBuf(),o);
730 SBuf f1(fox1);
731 SBufStream ss2(f1);
732 ss2 << fox2;
733 CPPUNIT_ASSERT_EQUAL(ss2.buf(),literal);
734 CPPUNIT_ASSERT_EQUAL(f1,SBuf(fox1));
735}
736
737void testSBuf::testFindFirstOf()
738{
739 SBuf haystack(literal);
740 SBuf::size_type idx;
741
742 // not found
743 idx=haystack.find_first_of(SBuf("ADHRWYP"));
744 CPPUNIT_ASSERT(idx==SBuf::npos);
745
746 // found at beginning
747 idx=haystack.find_first_of(SBuf("THANDF"));
748 CPPUNIT_ASSERT_EQUAL(0,idx);
749
750 //found at end of haystack
751 idx=haystack.find_first_of(SBuf("QWERYVg"));
752 CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
753
754 //found in the middle of haystack
755 idx=haystack.find_first_of(SBuf("QWERqYV"));
756 CPPUNIT_ASSERT_EQUAL(4,idx);
757}
758
759void testSBuf::testAutoFind()
760{
761 SBufFindTest test;
762 test.run();
763}