From: Amos Jeffries Date: Sun, 2 Jun 2013 15:43:09 +0000 (-0600) Subject: Merge from trunk X-Git-Tag: SQUID_3_5_0_1~612^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b64e98d2e6184a4b081803cf7f10d56ebab9432d;p=thirdparty%2Fsquid.git Merge from trunk --- b64e98d2e6184a4b081803cf7f10d56ebab9432d diff --cc src/Makefile.am index 2a5a5a95d6,8d1eac4011..61efca4117 --- a/src/Makefile.am +++ b/src/Makefile.am @@@ -1093,9 -1089,9 +1094,10 @@@ check_PROGRAMS+= tests/testStore \ tests/testString \ tests/testURL \ + tests/testSBuf \ tests/testConfigParser \ tests/testStatHist \ + tests/testVector \ $(STORE_TESTS) ## NP: required to run the above list. check_PROGRAMS only builds the binaries... diff --cc src/tests/testSBuf.cc index 09635580ef,0000000000..a70534c68a mode 100644,000000..100644 --- a/src/tests/testSBuf.cc +++ b/src/tests/testSBuf.cc @@@ -1,763 -1,0 +1,763 @@@ +#include "squid.h" +#include "Mem.h" +#include "SBuf.h" +#include "SBufStream.h" +#include "SquidString.h" +#include "testSBuf.h" +#include "SBufFindTest.h" + +#include +#include + +CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf ); + +/* let this test link sanely */ +#include "event.h" +#include "MemObject.h" +void +eventAdd(const char *name, EVH * func, void *arg, double when, int, bool cbdata) +{} +int64_t +MemObject::endOffset() const +{ return 0; } +/* end of stubs */ + +// test string +static char fox[]="The quick brown fox jumped over the lazy dog"; +static char fox1[]="The quick brown fox "; +static char fox2[]="jumped over the lazy dog"; + +// TEST: globals variables (default/empty and with contents) are +// created outside and before any unit tests and memory subsystem +// initialization. Check for correct constructor operation. +SBuf empty_sbuf; +SBuf literal("The quick brown fox jumped over the lazy dog"); + +void +testSBuf::testSBufConstructDestruct() +{ + /* NOTE: Do not initialize memory here because we need + * to test correct operation before and after Mem::Init + */ + + // XXX: partial demo below of how to do constructor unit-test. use scope to ensure each test + // is working on local-scope variables constructed fresh for the test, and destructed when + // scope exists. use nested scopes to test destructor affects on copied data (MemBlob etc) + + // TEST: default constructor (implicit destructor non-crash test) + // test accessors on empty SBuf. + { + SBuf s1; + CPPUNIT_ASSERT_EQUAL(s1.length(),0); + CPPUNIT_ASSERT_EQUAL(s1,SBuf("")); + CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf); + CPPUNIT_ASSERT(0==strcmp("",s1.c_str())); + } + + // TEST: copy-construct NULL string (implicit destructor non-crash test) + { + SBuf s1(NULL); + CPPUNIT_ASSERT_EQUAL(s1.length(),0); + CPPUNIT_ASSERT_EQUAL(s1,SBuf("")); + CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf); + CPPUNIT_ASSERT(0==strcmp("",s1.c_str())); + } + + // TEST: copy-construct empty string (implicit destructor non-crash test) + { + SBuf s1(""); + CPPUNIT_ASSERT_EQUAL(s1.length(),0); + CPPUNIT_ASSERT_EQUAL(s1,SBuf("")); + CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf); + CPPUNIT_ASSERT(0==strcmp("",s1.c_str())); + } + + // TEST: copy-construct from a char* + { + SBuf s1(fox); - CPPUNIT_ASSERT_EQUAL(s1.length(),strlen(fox)); ++ CPPUNIT_ASSERT_EQUAL(static_cast(s1.length()),strlen(fox)); + CPPUNIT_ASSERT(0==strcmp(fox,s1.c_str())); + } + + // TEST: copy-construct from a SBuf + { + SBuf s1(empty_sbuf); + CPPUNIT_ASSERT_EQUAL(s1.length(),0); + CPPUNIT_ASSERT_EQUAL(s1,SBuf("")); + CPPUNIT_ASSERT_EQUAL(s1,empty_sbuf); + CPPUNIT_ASSERT(0==strcmp("",s1.c_str())); + + SBuf s5(literal); + CPPUNIT_ASSERT_EQUAL(s5,literal); + SBuf s6(fox); + CPPUNIT_ASSERT_EQUAL(s6,literal); + // XXX: other state checks. expected result of calling any state accessor on s4 ? + } + + // TEST: check that COW doesn't happen upon copy-construction + { + SBuf s1(empty_sbuf), s2(s1); + CPPUNIT_ASSERT_EQUAL(s1.rawContent(), s2.rawContent()); + SBuf s3(literal), s4(literal); + CPPUNIT_ASSERT_EQUAL(s3.rawContent(), s4.rawContent()); + } + + // TEST: sub-string copy + { + SBuf s1=SBuf(fox,4), s2(fox); + SBuf s3=s2.substr(4,s2.length()); //n is out-of-bounds + CPPUNIT_ASSERT_EQUAL(s1,s3); + SBuf s4=SBuf(fox,0,4); + s3=s2.substr(0,4); + CPPUNIT_ASSERT_EQUAL(s4,s3); + } + + // TEST: go via SquidString adapters. + { + String str(fox); + SBuf s1(str); + CPPUNIT_ASSERT_EQUAL(s1,literal); + } + + // TEST: go via std::string adapter. + { + std::string str(fox); + SBuf s1(str); + CPPUNIT_ASSERT_EQUAL(s1,literal); + } + +} + +void +testSBuf::testSBufConstructDestructAfterMemInit() +{ + Mem::Init(); + testSBufConstructDestruct(); + +} + +void +testSBuf::testEqualityTest() +{ + SBuf s1(fox),s2(fox); + CPPUNIT_ASSERT_EQUAL(s1,s1); //self-equality + CPPUNIT_ASSERT_EQUAL(s1,s2); //same contents + s2.assign("The quick brown fox jumped over the lazy doe"); + CPPUNIT_ASSERT(!(s1 == s2)); //same length, different contents + s2.assign("foo"); + CPPUNIT_ASSERT(!(s1 == s2)); //different length and contents + CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality + s2.clear(); + CPPUNIT_ASSERT(!(s1 == s2)); //null and not-null + CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality + s1.clear(); + CPPUNIT_ASSERT_EQUAL(s1,s2); //null and null +} + +void +testSBuf::testAppendSBuf() +{ + SBuf s1(fox1),s2(fox2); + s1.append(s2); + CPPUNIT_ASSERT_EQUAL(s1,literal); +} + +void +testSBuf::testPrintf() +{ + SBuf s1,s2; + s1.Printf("%s:%d:%03.3f","fox",10,12345.67); + s2.assign("fox:10:12345.670"); + CPPUNIT_ASSERT_EQUAL(s1,s2); +} + +void +testSBuf::testAppendCString() +{ + SBuf s1(fox1); + s1.append(fox2); + CPPUNIT_ASSERT_EQUAL(s1,literal); +} + +void +testSBuf::testAppendStdString() +{ + SBuf s1(fox1); + std::string str(fox2); + s1.append(str); + CPPUNIT_ASSERT_EQUAL(s1,literal); +} + +void +testSBuf::testAppendf() +{ + SBuf s1,s2; + s1.appendf("%s:%d:%03.2f",fox,1234,1234.56); + s2.assign("The quick brown fox jumped over the lazy dog:1234:1234.56"); + CPPUNIT_ASSERT_EQUAL(s1,s2); +} + +void +testSBuf::testDumpStats() +{ + SBuf::GetStats().dump(std::cout); + MemBlob::GetStats().dump(std::cout); + std::cout << "sizeof(SBuf): " << sizeof(SBuf) << std::endl; + std::cout << "sizeof(MemBlob): " << sizeof(MemBlob) << std::endl; +} + +void +testSBuf::testSubscriptOp() +{ + SBuf chg(literal); + CPPUNIT_ASSERT_EQUAL(chg[5],'u'); + chg.setAt(5,'e'); + CPPUNIT_ASSERT_EQUAL(literal[5],'u'); + CPPUNIT_ASSERT_EQUAL(chg[5],'e'); +} + +// note: can't use cppunit's CPPUNIT_TEST_EXCEPTION because TextException asserts, and +// so the test can't be properly completed. +void +testSBuf::testSubscriptOpFail() +{ + char c; + c=literal.at(literal.length()); //out of bounds by 1 + //notreached + std::cout << c << std::endl; +} + +static int sign(int v) +{ + if (v < 0) + return -1; + if (v>0) + return 1; + return 0; +} + +void +testSBuf::testComparisons() +{ + //same length + SBuf s1("foo"),s2("foe"); + CPPUNIT_ASSERT(s1.compare(s2)>0); + CPPUNIT_ASSERT(s1.compare(s2,caseInsensitive,2)==0); + CPPUNIT_ASSERT(s1 > s2); + CPPUNIT_ASSERT(s2 < s1); + CPPUNIT_ASSERT_EQUAL(sign(s1.compare(s2)),sign(strcmp(s1.c_str(),s2.c_str()))); + //different lengths + s1.assign("foo"); + s2.assign("foof"); + CPPUNIT_ASSERT(s1.compare(s2)<0); + CPPUNIT_ASSERT_EQUAL(sign(s1.compare(s2)),sign(strcmp(s1.c_str(),s2.c_str()))); + CPPUNIT_ASSERT(s1 < s2); +} + +void +testSBuf::testConsume() +{ + SBuf s1(literal),s2,s3; + s2=s1.consume(4); + s3.assign("The "); + CPPUNIT_ASSERT_EQUAL(s2,s3); + s3.assign("quick brown fox jumped over the lazy dog"); + CPPUNIT_ASSERT_EQUAL(s1,s3); + s1.consume(40); + CPPUNIT_ASSERT_EQUAL(s1,SBuf()); +} + +void +testSBuf::testRawContent() +{ + SBuf s1(literal); + SBuf s2(s1); + s2.append("foo"); + const char *foo; + foo = s1.rawContent(); + CPPUNIT_ASSERT(strncmp(fox,foo,s1.length())==0); + foo = s1.c_str(); + CPPUNIT_ASSERT(!strcmp(fox,foo)); +} + +void +testSBuf::testRawSpace() +{ + SBuf s1(literal); + SBuf s2(fox1); + SBuf::size_type sz=s2.length(); + char *rb=s2.rawSpace(strlen(fox2)+1); + strcpy(rb,fox2); + s2.forceSize(sz+strlen(fox2)); + CPPUNIT_ASSERT_EQUAL(s1,s2); +} + +void +testSBuf::testChop() +{ + SBuf s1(literal),s2; + s1.chop(4,5); + s2.assign("quick"); + CPPUNIT_ASSERT_EQUAL(s1,s2); + s1=literal; + s2.clear(); + s1.chop(5,0); + CPPUNIT_ASSERT_EQUAL(s1,s2); + const char *alphabet="abcdefghijklmnopqrstuvwxyz"; + SBuf a(alphabet); + std::string s(alphabet); // TODO + { //regular chopping + SBuf b(a); + b.chop(3,3); + SBuf ref("def"); + CPPUNIT_ASSERT_EQUAL(ref,b); + } + { // chop at end + SBuf b(a); + b.chop(b.length()-3); + SBuf ref("xyz"); + CPPUNIT_ASSERT_EQUAL(ref,b); + } + { // chop at beginning + SBuf b(a); + b.chop(0,3); + SBuf ref("abc"); + CPPUNIT_ASSERT_EQUAL(ref,b); + } + { // chop to zero length + SBuf b(a); + b.chop(5,0); + SBuf ref(""); + CPPUNIT_ASSERT_EQUAL(ref,b); + } + { // chop beyond end (at npos) + SBuf b(a); + b.chop(SBuf::npos,4); + SBuf ref(""); + CPPUNIT_ASSERT_EQUAL(ref,b); + } + { // chop beyond end + SBuf b(a); + b.chop(b.length()+2,4); + SBuf ref(""); + CPPUNIT_ASSERT_EQUAL(ref,b); + } + { // null-chop + SBuf b(a); + b.chop(0,b.length()); + SBuf ref(a); + CPPUNIT_ASSERT_EQUAL(ref,b); + } + { // overflow chopped area + SBuf b(a); + b.chop(b.length()-3,b.length()); + SBuf ref("xyz"); + CPPUNIT_ASSERT_EQUAL(ref,b); + } +} + +void +testSBuf::testChomp() +{ + SBuf s1("complete string"); + SBuf s2(s1); + s2.trim(SBuf(" ,")); + CPPUNIT_ASSERT_EQUAL(s1,s2); + s2.assign(" complete string ,"); + s2.trim(SBuf(" ,")); + CPPUNIT_ASSERT_EQUAL(s1,s2); + s1.assign(", complete string ,"); + s2=s1; + s2.trim(SBuf(" ")); + CPPUNIT_ASSERT_EQUAL(s1,s2); +} + +// inspired to SBufFindTest; to be expanded. +class SBufSubstrAutoTest +{ + SBuf fullString, sb; + std::string fullReference, str; +public: + void performEqualityTest() { + SBuf ref(str); + CPPUNIT_ASSERT_EQUAL(ref,sb); + } + SBufSubstrAutoTest() : fullString(fox), fullReference(fox) { + for (int offset=fullString.length()-1; offset >= 0; --offset ) { + for (int length=fullString.length()-1-offset; length >= 0; --length) { + sb=fullString.substr(offset,length); + str=fullReference.substr(offset,length); + performEqualityTest(); + } + } + } +}; + +void +testSBuf::testSubstr() +{ + SBuf s1(literal),s2,s3; + s2=s1.substr(4,5); + s3.assign("quick"); + CPPUNIT_ASSERT_EQUAL(s2,s3); + s1.chop(4,5); + CPPUNIT_ASSERT_EQUAL(s1,s2); + SBufSubstrAutoTest sat; // work done in the constructor +} + +void +testSBuf::testFindChar() +{ + const char *alphabet="abcdefghijklmnopqrstuvwxyz"; + SBuf s1(alphabet); + SBuf::size_type idx; + SBuf::size_type nposResult=SBuf::npos; + + // FORWARD SEARCH + // needle in haystack + idx=s1.find('d'); + CPPUNIT_ASSERT(idx == 3); + CPPUNIT_ASSERT(s1[idx]=='d'); + + // needle not present in haystack + idx=s1.find(' '); //fails + CPPUNIT_ASSERT_EQUAL(nposResult,idx); + + // search in portion + idx=s1.find('e',3); + CPPUNIT_ASSERT_EQUAL(4,idx); + + // char not in searched portion + idx=s1.find('e',5); + CPPUNIT_ASSERT_EQUAL(nposResult,idx); + + // invalid start position + idx=s1.find('d',SBuf::npos); + CPPUNIT_ASSERT_EQUAL(nposResult,idx); + + // invalid start position + idx=s1.find('d', -5); + CPPUNIT_ASSERT_EQUAL(3, idx); + + // search outside of haystack + idx=s1.find('d',s1.length()+1); + CPPUNIT_ASSERT_EQUAL(nposResult,idx); + + // REVERSE SEARCH + // needle in haystack + idx=s1.rfind('d'); + CPPUNIT_ASSERT_EQUAL(3, idx); + CPPUNIT_ASSERT_EQUAL('d', s1[idx]); + + // needle not present in haystack + idx=s1.rfind(' '); //fails + CPPUNIT_ASSERT_EQUAL(nposResult,idx); + + // search in portion + idx=s1.rfind('e',5); + CPPUNIT_ASSERT_EQUAL(4,idx); + + // char not in searched portion + idx=s1.rfind('e',3); + CPPUNIT_ASSERT_EQUAL(nposResult,idx); + + // invalid start position + idx=s1.rfind('d', -5); + CPPUNIT_ASSERT_EQUAL(nposResult,idx); + + // overlong haystack specification + idx=s1.rfind('d',s1.length()+1); + CPPUNIT_ASSERT_EQUAL(3,idx); +} + +void +testSBuf::testFindSBuf() +{ + const char *alphabet="abcdefghijklmnopqrstuvwxyz"; + SBuf haystack(alphabet); + SBuf::size_type idx; + SBuf::size_type nposResult=SBuf::npos; + + // FORWARD search + // needle in haystack + idx = haystack.find(SBuf("def")); + CPPUNIT_ASSERT_EQUAL(3,idx); + + idx = haystack.find(SBuf("xyz")); + CPPUNIT_ASSERT_EQUAL(23,idx); + + // needle not in haystack, no initial char match + idx = haystack.find(SBuf(" eq")); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // needle not in haystack, initial sequence match + idx = haystack.find(SBuf("deg")); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // needle past end of haystack + idx = haystack.find(SBuf("xyz1")); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // search in portion: needle not in searched part + idx = haystack.find(SBuf("def"),7); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // search in portion: overhang + idx = haystack.find(SBuf("def"),4); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // invalid start position + idx = haystack.find(SBuf("def"),SBuf::npos); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // invalid start position: negative + idx = haystack.find(SBuf("def"),-5); + CPPUNIT_ASSERT_EQUAL(3, idx); + + // needle bigger than haystack + idx = SBuf("def").find(haystack); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // search in a double-matching haystack + { + SBuf h2=haystack; + h2.append(haystack); + + idx = h2.find(SBuf("def")); + CPPUNIT_ASSERT_EQUAL(3,idx); + + idx = h2.find(SBuf("xyzab")); + CPPUNIT_ASSERT_EQUAL(23,idx); + } + + // REVERSE search + // needle in haystack + idx = haystack.rfind(SBuf("def")); + CPPUNIT_ASSERT_EQUAL(3,idx); + + idx = haystack.rfind(SBuf("xyz")); + CPPUNIT_ASSERT_EQUAL(23,idx); + + // needle not in haystack, no initial char match + idx = haystack.rfind(SBuf(" eq")); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // needle not in haystack, initial sequence match + idx = haystack.rfind(SBuf("deg")); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // needle past end of haystack + idx = haystack.rfind(SBuf("xyz1")); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // search in portion: needle in searched part + idx = haystack.rfind(SBuf("def"),7); + CPPUNIT_ASSERT_EQUAL(3, idx); + + // search in portion: needle not in searched part + idx = haystack.rfind(SBuf("mno"),3); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // search in portion: overhang + idx = haystack.rfind(SBuf("def"),4); + CPPUNIT_ASSERT_EQUAL(3, idx); + + // npos start position + idx = haystack.rfind(SBuf("def"),SBuf::npos); + CPPUNIT_ASSERT_EQUAL(3, idx); + + // invalid start position: negative + idx = haystack.rfind(SBuf("def"),-5); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // needle bigger than haystack + idx = SBuf("def").rfind(haystack); + CPPUNIT_ASSERT_EQUAL(nposResult, idx); + + // search in a double-matching haystack + { + SBuf h2=haystack; + h2.append(haystack); + + idx = h2.rfind(SBuf("def")); + CPPUNIT_ASSERT_EQUAL(29,idx); + + idx = h2.find(SBuf("xyzab")); + CPPUNIT_ASSERT_EQUAL(23,idx); + } +} + +void +testSBuf::testRFindChar() +{ + SBuf s1(literal); + SBuf::size_type idx; + idx=s1.rfind(' '); + CPPUNIT_ASSERT_EQUAL(40,idx); + CPPUNIT_ASSERT_EQUAL(' ',s1[idx]); +} + +void +testSBuf::testRFindSBuf() +{ + SBuf haystack(literal),afox("fox"); + SBuf goobar("goobar"); + SBuf::size_type idx; + + // corner case: search for a zero-length SBuf + idx=haystack.rfind(SBuf("")); + CPPUNIT_ASSERT_EQUAL(haystack.length(),idx); + + // corner case: search for a needle longer than the haystack + idx=afox.rfind(SBuf(" ")); + CPPUNIT_ASSERT(idx==SBuf::npos); + + idx=haystack.rfind(SBuf("fox")); + CPPUNIT_ASSERT_EQUAL(16,idx); + + // needle not found, no match for first char + idx=goobar.rfind(SBuf("foo")); + CPPUNIT_ASSERT(idx==SBuf::npos); + + // needle not found, match for first char but no match for SBuf + idx=haystack.rfind(SBuf("foe")); + CPPUNIT_ASSERT(idx==SBuf::npos); + + SBuf g("g"); //match at the last char + idx=haystack.rfind(g); + CPPUNIT_ASSERT_EQUAL(43,idx); + CPPUNIT_ASSERT_EQUAL('g',haystack[idx]); + + idx=haystack.rfind(SBuf("The")); + CPPUNIT_ASSERT_EQUAL(0,idx); + + haystack.append("The"); + idx=haystack.rfind(SBuf("The")); + CPPUNIT_ASSERT_EQUAL(44,idx); + + //partial match + haystack="The quick brown fox"; + SBuf needle("foxy lady"); + idx=haystack.rfind(needle); + CPPUNIT_ASSERT(idx==SBuf::npos); +} + +void +testSBuf::testSBufLength() +{ + SBuf s(fox); + CPPUNIT_ASSERT((size_t)s.length()==strlen(fox)); +} + +void +testSBuf::testScanf() +{ + SBuf s1; + char s[128]; + int i; + float f; + int rv; + s1.assign("string , 123 , 123.50"); + rv=s1.scanf("%s , %d , %f",s,&i,&f); + CPPUNIT_ASSERT(3 == rv); + CPPUNIT_ASSERT(0 == strcmp(s,"string")); + CPPUNIT_ASSERT(i == 123); + CPPUNIT_ASSERT(f == 123.5); +} + +void testSBuf::testCopy() +{ + char buf[40]; //shorter than literal() + SBuf s(fox1),s2; + CPPUNIT_ASSERT(s.copy(buf,40)==s.length()); + CPPUNIT_ASSERT(strncmp(s.rawContent(),buf,s.length())==0); + s=literal; + CPPUNIT_ASSERT(s.copy(buf,40)==40); + s2.assign(buf,0,40); + s.chop(0,40); + CPPUNIT_ASSERT(s==s2); +} + +void testSBuf::testStringOps() +{ + SBuf sng(literal), + ref("the quick brown fox jumped over the lazy dog"); + sng=sng.toLower(); + CPPUNIT_ASSERT_EQUAL(ref,sng); + sng=literal; + CPPUNIT_ASSERT(0==sng.compare(ref,caseInsensitive)); +} + +void testSBuf::testGrow() +{ + SBuf t; + t.assign("foo"); + const char *ref=t.rawContent(); + t.reserveCapacity(10240); + const char *match=t.rawContent(); + CPPUNIT_ASSERT(match!=ref); + ref=match; + t.append(literal).append(literal).append(literal).append(literal).append(literal); + t.append(t).append(t).append(t).append(t).append(t); + CPPUNIT_ASSERT(match==ref); +} + +void testSBuf::testStartsWith() +{ + static SBuf casebuf("THE QUICK"); + CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1))); + CPPUNIT_ASSERT(!SBuf("The quick brown").startsWith(SBuf(fox1))); //too short + CPPUNIT_ASSERT(!literal.startsWith(SBuf(fox2))); //wrong contents + + CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive)); + casebuf=SBuf(fox1).toUpper(); + CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive)); + CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1),caseInsensitive)); + casebuf = "tha quick"; + CPPUNIT_ASSERT(!literal.startsWith(casebuf,caseInsensitive)); +} + +void testSBuf::testSBufStream() +{ + SBuf b("const.string, int 10 and a float 10.5"); + SBufStream ss; + ss << "const.string, int " << 10 << " and a float " << 10.5; + SBuf o=ss.buf(); + CPPUNIT_ASSERT_EQUAL(b,o); + ss.clearBuf(); + o=ss.buf(); + CPPUNIT_ASSERT_EQUAL(SBuf(),o); + SBuf f1(fox1); + SBufStream ss2(f1); + ss2 << fox2; + CPPUNIT_ASSERT_EQUAL(ss2.buf(),literal); + CPPUNIT_ASSERT_EQUAL(f1,SBuf(fox1)); +} + +void testSBuf::testFindFirstOf() +{ + SBuf haystack(literal); + SBuf::size_type idx; + + // not found + idx=haystack.find_first_of(SBuf("ADHRWYP")); + CPPUNIT_ASSERT(idx==SBuf::npos); + + // found at beginning + idx=haystack.find_first_of(SBuf("THANDF")); + CPPUNIT_ASSERT_EQUAL(0,idx); + + //found at end of haystack + idx=haystack.find_first_of(SBuf("QWERYVg")); + CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx); + + //found in the middle of haystack + idx=haystack.find_first_of(SBuf("QWERqYV")); + CPPUNIT_ASSERT_EQUAL(4,idx); +} + +void testSBuf::testAutoFind() +{ + SBufFindTest test; + test.run(); +}