add latin-1 wrapper for html_entities
[libi2ncommon] / test / stringfunc.cpp
index bf33781..90bd63a 100644 (file)
@@ -128,6 +128,12 @@ BOOST_AUTO_TEST_CASE(html_entities3)
     BOOST_CHECK_EQUAL(string("Ď ༱ 肈"), output);
 }
 
+BOOST_AUTO_TEST_CASE(entities_latin1)
+{
+    BOOST_CHECK_EQUAL((std::string)"noop", html_entities_iso ("noop"));
+    BOOST_CHECK_EQUAL((std::string)"täst", html_entities_iso ("t\xe4st"));
+    BOOST_CHECK_EQUAL((std::string)"TÄST", html_entities_iso ("T\xc4ST"));
+}
 
 
 BOOST_AUTO_TEST_CASE(nice_unit_format1)
@@ -614,9 +620,17 @@ BOOST_AUTO_TEST_CASE(SplitToVector)
 BOOST_AUTO_TEST_CASE(JoinString1)
 {
     std::list< std::string > parts;
-    get_push_back_filler(parts)("1")("2")("drei");
-
     std::string joined_string= join_string(parts,"/");
+    BOOST_CHECK_EQUAL( std::string("") , joined_string );
+
+    parts.push_back ("1");
+    joined_string= join_string(parts,"/");
+    // we should have slashes between the strings:
+    BOOST_CHECK_EQUAL( std::string("1") , joined_string );
+
+    get_push_back_filler(parts)("2")("drei");
+
+    joined_string= join_string(parts,"/");
     // we should have slashes between the strings:
     BOOST_CHECK_EQUAL( std::string("1/2/drei") , joined_string );
 
@@ -655,6 +669,121 @@ BOOST_AUTO_TEST_CASE(JoinStringVector)
 } // eo JoinStringVector
 
 
+BOOST_AUTO_TEST_CASE(JoinStringSet)
+{
+    std::set< std::string > parts;
+
+    std::string joined_string= join_string(parts,"/");
+    BOOST_CHECK_EQUAL( std::string() , joined_string );
+
+    parts.insert ("foo");
+    joined_string= join_string(parts,"/");
+    BOOST_CHECK_EQUAL( std::string("foo") , joined_string );
+
+    parts.insert ("bar");
+    parts.insert ("baz");
+
+    joined_string= join_string(parts,"/");
+    // we should have slashes between the strings:
+    BOOST_CHECK_EQUAL( std::string("bar/baz/foo") , joined_string );
+
+    parts.insert( std::string() );
+    joined_string= join_string(parts,"/");
+    // now we should have an additional trailing slash:
+    BOOST_CHECK_EQUAL( std::string("/bar/baz/foo") , joined_string );
+} // eo JoinStringSet
+
+
+BOOST_AUTO_TEST_CASE(JoinStringIterSet_Empty)
+{
+    std::set< std::string > parts;
+
+    // empty sequence → empty string
+    BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end ()     ), "");
+    BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end (), "/"), "");
+} // eo JoinStringSet
+
+BOOST_AUTO_TEST_CASE(JoinStringIterSet_One)
+{
+    std::set< std::string > parts;
+
+    parts.insert ("foo");
+
+    // cardinality == 1 → no delimiter
+    BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end ()     ), "foo");
+    BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end (), "/"), "foo");
+} // eo JoinStringSet
+
+BOOST_AUTO_TEST_CASE(JoinStringIterSet)
+{
+    std::set< std::string > parts;
+
+    parts.insert ("foo");
+    parts.insert ("bar");
+    parts.insert ("baz");
+
+    std::string joined_string= join_string(parts.begin (), parts.end (), "/");
+    // we should have slashes between the strings:
+    BOOST_CHECK_EQUAL( std::string("bar/baz/foo") , joined_string );
+
+    parts.insert( std::string() );
+    joined_string= join_string(parts.begin (), parts.end (),"/");
+    // now we should have an additional trailing slash:
+    BOOST_CHECK_EQUAL( std::string("/bar/baz/foo") , joined_string );
+} // eo JoinStringSet
+
+
+BOOST_AUTO_TEST_CASE(JoinStringIterSet_Default)
+{   /* default delimiter is newline */
+    std::set< std::string > parts;
+
+    parts.insert ("foo");
+    parts.insert ("bar");
+    parts.insert ("baz");
+
+    BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end ()), "bar\nbaz\nfoo");
+    BOOST_CHECK_EQUAL(join_string (parts                       ), "bar\nbaz\nfoo");
+
+} // eo JoinStringSet
+
+
+BOOST_AUTO_TEST_CASE(JoinStringArray_Empty)
+{
+    const char *const parts [] = { NULL };
+
+    BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [0], "/"), "");
+    BOOST_CHECK_EQUAL(join_string(parts                 , "/"), "");
+
+    BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [0]), "");
+    BOOST_CHECK_EQUAL(join_string(parts                 ), "");
+
+} // eo JoinStringSet
+
+BOOST_AUTO_TEST_CASE(JoinStringArray_One)
+{
+    const char *const parts [] = { "one", NULL };
+
+    BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [1], "/"), "one");
+    BOOST_CHECK_EQUAL(join_string(parts                 , "/"), "one");
+
+    BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [1]), "one");
+    BOOST_CHECK_EQUAL(join_string(parts                 ), "one");
+
+} // eo JoinStringSet
+
+BOOST_AUTO_TEST_CASE(JoinStringArray_Many)
+{
+    const char *const parts [5] = { "one", "two", "three", "many", NULL };
+
+    BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [4], "/"), "one/two/three/many");
+    BOOST_CHECK_EQUAL(join_string(parts                 , "/"), "one/two/three/many");
+
+    BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [4]), "one\ntwo\nthree\nmany");
+    BOOST_CHECK_EQUAL(join_string(parts                 ), "one\ntwo\nthree\nmany");
+
+} // eo JoinStringSet
+
+
 BOOST_AUTO_TEST_CASE(ConversionStringInt)
 {
     std::string s1("24");
@@ -849,4 +978,85 @@ BOOST_AUTO_TEST_CASE(shorten_stl_types_nothing)
     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
 }
 
+BOOST_AUTO_TEST_CASE(base64_encode_decode)
+{
+    string text = "Hello World\n";
+
+    string encoded = base64_encode(text);
+
+    BOOST_CHECK_EQUAL("SGVsbG8gV29ybGQK", encoded);
+    BOOST_CHECK_EQUAL(text, base64_decode(encoded));
+}
+
+BOOST_AUTO_TEST_CASE(base64_empty_string)
+{
+    string text = "";
+    string encoded = base64_encode(text);
+
+    BOOST_CHECK_EQUAL("", encoded);
+    BOOST_CHECK_EQUAL(text, base64_decode(encoded));
+}
+
+BOOST_AUTO_TEST_CASE(base64_large_string_with_zero)
+{
+    // 10 MB data
+    int data_size = 1024 * 1024 * 10;
+
+    string large_binary_data(data_size, 0);
+    BOOST_CHECK_EQUAL(data_size, large_binary_data.size());
+
+    string encoded = base64_encode(large_binary_data);
+
+    string decoded = base64_decode(encoded);
+    BOOST_CHECK_EQUAL(large_binary_data, decoded);
+}
+
+BOOST_AUTO_TEST_CASE(base64_large_string_with_zero_encode_linefeeds)
+{
+    // 10 MB data
+    int data_size = 1024 * 1024 * 10;
+
+    string large_binary_data(data_size, 0);
+    BOOST_CHECK_EQUAL(data_size, large_binary_data.size());
+
+    const bool one_line_mode = false;
+    string encoded = base64_encode(large_binary_data, one_line_mode);
+
+    string decoded = base64_decode(encoded, one_line_mode);
+    BOOST_CHECK_EQUAL(large_binary_data, decoded);
+}
+
+BOOST_AUTO_TEST_CASE(base64_decode_garbage)
+{
+    std::string data = "Hello World, this is unencoded data";
+    string decoded = base64_decode(data);
+
+    // garbage turns out to be an empty string
+    BOOST_CHECK_EQUAL(0, decoded.size());
+}
+
+BOOST_AUTO_TEST_CASE(base64_encode_with_linefeeds)
+{
+    const string data = string("Hello World\n")
+                       + "Hello World\n"
+                       + "Hello World\n"
+                       + "Hello World\n"
+                       + "Hello World\n"
+                       + "Hello World\n"
+                       + "Hello World\n";
+
+    const string encoded = base64_encode(data, false);
+
+    const std::string expected = string("SGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQK\n")
+                                 + "SGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQK\n";
+    BOOST_CHECK_EQUAL(expected, encoded);
+
+    // decode and compare
+    BOOST_CHECK_EQUAL(data, base64_decode(encoded, false));
+
+    // expected empty string when switching on single line base64 mode
+    // (openssl is very strict about this)
+    BOOST_CHECK_EQUAL("", base64_decode(encoded, true));
+}
+
 BOOST_AUTO_TEST_SUITE_END()