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