Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / tests / zypp / base / String_test.cc
index f479e22..152a229 100644 (file)
@@ -1,9 +1,6 @@
-#include <string>
-#include <vector>
-#include <iterator>
-
 #include <boost/test/auto_unit_test.hpp>
 
+#include "zypp/base/LogTools.h"
 #include "zypp/base/String.h"
 
 using boost::unit_test::test_suite;
@@ -48,43 +45,110 @@ BOOST_AUTO_TEST_CASE(testsplitEscaped)
   string s( "simple non-escaped string" );
   vector<string> v;
 
-  insert_iterator<vector<string> > ii (v,v.end());
-  splitEscaped( s, ii );
+  splitEscaped( s, std::back_inserter(v) );
   BOOST_CHECK_EQUAL( v.size(), 3 );
+  BOOST_CHECK_EQUAL( v[0], "simple" );
+  BOOST_CHECK_EQUAL( v[1], "non-escaped" );
+  BOOST_CHECK_EQUAL( v[2], "string" );
 
   v.clear();
   s = string( "\"escaped sentence \"" );
-  ii = insert_iterator<vector<string> >( v, v.end() );
-  splitEscaped( s, ii );
+  splitEscaped( s, std::back_inserter(v) );
   BOOST_CHECK_EQUAL( v.size(), 1 );
-  BOOST_CHECK_EQUAL( v.front(), string( "escaped sentence " ) );
-
-   v.clear();
-   s = string( "\"escaped \\\\sent\\\"ence \\\\\"" );
-   ii = insert_iterator<vector<string> >( v, v.end() );
-   splitEscaped( s, ii );
-   BOOST_CHECK_EQUAL( v.size(), 1 );
-   BOOST_CHECK_EQUAL( v.front(), string( "escaped \\sent\"ence \\" ) );
-
-
-   v.clear();
-   s = string( "escaped sentence\\ with\\ space" );
-   ii = insert_iterator<vector<string> >( v, v.end() );
-   splitEscaped( s, ii );
-   BOOST_CHECK_EQUAL( v.size(), 2 );
-   BOOST_CHECK_EQUAL( v[1], string( "sentence with space" ) );
-
-   // split - join
-   v.clear();
-   s = "some line \"\" foo\\ a foo\\\\ b";
-   str::splitEscaped( s, std::back_inserter(v) );
-   BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end() ) );
-
-   // split - join using alternate sepchar
-   s = str::joinEscaped( v.begin(), v.end(), 'o' );
-   v.clear();
-   str::splitEscaped( s, std::back_inserter(v), "o" );
-   BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end(), 'o' ) );
+  BOOST_CHECK_EQUAL( v[0], "escaped sentence " );
+
+  v.clear();
+  s = string( "\"escaped \\\\sent\\\"ence \\\\\"" );
+  splitEscaped( s, std::back_inserter(v) );
+  BOOST_CHECK_EQUAL( v.size(), 1 );
+  BOOST_CHECK_EQUAL( v[0], "escaped \\sent\"ence \\" );
+
+  v.clear();
+  s = string( "escaped sentence\\ with\\ space" );
+  splitEscaped( s, std::back_inserter(v) );
+  BOOST_CHECK_EQUAL( v.size(), 2 );
+  BOOST_CHECK_EQUAL( v[0], "escaped" );
+  BOOST_CHECK_EQUAL( v[1], "sentence with space" );
+
+  // split - join
+  v.clear();
+  s = "some line \"\" foo\\ a foo\\\\ b";
+  str::splitEscaped( s, std::back_inserter(v) );
+  BOOST_CHECK_EQUAL( v.size(), 6 );
+  BOOST_CHECK_EQUAL( v[0], "some" );
+  BOOST_CHECK_EQUAL( v[1], "line" );
+  BOOST_CHECK_EQUAL( v[2], "" );
+  BOOST_CHECK_EQUAL( v[3], "foo a" );
+  BOOST_CHECK_EQUAL( v[4], "foo\\" );
+  BOOST_CHECK_EQUAL( v[5], "b" );
+  BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end() ) );
+
+  // split - join using alternate sepchar
+  s = str::joinEscaped( v.begin(), v.end(), 'o' );
+  v.clear();
+  str::splitEscaped( s, std::back_inserter(v), "o" );
+  BOOST_CHECK_EQUAL( v.size(), 6 );
+  BOOST_CHECK_EQUAL( v[0], "some" );
+  BOOST_CHECK_EQUAL( v[1], "line" );
+  BOOST_CHECK_EQUAL( v[2], "" );
+  BOOST_CHECK_EQUAL( v[3], "foo a" );
+  BOOST_CHECK_EQUAL( v[4], "foo\\" );
+  BOOST_CHECK_EQUAL( v[5], "b" );
+  BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end(), 'o' ) );
+}
+
+BOOST_AUTO_TEST_CASE(bnc_909772)
+{
+  // While \-escaping processes single-quote, double-quote, backslash and sepchar[ ]
+  // deescaping failed to process the quotes correctly.
+  std::string s;
+  std::vector<std::string> v;
+
+  v.clear();
+  v.push_back("");
+  v.push_back("'\" \\");
+  v.push_back("\\'\\\"\\ \\\\");
+  s = str::joinEscaped( v.begin(), v.end() );
+  BOOST_CHECK_EQUAL( s, "\"\""  " "  "\\'\\\"\\ \\\\"  " "  "\\\\\\'\\\\\\\"\\\\\\ \\\\\\\\" );
+
+  s += " ";
+  s += "'"   "\\\\\" \\ \\\\"   "'\\ single";  // single quote: all literal, no ' inside
+
+  s += " ";
+  s += "\""   "\\'\\\" \\ \\\\"   "\"\\ double";// double quote: all literal except \\ \"
+
+  v.clear();
+  splitEscaped( s, std::back_inserter(v) );
+  BOOST_CHECK_EQUAL( v.size(), 5 );
+  BOOST_CHECK_EQUAL( v[0], "" );
+  BOOST_CHECK_EQUAL( v[1], "'\" \\" );
+  BOOST_CHECK_EQUAL( v[2], "\\'\\\"\\ \\\\" );
+  BOOST_CHECK_EQUAL( v[3], "\\\\\" \\ \\\\ single" );
+  BOOST_CHECK_EQUAL( v[4], "\\'\" \\ \\ double" );
+}
+
+BOOST_AUTO_TEST_CASE(testsplitEscapedWithEmpty)
+{
+  string s( "simple:non-escaped:string" );
+  vector<string> v;
+
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
+  BOOST_CHECK_EQUAL(v.size(), 3);
+
+  v.clear();
+  s = "non-escaped:with::spaces:";
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 5);
+  BOOST_CHECK_EQUAL(v.size(), 5);
+
+  v.clear();
+  s = "::";
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
+  BOOST_CHECK_EQUAL(v.size(), 3);
+
+  v.clear();
+  s = ":escaped::with\\:spaces";
+  BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 4);
+  BOOST_CHECK_EQUAL(v.size(), 4);
 }
 
 BOOST_AUTO_TEST_CASE(test_escape)
@@ -94,3 +158,191 @@ BOOST_AUTO_TEST_CASE(test_escape)
 
   BOOST_CHECK_EQUAL( escaped, "bad\\|ass\\\\\\|worse" );
 }
+
+BOOST_AUTO_TEST_CASE(conversions)
+{
+    BOOST_CHECK_EQUAL(str::numstring(42),     "42");
+    BOOST_CHECK_EQUAL(str::numstring(42, 6),  "    42");
+    BOOST_CHECK_EQUAL(str::numstring(42, -6), "42    ");
+
+    BOOST_CHECK_EQUAL(str::hexstring(42),     "0x0000002a");
+    BOOST_CHECK_EQUAL(str::hexstring(42, 6),  "0x002a");
+    BOOST_CHECK_EQUAL(str::hexstring(42, -6), "0x2a  ");
+
+    BOOST_CHECK_EQUAL(str::octstring(42),     "00052");
+    BOOST_CHECK_EQUAL(str::octstring(42, 6),  "000052");
+    BOOST_CHECK_EQUAL(str::octstring(42, -6), "052   ");
+
+    BOOST_CHECK_EQUAL(str::strtonum<int>("42"), 42);
+
+    BOOST_CHECK_EQUAL(str::toLower("This IS A TeST"), "this is a test");
+    BOOST_CHECK_EQUAL(str::toUpper("This IS A TeST"), "THIS IS A TEST");
+    BOOST_CHECK_EQUAL(str::compareCI("TeST", "test"), 0);
+
+    BOOST_CHECK_EQUAL(str::compareCI("TeST", "test"), 0);
+    BOOST_CHECK_EQUAL(str::compareCI("TeST", "test"), 0);
+}
+
+BOOST_AUTO_TEST_CASE(conversions_to_bool)
+{
+  // true iff true-string {1,on,yes,true}
+  BOOST_CHECK_EQUAL( str::strToTrue("1"),     true );
+  BOOST_CHECK_EQUAL( str::strToTrue("42"),    true );
+  BOOST_CHECK_EQUAL( str::strToTrue("ON"),    true );
+  BOOST_CHECK_EQUAL( str::strToTrue("YES"),   true );
+  BOOST_CHECK_EQUAL( str::strToTrue("TRUE"),  true );
+  BOOST_CHECK_EQUAL( str::strToTrue("0"),     false );
+  BOOST_CHECK_EQUAL( str::strToTrue("OFF"),   false );
+  BOOST_CHECK_EQUAL( str::strToTrue("NO"),    false );
+  BOOST_CHECK_EQUAL( str::strToTrue("FALSE"), false );
+  BOOST_CHECK_EQUAL( str::strToTrue(""),      false );
+  BOOST_CHECK_EQUAL( str::strToTrue("foo"),   false );
+
+  // false iff false-string {0,off,no,false}
+  BOOST_CHECK_EQUAL( str::strToFalse("1"),     true );
+  BOOST_CHECK_EQUAL( str::strToFalse("42"),    true );
+  BOOST_CHECK_EQUAL( str::strToFalse("ON"),    true );
+  BOOST_CHECK_EQUAL( str::strToFalse("YES"),   true );
+  BOOST_CHECK_EQUAL( str::strToFalse("TRUE"),  true );
+  BOOST_CHECK_EQUAL( str::strToFalse("0"),     false );
+  BOOST_CHECK_EQUAL( str::strToFalse("OFF"),   false );
+  BOOST_CHECK_EQUAL( str::strToFalse("NO"),    false );
+  BOOST_CHECK_EQUAL( str::strToFalse("FALSE"), false );
+  BOOST_CHECK_EQUAL( str::strToFalse(""),      true );
+  BOOST_CHECK_EQUAL( str::strToFalse("foo"),   true );
+
+  // true iff true-string
+  BOOST_CHECK_EQUAL( str::strToBool("TRUE",  false), true );
+  BOOST_CHECK_EQUAL( str::strToBool("FALSE", false), false );
+  BOOST_CHECK_EQUAL( str::strToBool("",      false), false );
+  BOOST_CHECK_EQUAL( str::strToBool("foo",   false), false );
+
+  // false iff false-string
+  BOOST_CHECK_EQUAL( str::strToBool("TRUE",  true),  true );
+  BOOST_CHECK_EQUAL( str::strToBool("FALSE", true),  false );
+  BOOST_CHECK_EQUAL( str::strToBool("",      true),  true );
+  BOOST_CHECK_EQUAL( str::strToBool("foo",   true),  true );
+
+  // true/false iff true/false-string, else unchanged
+  bool ret;
+  ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("TRUE",  ret),  true );
+  ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("FALSE", ret),  false );
+  ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("",      ret),  true );
+  ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("foo",   ret),  true );
+
+  ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("TRUE",  ret),  true );
+  ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("FALSE", ret),  false );
+  ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("",      ret),  false );
+  ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("foo",   ret),  false );
+}
+
+BOOST_AUTO_TEST_CASE(operations)
+{
+    BOOST_CHECK_EQUAL(str::ltrim(" \t f \t ffo \t "), "f \t ffo \t ");
+    BOOST_CHECK_EQUAL(str::rtrim(" \t f \t ffo \t "), " \t f \t ffo");
+    BOOST_CHECK_EQUAL(str::trim(" \t f \t ffo \t "),  "f \t ffo");
+
+    // strip first
+    {
+        string tostrip(" Oh! la la ");
+        string word( str::stripFirstWord(tostrip, true) ); // ltrim first
+        BOOST_CHECK_EQUAL(word, "Oh!");
+        BOOST_CHECK_EQUAL(tostrip, "la la ");
+    }
+    {
+        string tostrip(" Oh! la la ");
+        string word( str::stripFirstWord(tostrip, false) ); // no ltrim first
+        BOOST_CHECK_EQUAL(word, "");
+        BOOST_CHECK_EQUAL(tostrip, "Oh! la la ");
+    }
+
+    // strip last
+    {
+        string tostrip(" Oh! la la ");
+        string word( str::stripLastWord(tostrip, true) ); // rtrim first
+        BOOST_CHECK_EQUAL(word, "la");
+        BOOST_CHECK_EQUAL(tostrip, " Oh! la");
+    }
+    {
+        string tostrip(" Oh! la la ");
+        string word( str::stripLastWord(tostrip, false) ); // no rtrim first
+        BOOST_CHECK_EQUAL(word, "");
+        BOOST_CHECK_EQUAL(tostrip, " Oh! la la");
+    }
+}
+
+BOOST_AUTO_TEST_CASE(prefix_suffix)
+{
+  BOOST_CHECK( str::hasPrefix("abcXabcYabc", "abcX") );
+  BOOST_CHECK( str::hasSuffix("abcXabcYabc", "Yabc") );
+
+  BOOST_CHECK_EQUAL( str::stripPrefix("abcXabcYabc", "abcX"),  "abcYabc" );
+  BOOST_CHECK_EQUAL( str::stripSuffix("abcXabcYabc", "Yabc"),  "abcXabc" );
+
+  BOOST_CHECK( ! str::hasPrefix("abcXabcYabc", "ac") );
+  BOOST_CHECK( ! str::hasSuffix("abcXabcYabc", "ac") );
+
+  BOOST_CHECK_EQUAL( str::stripPrefix("abcXabcYabc", "ac"),  "abcXabcYabc" );
+  BOOST_CHECK_EQUAL( str::stripSuffix("abcXabcYabc", "ac"),  "abcXabcYabc" );
+
+  BOOST_CHECK( str::startsWith("abcXabcYabc", "abc") );
+  BOOST_CHECK( str::endsWith("abcXabcYabc", "abc") );
+
+  BOOST_CHECK( str::contains("abcXabcYabc", "XabcY") );
+  BOOST_CHECK( ! str::contains("abcXabcYabc", "xabcy") );
+  BOOST_CHECK( str::containsCI("abcXabcYabc", "xabcy") );
+
+  BOOST_CHECK_EQUAL( str::commonPrefix("", ""),                0 );
+  BOOST_CHECK_EQUAL( str::commonPrefix("a", ""),       0 );
+  BOOST_CHECK_EQUAL( str::commonPrefix("", "b"),       0 );
+  BOOST_CHECK_EQUAL( str::commonPrefix("a", "b"),      0 );
+  BOOST_CHECK_EQUAL( str::commonPrefix("c", "c"),      1 );
+  BOOST_CHECK_EQUAL( str::commonPrefix("ca", "cb"),    1 );
+}
+
+BOOST_AUTO_TEST_CASE(hexencode_hexdecode)
+{
+  std::string o;
+  o.reserve( 256 );
+  for ( unsigned i = 1; i < 256; ++i )
+    o += i;
+
+  std::string e( str::hexencode( o ) );
+  // encoded contains nothing but [%a-zA-Z0-9]
+  for ( unsigned i = 0; i < 255; ++i )
+  {
+    char ch = e[i];
+    BOOST_CHECK( ch == '%'
+                 || ( 'a' <= ch && ch <= 'z' )
+                 || ( 'A' <= ch && ch <= 'Z' )
+                 || ( '0' <= ch && ch <= '9' ) );
+  }
+
+  std::string d( str::hexdecode( e ) );
+  // decoded equals original
+  BOOST_CHECK( o == d );
+
+  // Test %XX is decoded for hexdigits only
+  const char *const dig = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  for ( const char * d1 = dig; *d1; ++d1 )
+    for ( const char * d2 = dig; *d2; ++d2 )
+    {
+      std::string eu( "%" );
+      eu += *d1; eu += *d2;
+      std::string el( str::toLower(eu) );
+
+      std::string u( str::hexdecode( eu ) );
+      std::string l( str::hexdecode( el ) );
+
+      if ( *d1 <= 'F' &&  *d2 <= 'F' )
+      {
+       BOOST_CHECK_EQUAL( u, l );              // no matter if upper or lower case hexdigit
+       BOOST_CHECK_EQUAL( u.size(), 1 );       // size 1 == decoded
+      }
+      else
+      {
+       BOOST_CHECK_EQUAL( u, eu );             // no hexdigits remain unchanged
+       BOOST_CHECK_EQUAL( l, el );
+     }
+    }
+}