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