]>
Commit | Line | Data |
---|---|---|
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 | ||
12 | CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf ); | |
13 | ||
14 | /* let this test link sanely */ | |
15 | #include "event.h" | |
16 | #include "MemObject.h" | |
17 | void | |
18 | eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata) | |
19 | {} | |
20 | int64_t | |
21 | MemObject::endOffset() const | |
22 | { return 0; } | |
23 | /* end of stubs */ | |
24 | ||
25 | // test string | |
26 | static char fox[]="The quick brown fox jumped over the lazy dog"; | |
27 | static char fox1[]="The quick brown fox "; | |
28 | static 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. | |
33 | SBuf empty_sbuf; | |
34 | SBuf literal("The quick brown fox jumped over the lazy dog"); | |
35 | ||
36 | void | |
37 | testSBuf::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 | ||
75 | // TEST: copy-construct from a SBuf | |
76 | { | |
77 | SBuf s1(empty_sbuf); | |
78 | CPPUNIT_ASSERT_EQUAL(s1.length(),0); | |
79 | CPPUNIT_ASSERT_EQUAL(s1,SBuf("")); | |
80 | CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf); | |
81 | CPPUNIT_ASSERT(0==strcmp("",s1.c_str())); | |
82 | ||
83 | SBuf s5(literal); | |
84 | CPPUNIT_ASSERT_EQUAL(s5,literal); | |
85 | SBuf s6(fox); | |
86 | CPPUNIT_ASSERT_EQUAL(s6,literal); | |
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 | { | |
100 | SBuf s1=SBuf(fox,4), s2(fox); | |
101 | SBuf s3=s2.substr(4,s2.length()); //n is out-of-bounds | |
102 | CPPUNIT_ASSERT_EQUAL(s1,s3); | |
103 | SBuf s4=SBuf(fox,0,4); | |
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); | |
112 | CPPUNIT_ASSERT_EQUAL(s1,literal); | |
113 | } | |
114 | } | |
115 | ||
116 | void | |
117 | testSBuf::testSBufConstructDestructAfterMemInit() | |
118 | { | |
119 | Mem::Init(); | |
120 | testSBufConstructDestruct(); | |
121 | ||
122 | // XXX: or perhapse ... | |
123 | // repeat all of the tests inside testSBufConstructDestructBeforeMemInit() | |
124 | // with additional checks on Mem usage stats after each operation ?? | |
125 | } | |
126 | ||
127 | void | |
128 | testSBuf::testEqualityTest() | |
129 | { | |
130 | SBuf s1(fox),s2(fox); | |
131 | CPPUNIT_ASSERT_EQUAL(s1,s1); //self-equality | |
132 | CPPUNIT_ASSERT_EQUAL(s1,s2); //same contents | |
133 | s2.assign("The quick brown fox jumped over the lazy doe"); | |
134 | CPPUNIT_ASSERT(!(s1 == s2)); //same length, different contents | |
135 | s2.assign("foo"); | |
136 | CPPUNIT_ASSERT(!(s1 == s2)); //different length and contents | |
137 | CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality | |
138 | s2.clear(); | |
139 | CPPUNIT_ASSERT(!(s1 == s2)); //null and not-null | |
140 | CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality | |
141 | s1.clear(); | |
142 | CPPUNIT_ASSERT_EQUAL(s1,s2); //null and null | |
143 | } | |
144 | ||
145 | void | |
146 | testSBuf::testAppendSBuf() | |
147 | { | |
148 | SBuf s1(fox1),s2(fox2); | |
149 | s1.append(s2); | |
150 | CPPUNIT_ASSERT_EQUAL(s1,literal); | |
151 | } | |
152 | ||
153 | void | |
154 | testSBuf::testPrintf() | |
155 | { | |
156 | SBuf s1,s2; | |
157 | s1.Printf("%s:%d:%03.3f","fox",10,12345.67); | |
158 | s2.assign("fox:10:12345.670"); | |
159 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
160 | } | |
161 | ||
162 | void | |
163 | testSBuf::testAppendCString() | |
164 | { | |
165 | SBuf s1(fox1); | |
166 | s1.append(fox2); | |
167 | CPPUNIT_ASSERT_EQUAL(s1,literal); | |
168 | } | |
169 | ||
170 | void | |
171 | testSBuf::testAppendStdString() | |
172 | { | |
173 | SBuf s1(fox1); | |
174 | std::string str(fox2); | |
175 | s1.append(str); | |
176 | CPPUNIT_ASSERT_EQUAL(s1,literal); | |
177 | } | |
178 | ||
179 | void | |
180 | testSBuf::testAppendf() | |
181 | { | |
182 | SBuf s1,s2; | |
183 | s1.appendf("%s:%d:%03.2f",fox,1234,1234.56); | |
184 | s2.assign("The quick brown fox jumped over the lazy dog:1234:1234.56"); | |
185 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
186 | } | |
187 | ||
188 | void | |
189 | testSBuf::testDumpStats() | |
190 | { | |
191 | SBuf::GetStats().dump(std::cout); | |
192 | MemBlob::GetStats().dump(std::cout); | |
193 | std::cout << "sizeof(SBuf): " << sizeof(SBuf) << std::endl; | |
194 | std::cout << "sizeof(MemBlob): " << sizeof(MemBlob) << std::endl; | |
195 | } | |
196 | ||
197 | void | |
198 | testSBuf::testSubscriptOp() | |
199 | { | |
200 | SBuf chg(literal); | |
201 | CPPUNIT_ASSERT_EQUAL(chg[5],'u'); | |
202 | chg.setAt(5,'e'); | |
203 | CPPUNIT_ASSERT_EQUAL(literal[5],'u'); | |
204 | CPPUNIT_ASSERT_EQUAL(chg[5],'e'); | |
205 | // std::cout << chg << std::endl << empty_sbuf << std::endl ; | |
206 | } | |
207 | ||
208 | // note: can't use cppunit's CPPUNIT_TEST_EXCEPTION because TextException asserts, and | |
209 | // so the test can't be properly completed. | |
210 | void | |
211 | testSBuf::testSubscriptOpFail() | |
212 | { | |
213 | char c; | |
214 | c=literal.at(1234); //out of bounds | |
215 | //notreached | |
216 | std::cout << c << std::endl; | |
217 | } | |
218 | ||
219 | static int sign(int v) | |
220 | { | |
221 | if (v < 0) | |
222 | return -1; | |
223 | if (v>0) | |
224 | return 1; | |
225 | return 0; | |
226 | } | |
227 | ||
228 | void | |
229 | testSBuf::testComparisons() | |
230 | { | |
231 | //same length | |
232 | SBuf s1("foo"),s2("foe"); | |
233 | CPPUNIT_ASSERT(s1.compare(s2)>0); | |
234 | CPPUNIT_ASSERT(s1.compare(s2,caseInsensitive,2)==0); | |
235 | CPPUNIT_ASSERT(s1 > s2); | |
236 | CPPUNIT_ASSERT(s2 < s1); | |
237 | CPPUNIT_ASSERT_EQUAL(sign(s1.compare(s2)),sign(strcmp(s1.c_str(),s2.c_str()))); | |
238 | //different lengths | |
239 | s1.assign("foo"); | |
240 | s2.assign("foof"); | |
241 | CPPUNIT_ASSERT(s1.compare(s2)<0); | |
242 | CPPUNIT_ASSERT_EQUAL(sign(s1.compare(s2)),sign(strcmp(s1.c_str(),s2.c_str()))); | |
243 | CPPUNIT_ASSERT(s1 < s2); | |
244 | } | |
245 | ||
246 | void | |
247 | testSBuf::testConsume() | |
248 | { | |
249 | SBuf s1(literal),s2,s3; | |
250 | s2=s1.consume(4); | |
251 | s3.assign("The "); | |
252 | CPPUNIT_ASSERT_EQUAL(s2,s3); | |
253 | s3.assign("quick brown fox jumped over the lazy dog"); | |
254 | CPPUNIT_ASSERT_EQUAL(s1,s3); | |
255 | s1.consume(40); | |
256 | CPPUNIT_ASSERT_EQUAL(s1,SBuf()); | |
257 | } | |
258 | ||
259 | void | |
260 | testSBuf::testRawContent() | |
261 | { | |
262 | SBuf s1(literal); | |
263 | SBuf s2(s1); | |
264 | s2.append("foo"); | |
265 | const char *foo; | |
266 | foo = s1.rawContent(); | |
267 | CPPUNIT_ASSERT(strncmp(fox,foo,s1.length())==0); | |
268 | foo = s1.c_str(); | |
269 | CPPUNIT_ASSERT(!strcmp(fox,foo)); | |
270 | } | |
271 | ||
272 | void | |
273 | testSBuf::testRawSpace() | |
274 | { | |
275 | SBuf s1(literal); | |
276 | SBuf s2(fox1); | |
277 | char *rb=s2.rawSpace(strlen(fox2)+1); | |
278 | strcat(rb,fox2); | |
279 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
280 | } | |
281 | ||
282 | void | |
283 | testSBuf::testChop() | |
284 | { | |
285 | SBuf s1(literal),s2; | |
286 | s1.chop(4,5); | |
287 | s2.assign("quick"); | |
288 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
289 | s1=literal; | |
290 | s2.clear(); | |
291 | s1.chop(5,0); | |
292 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
293 | } | |
294 | ||
295 | void | |
296 | testSBuf::testChomp() | |
297 | { | |
298 | SBuf s1("complete string"); | |
299 | SBuf s2(s1); | |
300 | s2.trim(SBuf(" ,")); | |
301 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
302 | s2.assign(" complete string ,"); | |
303 | s2.trim(SBuf(" ,")); | |
304 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
305 | s1.assign(", complete string ,"); | |
306 | s2=s1; | |
307 | s2.trim(SBuf(" ")); | |
308 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
309 | } | |
310 | ||
311 | void | |
312 | testSBuf::testSubstr() | |
313 | { | |
314 | SBuf s1(literal),s2,s3; | |
315 | s2=s1.substr(4,5); | |
316 | s3.assign("quick"); | |
317 | CPPUNIT_ASSERT_EQUAL(s2,s3); | |
318 | s1.chop(4,5); | |
319 | CPPUNIT_ASSERT_EQUAL(s1,s2); | |
320 | } | |
321 | ||
322 | void | |
323 | testSBuf::testFindChar() | |
324 | { | |
325 | const char *alphabet="abcdefghijklmnopqrstuvwxyz"; | |
326 | SBuf s1(alphabet); | |
327 | SBuf::size_type idx; | |
328 | SBuf::size_type nposResult=SBuf::npos; | |
329 | ||
330 | // FORWARD SEARCH | |
331 | // needle in haystack | |
332 | idx=s1.find('d'); | |
333 | CPPUNIT_ASSERT(idx == 3); | |
334 | CPPUNIT_ASSERT(s1[idx]=='d'); | |
335 | ||
336 | // needle not present in haystack | |
337 | idx=s1.find(' '); //fails | |
338 | CPPUNIT_ASSERT_EQUAL(nposResult,idx); | |
339 | ||
340 | // search in portion | |
341 | idx=s1.find('e',3); | |
342 | CPPUNIT_ASSERT_EQUAL(4,idx); | |
343 | ||
344 | // char not in searched portion | |
345 | idx=s1.find('e',5); | |
346 | CPPUNIT_ASSERT_EQUAL(nposResult,idx); | |
347 | ||
348 | // invalid start position | |
349 | idx=s1.find('d',SBuf::npos); | |
350 | CPPUNIT_ASSERT_EQUAL(nposResult,idx); | |
351 | ||
352 | // invalid start position | |
353 | idx=s1.find('d', -5); | |
354 | CPPUNIT_ASSERT_EQUAL(3, idx); | |
355 | ||
356 | // search outside of haystack | |
357 | idx=s1.find('d',s1.length()+1); | |
358 | CPPUNIT_ASSERT_EQUAL(nposResult,idx); | |
359 | ||
360 | // REVERSE SEARCH | |
361 | // needle in haystack | |
362 | idx=s1.rfind('d'); | |
363 | CPPUNIT_ASSERT_EQUAL(3, idx); | |
364 | CPPUNIT_ASSERT_EQUAL('d', s1[idx]); | |
365 | ||
366 | // needle not present in haystack | |
367 | idx=s1.rfind(' '); //fails | |
368 | CPPUNIT_ASSERT_EQUAL(nposResult,idx); | |
369 | ||
370 | // search in portion | |
371 | idx=s1.rfind('e',5); | |
372 | CPPUNIT_ASSERT_EQUAL(4,idx); | |
373 | ||
374 | // char not in searched portion | |
375 | idx=s1.rfind('e',3); | |
376 | CPPUNIT_ASSERT_EQUAL(nposResult,idx); | |
377 | ||
378 | // invalid start position | |
379 | idx=s1.rfind('d', -5); | |
380 | CPPUNIT_ASSERT_EQUAL(nposResult,idx); | |
381 | ||
382 | // overlong haystack specification | |
383 | idx=s1.rfind('d',s1.length()+1); | |
384 | CPPUNIT_ASSERT_EQUAL(3,idx); | |
385 | } | |
386 | ||
387 | void | |
388 | testSBuf::testFindSBuf() | |
389 | { | |
390 | const char *alphabet="abcdefghijklmnopqrstuvwxyz"; | |
391 | SBuf haystack(alphabet); | |
392 | SBuf::size_type idx; | |
393 | SBuf::size_type nposResult=SBuf::npos; | |
394 | ||
395 | // FORWARD search | |
396 | // needle in haystack | |
397 | idx = haystack.find(SBuf("def")); | |
398 | CPPUNIT_ASSERT_EQUAL(3,idx); | |
399 | ||
400 | idx = haystack.find(SBuf("xyz")); | |
401 | CPPUNIT_ASSERT_EQUAL(23,idx); | |
402 | ||
403 | // needle not in haystack, no initial char match | |
404 | idx = haystack.find(SBuf(" eq")); | |
405 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
406 | ||
407 | // needle not in haystack, initial sequence match | |
408 | idx = haystack.find(SBuf("deg")); | |
409 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
410 | ||
411 | // needle past end of haystack | |
412 | idx = haystack.find(SBuf("xyz1")); | |
413 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
414 | ||
415 | // search in portion: needle not in searched part | |
416 | idx = haystack.find(SBuf("def"),7); | |
417 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
418 | ||
419 | // search in portion: overhang | |
420 | idx = haystack.find(SBuf("def"),4); | |
421 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
422 | ||
423 | // invalid start position | |
424 | idx = haystack.find(SBuf("def"),SBuf::npos); | |
425 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
426 | ||
427 | // invalid start position: negative | |
428 | idx = haystack.find(SBuf("def"),-5); | |
429 | CPPUNIT_ASSERT_EQUAL(3, idx); | |
430 | ||
431 | // needle bigger than haystack | |
432 | idx = SBuf("def").find(haystack); | |
433 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
434 | ||
435 | // search in a double-matching haystack | |
436 | { | |
437 | SBuf h2=haystack; | |
438 | h2.append(haystack); | |
439 | ||
440 | idx = h2.find(SBuf("def")); | |
441 | CPPUNIT_ASSERT_EQUAL(3,idx); | |
442 | ||
443 | idx = h2.find(SBuf("xyzab")); | |
444 | CPPUNIT_ASSERT_EQUAL(23,idx); | |
445 | } | |
446 | ||
447 | ||
448 | // REVERSE search | |
449 | // needle in haystack | |
450 | idx = haystack.rfind(SBuf("def")); | |
451 | CPPUNIT_ASSERT_EQUAL(3,idx); | |
452 | ||
453 | idx = haystack.rfind(SBuf("xyz")); | |
454 | CPPUNIT_ASSERT_EQUAL(23,idx); | |
455 | ||
456 | // needle not in haystack, no initial char match | |
457 | idx = haystack.rfind(SBuf(" eq")); | |
458 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
459 | ||
460 | // needle not in haystack, initial sequence match | |
461 | idx = haystack.rfind(SBuf("deg")); | |
462 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
463 | ||
464 | // needle past end of haystack | |
465 | idx = haystack.rfind(SBuf("xyz1")); | |
466 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
467 | ||
468 | // search in portion: needle in searched part | |
469 | idx = haystack.rfind(SBuf("def"),7); | |
470 | CPPUNIT_ASSERT_EQUAL(3, idx); | |
471 | ||
472 | // search in portion: needle not in searched part | |
473 | idx = haystack.rfind(SBuf("mno"),3); | |
474 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
475 | ||
476 | // search in portion: overhang | |
477 | idx = haystack.rfind(SBuf("def"),4); | |
478 | CPPUNIT_ASSERT_EQUAL(3, idx); | |
479 | ||
480 | // npos start position | |
481 | idx = haystack.rfind(SBuf("def"),SBuf::npos); | |
482 | CPPUNIT_ASSERT_EQUAL(3, idx); | |
483 | ||
484 | // invalid start position: negative | |
485 | idx = haystack.rfind(SBuf("def"),-5); | |
486 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
487 | ||
488 | // needle bigger than haystack | |
489 | idx = SBuf("def").rfind(haystack); | |
490 | CPPUNIT_ASSERT_EQUAL(nposResult, idx); | |
491 | ||
492 | // search in a double-matching haystack | |
493 | { | |
494 | SBuf h2=haystack; | |
495 | h2.append(haystack); | |
496 | ||
497 | idx = h2.rfind(SBuf("def")); | |
498 | CPPUNIT_ASSERT_EQUAL(29,idx); | |
499 | ||
500 | idx = h2.find(SBuf("xyzab")); | |
501 | CPPUNIT_ASSERT_EQUAL(23,idx); | |
502 | } | |
503 | } | |
504 | ||
505 | void | |
506 | testSBuf::testRFindChar() | |
507 | { | |
508 | SBuf s1(literal); | |
509 | SBuf::size_type idx; | |
510 | idx=s1.rfind(' '); | |
511 | CPPUNIT_ASSERT_EQUAL(40,idx); | |
512 | CPPUNIT_ASSERT_EQUAL(' ',s1[idx]); | |
513 | } | |
514 | ||
515 | void | |
516 | testSBuf::testRFindSBuf() | |
517 | { | |
518 | SBuf haystack(literal),afox("fox"); | |
519 | SBuf goobar("goobar"); | |
520 | SBuf::size_type idx; | |
521 | ||
522 | // corner case: search for a zero-length SBuf | |
523 | idx=haystack.rfind(SBuf("")); | |
524 | CPPUNIT_ASSERT_EQUAL(haystack.length(),idx); | |
525 | ||
526 | // corner case: search for a needle longer than the haystack | |
527 | idx=afox.rfind(SBuf(" ")); | |
528 | CPPUNIT_ASSERT(idx==SBuf::npos); | |
529 | ||
530 | idx=haystack.rfind(SBuf("fox")); | |
531 | CPPUNIT_ASSERT_EQUAL(16,idx); | |
532 | ||
533 | // needle not found, no match for first char | |
534 | idx=goobar.rfind(SBuf("foo")); | |
535 | CPPUNIT_ASSERT(idx==SBuf::npos); | |
536 | ||
537 | // needle not found, match for first char but no match for SBuf | |
538 | idx=haystack.rfind(SBuf("foe")); | |
539 | CPPUNIT_ASSERT(idx==SBuf::npos); | |
540 | ||
541 | SBuf g("g"); //match at the last char | |
542 | idx=haystack.rfind(g); | |
543 | CPPUNIT_ASSERT_EQUAL(43,idx); | |
544 | CPPUNIT_ASSERT_EQUAL('g',haystack[idx]); | |
545 | ||
546 | idx=haystack.rfind(SBuf("The")); | |
547 | CPPUNIT_ASSERT_EQUAL(0,idx); | |
548 | ||
549 | haystack.append("The"); | |
550 | idx=haystack.rfind(SBuf("The")); | |
551 | CPPUNIT_ASSERT_EQUAL(44,idx); | |
552 | ||
553 | //partial match | |
554 | haystack="The quick brown fox"; | |
555 | SBuf needle("foxy lady"); | |
556 | idx=haystack.rfind(needle); | |
557 | CPPUNIT_ASSERT(idx==SBuf::npos); | |
558 | } | |
559 | ||
560 | void | |
561 | testSBuf::testSBufLength() | |
562 | { | |
563 | SBuf s(fox); | |
564 | CPPUNIT_ASSERT((size_t)s.length()==strlen(fox)); | |
565 | } | |
566 | ||
567 | void | |
568 | testSBuf::testScanf() | |
569 | { | |
570 | SBuf s1; | |
571 | char s[128]; | |
572 | int i; | |
573 | float f; | |
574 | int rv; | |
575 | s1.assign("string , 123 , 123.50"); | |
576 | rv=s1.scanf("%s , %d , %f",s,&i,&f); | |
577 | CPPUNIT_ASSERT(3 == rv); | |
578 | CPPUNIT_ASSERT(0 == strcmp(s,"string")); | |
579 | CPPUNIT_ASSERT(i == 123); | |
580 | CPPUNIT_ASSERT(f == 123.5); | |
581 | } | |
582 | ||
583 | void testSBuf::testCopy() | |
584 | { | |
585 | char buf[40]; //shorter than literal() | |
586 | SBuf s(fox1),s2; | |
587 | CPPUNIT_ASSERT(s.copy(buf,40)==s.length()); | |
588 | CPPUNIT_ASSERT(strncmp(s.rawContent(),buf,s.length())==0); | |
589 | s=literal; | |
590 | CPPUNIT_ASSERT(s.copy(buf,40)==40); | |
591 | s2.assign(buf,0,40); | |
592 | s.chop(0,40); | |
593 | CPPUNIT_ASSERT(s==s2); | |
594 | } | |
595 | ||
412da427 FC |
596 | void testSBuf::testStringOps() |
597 | { | |
598 | SBuf sng(literal), | |
599 | ref("the quick brown fox jumped over the lazy dog"); | |
600 | sng=sng.toLower(); | |
601 | CPPUNIT_ASSERT_EQUAL(ref,sng); | |
602 | sng=literal; | |
603 | CPPUNIT_ASSERT(0==sng.compare(ref,caseInsensitive)); | |
604 | } | |
605 | ||
606 | void testSBuf::testGrow() | |
607 | { | |
608 | SBuf t; | |
609 | t.assign("foo"); | |
610 | const char *ref=t.rawContent(); | |
611 | t.reserveCapacity(10240); | |
612 | const char *match=t.rawContent(); | |
613 | CPPUNIT_ASSERT(match!=ref); | |
614 | ref=match; | |
615 | t.append(literal).append(literal).append(literal).append(literal).append(literal); | |
616 | t.append(t).append(t).append(t).append(t).append(t); | |
617 | CPPUNIT_ASSERT(match==ref); | |
618 | } | |
619 | ||
620 | void testSBuf::testStartsWith() | |
621 | { | |
622 | static SBuf casebuf("THE QUICK"); | |
623 | CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1))); | |
624 | CPPUNIT_ASSERT(!SBuf("The quick brown").startsWith(SBuf(fox1))); //too short | |
625 | CPPUNIT_ASSERT(!literal.startsWith(SBuf(fox2))); //wrong contents | |
626 | ||
627 | CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive)); | |
628 | casebuf=SBuf(fox1).toUpper(); | |
629 | CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive)); | |
630 | CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1),caseInsensitive)); | |
631 | casebuf = "tha quick"; | |
632 | CPPUNIT_ASSERT(!literal.startsWith(casebuf,caseInsensitive)); | |
633 | } | |
634 | ||
412da427 FC |
635 | void testSBuf::testSBufStream() |
636 | { | |
637 | SBuf b("const.string, int 10 and a float 10.5"); | |
638 | SBufStream ss; | |
639 | ss << "const.string, int " << 10 << " and a float " << 10.5; | |
640 | SBuf o=ss.buf(); | |
641 | CPPUNIT_ASSERT_EQUAL(b,o); | |
642 | ss.clearBuf(); | |
643 | o=ss.buf(); | |
644 | CPPUNIT_ASSERT_EQUAL(SBuf(),o); | |
645 | SBuf f1(fox1); | |
646 | SBufStream ss2(f1); | |
647 | ss2 << fox2; | |
648 | CPPUNIT_ASSERT_EQUAL(ss2.buf(),literal); | |
649 | CPPUNIT_ASSERT_EQUAL(f1,SBuf(fox1)); | |
650 | } | |
651 | ||
652 | void testSBuf::testFindFirstOf() | |
653 | { | |
654 | SBuf haystack(literal); | |
655 | SBuf::size_type idx; | |
656 | ||
657 | // not found | |
658 | idx=haystack.find_first_of(SBuf("ADHRWYP")); | |
659 | CPPUNIT_ASSERT(idx==SBuf::npos); | |
660 | ||
661 | // found at beginning | |
662 | idx=haystack.find_first_of(SBuf("THANDF")); | |
663 | CPPUNIT_ASSERT_EQUAL(0,idx); | |
664 | ||
665 | //found at end of haystack | |
666 | idx=haystack.find_first_of(SBuf("QWERYVg")); | |
667 | CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx); | |
668 | ||
669 | //found in the middle of haystack | |
670 | idx=haystack.find_first_of(SBuf("QWERqYV")); | |
671 | CPPUNIT_ASSERT_EQUAL(4,idx); | |
672 | } | |
673 | ||
674 | void testSBuf::testAutoFind() | |
675 | { | |
676 | SBufFindTest test; | |
677 | test.run(); | |
678 | } |