+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
#include "squid.h"
-#include "Mem.h"
-#include "SBuf.h"
-#include "SBufStream.h"
-#include "SquidString.h"
-#include "testSBuf.h"
-#include "SBufFindTest.h"
+#include "base/CharacterSet.h"
+#include "sbuf/SBuf.h"
+#include "sbuf/Algorithms.h"
+#include "sbuf/SBufStream.h"
+#include "tests/SBufFindTest.h"
+#include "tests/testSBuf.h"
+#include "unitTestMain.h"
#include <iostream>
#include <stdexcept>
+#include <unordered_map>
CPPUNIT_TEST_SUITE_REGISTRATION( testSBuf );
// test accessors on empty SBuf.
{
SBuf s1;
- CPPUNIT_ASSERT_EQUAL(0,s1.length());
+ CPPUNIT_ASSERT_EQUAL(0U,s1.length());
CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
// TEST: copy-construct NULL string (implicit destructor non-crash test)
{
SBuf s1(NULL);
- CPPUNIT_ASSERT_EQUAL(0,s1.length());
+ CPPUNIT_ASSERT_EQUAL(0U,s1.length());
CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
// TEST: copy-construct empty string (implicit destructor non-crash test)
{
SBuf s1("");
- CPPUNIT_ASSERT_EQUAL(0,s1.length());
+ CPPUNIT_ASSERT_EQUAL(0U,s1.length());
CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
// TEST: copy-construct from a SBuf
{
SBuf s1(empty_sbuf);
- CPPUNIT_ASSERT_EQUAL(0,s1.length());
+ CPPUNIT_ASSERT_EQUAL(0U,s1.length());
CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
CPPUNIT_ASSERT_EQUAL(s4,s3);
}
- // TEST: go via SquidString adapters.
- {
- String str(fox);
- SBuf s1(str);
- CPPUNIT_ASSERT_EQUAL(literal,s1);
- }
-
// TEST: go via std::string adapter.
{
std::string str(fox);
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);
+ CPPUNIT_ASSERT_EQUAL(s2,s1);
}
void
return 0;
}
+static void
+testComparisonStdFull(const char *left, const char *right)
+{
+ if (sign(strcmp(left, right)) != sign(SBuf(left).cmp(SBuf(right))))
+ std::cerr << std::endl << " cmp(SBuf) npos " << left << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strcmp(left, right)), sign(SBuf(left).cmp(SBuf(right))));
+
+ if (sign(strcmp(left, right)) != sign(SBuf(left).cmp(right)))
+ std::cerr << std::endl << " cmp(char*) npos " << left << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strcmp(left, right)), sign(SBuf(left).cmp(right)));
+
+ if (sign(strcasecmp(left, right)) != sign(SBuf(left).caseCmp(SBuf(right))))
+ std::cerr << std::endl << " caseCmp(SBuf) npos " << left << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left, right)), sign(SBuf(left).caseCmp(SBuf(right))));
+
+ if (sign(strcasecmp(left, right)) != sign(SBuf(left).caseCmp(right)))
+ std::cerr << std::endl << " caseCmp(char*) npos " << left << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left, right)), sign(SBuf(left).caseCmp(right)));
+}
+
+static void
+testComparisonStdN(const char *left, const char *right, const size_t n)
+{
+ if (sign(strncmp(left, right, n)) != sign(SBuf(left).cmp(SBuf(right), n)))
+ std::cerr << std::endl << " cmp(SBuf) " << n << ' ' << left << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strncmp(left, right, n)), sign(SBuf(left).cmp(SBuf(right), n)));
+
+ if (sign(strncmp(left, right, n)) != sign(SBuf(left).cmp(right, n)))
+ std::cerr << std::endl << " cmp(char*) " << n << ' ' << SBuf(left) << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strncmp(left, right, n)), sign(SBuf(left).cmp(right, n)));
+
+ if (sign(strncasecmp(left, right, n)) != sign(SBuf(left).caseCmp(SBuf(right), n)))
+ std::cerr << std::endl << " caseCmp(SBuf) " << n << ' ' << left << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left, right, n)), sign(SBuf(left).caseCmp(SBuf(right), n)));
+
+ if (sign(strncasecmp(left, right, n)) != sign(SBuf(left).caseCmp(right, n)))
+ std::cerr << std::endl << " caseCmp(char*) " << n << ' ' << SBuf(left) << " ?= " << right << std::endl;
+ CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left, right, n)), sign(SBuf(left).caseCmp(right, n)));
+}
+
+static void
+testComparisonStdOneWay(const char *left, const char *right)
+{
+ testComparisonStdFull(left, right);
+ const size_t maxN = 2 + min(strlen(left), strlen(right));
+ for (size_t n = 0; n <= maxN; ++n) {
+ testComparisonStdN(left, right, n);
+ }
+}
+
+static void
+testComparisonStd(const char *s1, const char *s2)
+{
+ testComparisonStdOneWay(s1, s2);
+ testComparisonStdOneWay(s2, s1);
+}
+
void
testSBuf::testComparisons()
{
// \0-clenliness test
s1.assign("f\0oo",4);
s2.assign("f\0Oo",4);
- CPPUNIT_ASSERT_EQUAL(1,s1.cmp(s2));
+ CPPUNIT_ASSERT(s1.cmp(s2) > 0);
CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2));
CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2,3));
CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2,2));
CPPUNIT_ASSERT_EQUAL(0,s1.cmp(s2,2));
+
+ testComparisonStd("foo", "fooz");
+ testComparisonStd("foo", "foo");
+ testComparisonStd("foo", "f");
+ testComparisonStd("foo", "bar");
+
+ testComparisonStd("foo", "FOOZ");
+ testComparisonStd("foo", "FOO");
+ testComparisonStd("foo", "F");
+
+ testComparisonStdOneWay("", "");
+
+ // rare case C-string input matching SBuf with N>strlen(s)
+ {
+ char *right = xstrdup("foo34567890123456789012345678");
+ SBuf left("fooZYXWVUTSRQPONMLKJIHGFEDCBA");
+ // is 3 bytes in length. NEVER more.
+ right[3] = '\0';
+ left.setAt(3, '\0');
+
+ // pick another spot to truncate at if something goes horribly wrong.
+ right[14] = '\0';
+ left.setAt(14, '\0');
+
+ const SBuf::size_type maxN = 20 + min(left.length(), static_cast<SBuf::size_type>(strlen(right)));
+ for (SBuf::size_type n = 0; n <= maxN; ++n) {
+ if (sign(strncmp(left.rawContent(), right, n)) != sign(left.cmp(right, n)) )
+ std::cerr << std::endl << " cmp(char*) " << n << ' ' << left << " ?= " << right;
+ CPPUNIT_ASSERT_EQUAL(sign(strncmp(left.rawContent(), right, n)), sign(left.cmp(right, n)));
+ if (sign(strncasecmp(left.rawContent(), right, n)) != sign(left.caseCmp(right, n)))
+ std::cerr << std::endl << " caseCmp(char*) " << n << ' ' << left << " ?= " << right;
+ CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left.rawContent(), right, n)), sign(left.caseCmp(right, n)));
+ }
+ xfree(right);
+ }
}
void
const char *alphabet="abcdefghijklmnopqrstuvwxyz";
SBuf a(alphabet);
std::string s(alphabet); // TODO
- { //regular chopping
+ { //regular chopping
SBuf b(a);
b.chop(3,3);
SBuf ref("def");
CPPUNIT_ASSERT_EQUAL(ref,b);
}
- { // chop at end
+ { // chop at end
SBuf b(a);
b.chop(b.length()-3);
SBuf ref("xyz");
CPPUNIT_ASSERT_EQUAL(ref,b);
}
- { // chop at beginning
+ { // chop at beginning
SBuf b(a);
b.chop(0,3);
SBuf ref("abc");
CPPUNIT_ASSERT_EQUAL(ref,b);
}
- { // chop to zero length
+ { // chop to zero length
SBuf b(a);
b.chop(5,0);
SBuf ref("");
CPPUNIT_ASSERT_EQUAL(ref,b);
}
- { // chop beyond end (at npos)
+ { // chop beyond end (at npos)
SBuf b(a);
b.chop(SBuf::npos,4);
SBuf ref("");
CPPUNIT_ASSERT_EQUAL(ref,b);
}
- { // chop beyond end
+ { // chop beyond end
SBuf b(a);
b.chop(b.length()+2,4);
SBuf ref("");
CPPUNIT_ASSERT_EQUAL(ref,b);
}
- { // null-chop
+ { // null-chop
SBuf b(a);
b.chop(0,b.length());
SBuf ref(a);
CPPUNIT_ASSERT_EQUAL(ref,b);
}
- { // overflow chopped area
+ { // overflow chopped area
SBuf b(a);
b.chop(b.length()-3,b.length());
SBuf ref("xyz");
CPPUNIT_ASSERT_EQUAL(s1,s2);
}
-// inspired to SBufFindTest; to be expanded.
+// inspired by SBufFindTest; to be expanded.
class SBufSubstrAutoTest
{
SBuf fullString, sb;
// FORWARD SEARCH
// needle in haystack
idx=s1.find('d');
- CPPUNIT_ASSERT_EQUAL(3,idx);
+ CPPUNIT_ASSERT_EQUAL(3U,idx);
CPPUNIT_ASSERT_EQUAL('d',s1[idx]);
// needle not present in haystack
CPPUNIT_ASSERT_EQUAL(nposResult,idx);
// search in portion
- idx=s1.find('e',3);
- CPPUNIT_ASSERT_EQUAL(4,idx);
+ idx=s1.find('e',3U);
+ CPPUNIT_ASSERT_EQUAL(4U,idx);
// char not in searched portion
- idx=s1.find('e',5);
+ idx=s1.find('e',5U);
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(3U, idx);
CPPUNIT_ASSERT_EQUAL('d', s1[idx]);
// needle not present in haystack
// search in portion
idx=s1.rfind('e',5);
- CPPUNIT_ASSERT_EQUAL(4,idx);
+ CPPUNIT_ASSERT_EQUAL(4U,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);
+ CPPUNIT_ASSERT_EQUAL(3U,idx);
}
void
// FORWARD search
// needle in haystack
idx = haystack.find(SBuf("def"));
- CPPUNIT_ASSERT_EQUAL(3,idx);
+ CPPUNIT_ASSERT_EQUAL(3U,idx);
idx = haystack.find(SBuf("xyz"));
- CPPUNIT_ASSERT_EQUAL(23,idx);
+ CPPUNIT_ASSERT_EQUAL(23U,idx);
// needle not in haystack, no initial char match
idx = haystack.find(SBuf(" eq"));
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);
h2.append(haystack);
idx = h2.find(SBuf("def"));
- CPPUNIT_ASSERT_EQUAL(3,idx);
+ CPPUNIT_ASSERT_EQUAL(3U,idx);
idx = h2.find(SBuf("xyzab"));
- CPPUNIT_ASSERT_EQUAL(23,idx);
+ CPPUNIT_ASSERT_EQUAL(23U,idx);
}
// REVERSE search
// needle in haystack
idx = haystack.rfind(SBuf("def"));
- CPPUNIT_ASSERT_EQUAL(3,idx);
+ CPPUNIT_ASSERT_EQUAL(3U,idx);
idx = haystack.rfind(SBuf("xyz"));
- CPPUNIT_ASSERT_EQUAL(23,idx);
+ CPPUNIT_ASSERT_EQUAL(23U,idx);
// needle not in haystack, no initial char match
idx = haystack.rfind(SBuf(" eq"));
// search in portion: needle in searched part
idx = haystack.rfind(SBuf("def"),7);
- CPPUNIT_ASSERT_EQUAL(3, idx);
+ CPPUNIT_ASSERT_EQUAL(3U, idx);
// search in portion: needle not in searched part
idx = haystack.rfind(SBuf("mno"),3);
// search in portion: overhang
idx = haystack.rfind(SBuf("def"),4);
- CPPUNIT_ASSERT_EQUAL(3, idx);
+ CPPUNIT_ASSERT_EQUAL(3U, 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);
+ CPPUNIT_ASSERT_EQUAL(3U, idx);
// needle bigger than haystack
idx = SBuf("def").rfind(haystack);
h2.append(haystack);
idx = h2.rfind(SBuf("def"));
- CPPUNIT_ASSERT_EQUAL(29,idx);
+ CPPUNIT_ASSERT_EQUAL(29U,idx);
idx = h2.find(SBuf("xyzab"));
- CPPUNIT_ASSERT_EQUAL(23,idx);
+ CPPUNIT_ASSERT_EQUAL(23U,idx);
}
}
SBuf s1(literal);
SBuf::size_type idx;
idx=s1.rfind(' ');
- CPPUNIT_ASSERT_EQUAL(40,idx);
+ CPPUNIT_ASSERT_EQUAL(40U,idx);
CPPUNIT_ASSERT_EQUAL(' ',s1[idx]);
}
CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
idx=haystack.rfind(SBuf("fox"));
- CPPUNIT_ASSERT_EQUAL(16,idx);
+ CPPUNIT_ASSERT_EQUAL(16U,idx);
// needle not found, no match for first char
idx=goobar.rfind(SBuf("foo"));
SBuf g("g"); //match at the last char
idx=haystack.rfind(g);
- CPPUNIT_ASSERT_EQUAL(43,idx);
+ CPPUNIT_ASSERT_EQUAL(43U,idx);
CPPUNIT_ASSERT_EQUAL('g',haystack[idx]);
idx=haystack.rfind(SBuf("The"));
- CPPUNIT_ASSERT_EQUAL(0,idx);
+ CPPUNIT_ASSERT_EQUAL(0U,idx);
haystack.append("The");
idx=haystack.rfind(SBuf("The"));
- CPPUNIT_ASSERT_EQUAL(44,idx);
+ CPPUNIT_ASSERT_EQUAL(44U,idx);
//partial match
haystack="The quick brown fox";
CPPUNIT_ASSERT_EQUAL(static_cast<float>(123.5),f);
}
-void testSBuf::testCopy()
+void
+testSBuf::testCopy()
{
char buf[40]; //shorter than literal()
SBuf s(fox1),s2;
CPPUNIT_ASSERT_EQUAL(s.length(),s.copy(buf,40));
CPPUNIT_ASSERT_EQUAL(0,strncmp(s.rawContent(),buf,s.length()));
s=literal;
- CPPUNIT_ASSERT_EQUAL(40,s.copy(buf,40));
+ CPPUNIT_ASSERT_EQUAL(40U,s.copy(buf,40));
s2.assign(buf,40);
s.chop(0,40);
CPPUNIT_ASSERT_EQUAL(s2,s);
}
-void testSBuf::testStringOps()
+void
+testSBuf::testStringOps()
{
- SBuf sng(literal.toLower()),
- ref("the quick brown fox jumped over the lazy dog");
+ SBuf sng(ToLower(literal)),
+ ref("the quick brown fox jumped over the lazy dog");
CPPUNIT_ASSERT_EQUAL(ref,sng);
sng=literal;
CPPUNIT_ASSERT_EQUAL(0,sng.compare(ref,caseInsensitive));
CPPUNIT_ASSERT_EQUAL(0,SBuf("the").compare(SBuf("THE"),caseInsensitive,6));
}
-void testSBuf::testGrow()
+void
+testSBuf::testGrow()
{
SBuf t;
t.assign("foo");
CPPUNIT_ASSERT_EQUAL(ref,match);
}
-void testSBuf::testStartsWith()
+void
+testSBuf::testStartsWith()
{
static SBuf casebuf("THE QUICK");
CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1)));
// case-insensitive checks
CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive));
- casebuf=SBuf(fox1).toUpper();
+ casebuf=ToUpper(SBuf(fox1));
CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive));
CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1),caseInsensitive));
casebuf = "tha quick";
CPPUNIT_ASSERT_EQUAL(false,literal.startsWith(casebuf,caseInsensitive));
}
-void testSBuf::testSBufStream()
+void
+testSBuf::testSBufStream()
{
SBuf b("const.string, int 10 and a float 10.5");
SBufStream ss;
CPPUNIT_ASSERT_EQUAL(f1,SBuf(fox1));
}
-void testSBuf::testFindFirstOf()
+void
+testSBuf::testFindFirstOf()
{
SBuf haystack(literal);
SBuf::size_type idx;
// not found
- idx=haystack.find_first_of(SBuf("ADHRWYP"));
+ idx=haystack.findFirstOf(CharacterSet("t1","ADHRWYP"));
CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
// found at beginning
- idx=haystack.find_first_of(SBuf("THANDF"));
- CPPUNIT_ASSERT_EQUAL(0,idx);
+ idx=haystack.findFirstOf(CharacterSet("t2","THANDF"));
+ CPPUNIT_ASSERT_EQUAL(0U,idx);
//found at end of haystack
- idx=haystack.find_first_of(SBuf("QWERYVg"));
+ idx=haystack.findFirstOf(CharacterSet("t3","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);
+ idx=haystack.findFirstOf(CharacterSet("t4","QWERqYV"));
+ CPPUNIT_ASSERT_EQUAL(4U,idx);
}
-void testSBuf::testAutoFind()
+void
+testSBuf::testFindFirstNotOf()
+{
+ SBuf haystack(literal);
+ SBuf::size_type idx;
+
+ // all chars from the set
+ idx=haystack.findFirstNotOf(CharacterSet("t1",literal.c_str()));
+ CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
+
+ // found at beginning
+ idx=haystack.findFirstNotOf(CharacterSet("t2","a"));
+ CPPUNIT_ASSERT_EQUAL(0U,idx);
+
+ //found at end of haystack
+ idx=haystack.findFirstNotOf(CharacterSet("t3",literal.substr(0,literal.length()-1).c_str()));
+ CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
+
+ //found in the middle of haystack
+ idx=haystack.findFirstNotOf(CharacterSet("t4","The"));
+ CPPUNIT_ASSERT_EQUAL(3U,idx);
+}
+
+void
+testSBuf::testAutoFind()
{
SBufFindTest test;
test.run();
}
-void testSBuf::testStdStringOps()
+void
+testSBuf::testStdStringOps()
{
const char *alphabet="abcdefghijklmnopqrstuvwxyz";
std::string astr(alphabet);
SBuf sb(alphabet);
CPPUNIT_ASSERT_EQUAL(astr,sb.toStdString());
}
+
+void
+testSBuf::testIterators()
+{
+ SBuf text("foo"), text2("foo");
+ CPPUNIT_ASSERT(text.begin() == text.begin());
+ CPPUNIT_ASSERT(text.begin() != text.end());
+ CPPUNIT_ASSERT(text.begin() != text2.begin());
+ {
+ auto i = text.begin();
+ auto e = text.end();
+ CPPUNIT_ASSERT_EQUAL('f', *i);
+ CPPUNIT_ASSERT(i != e);
+ ++i;
+ CPPUNIT_ASSERT_EQUAL('o', *i);
+ CPPUNIT_ASSERT(i != e);
+ ++i;
+ CPPUNIT_ASSERT_EQUAL('o', *i);
+ CPPUNIT_ASSERT(i != e);
+ ++i;
+ CPPUNIT_ASSERT(i == e);
+ }
+ {
+ auto i = text.rbegin();
+ auto e = text.rend();
+ CPPUNIT_ASSERT_EQUAL('o', *i);
+ CPPUNIT_ASSERT(i != e);
+ ++i;
+ CPPUNIT_ASSERT_EQUAL('o', *i);
+ CPPUNIT_ASSERT(i != e);
+ ++i;
+ CPPUNIT_ASSERT_EQUAL('f', *i);
+ CPPUNIT_ASSERT(i != e);
+ ++i;
+ CPPUNIT_ASSERT(i == e);
+ }
+}
+
+void
+testSBuf::testSBufHash()
+{
+ // same SBuf must have same hash
+ auto hasher=std::hash<SBuf>();
+ CPPUNIT_ASSERT_EQUAL(hasher(literal),hasher(literal));
+
+ // same content must have same hash
+ CPPUNIT_ASSERT_EQUAL(hasher(literal),hasher(SBuf(fox)));
+ CPPUNIT_ASSERT_EQUAL(hasher(SBuf(fox)),hasher(SBuf(fox)));
+
+ //differen content should have different hash
+ CPPUNIT_ASSERT(hasher(SBuf(fox)) != hasher(SBuf(fox1)));
+
+ {
+ std::unordered_map<SBuf, int> um;
+ um[SBuf("one")] = 1;
+ um[SBuf("two")] = 2;
+
+ auto i = um.find(SBuf("one"));
+ CPPUNIT_ASSERT(i != um.end());
+ CPPUNIT_ASSERT(i->second == 1);
+
+ i = um.find(SBuf("eleventy"));
+ CPPUNIT_ASSERT(i == um.end());
+ }
+}
+