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