Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / tests / zypp / base / String_test.cc
1 #include <boost/test/auto_unit_test.hpp>
2
3 #include "zypp/base/LogTools.h"
4 #include "zypp/base/String.h"
5
6 using boost::unit_test::test_suite;
7 using boost::unit_test::test_case;
8 using namespace boost::unit_test;
9
10 using namespace std;
11 using namespace zypp;
12 using namespace zypp::str;
13
14 BOOST_AUTO_TEST_CASE(gsubTest)
15 {
16   string olds = "olds";
17   string news = "new string";
18
19   BOOST_CHECK_EQUAL(gsub("test olds string",olds,news), "test new string string");
20   BOOST_CHECK_EQUAL(gsub("no string",olds,news),"no string");
21   BOOST_CHECK_EQUAL(gsub("oldsolds",olds,news),"new stringnew string");
22 }
23
24 BOOST_AUTO_TEST_CASE(replaceAllTest)
25 {
26   string olds = "olds";
27   string news = "new string";
28   string tests;
29
30   tests = "test olds string";
31   replaceAll(tests,olds,news);
32   BOOST_CHECK_EQUAL(tests, "test new string string");
33
34   tests = "no string";
35   replaceAll(tests,olds,news);
36   BOOST_CHECK_EQUAL(tests, "no string");
37
38   tests = "oldsolds";
39   replaceAll(tests,olds,news);
40   BOOST_CHECK_EQUAL(tests, "new stringnew string");
41 }
42
43 BOOST_AUTO_TEST_CASE(testsplitEscaped)
44 {
45   string s( "simple non-escaped string" );
46   vector<string> v;
47
48   splitEscaped( s, std::back_inserter(v) );
49   BOOST_CHECK_EQUAL( v.size(), 3 );
50   BOOST_CHECK_EQUAL( v[0], "simple" );
51   BOOST_CHECK_EQUAL( v[1], "non-escaped" );
52   BOOST_CHECK_EQUAL( v[2], "string" );
53
54   v.clear();
55   s = string( "\"escaped sentence \"" );
56   splitEscaped( s, std::back_inserter(v) );
57   BOOST_CHECK_EQUAL( v.size(), 1 );
58   BOOST_CHECK_EQUAL( v[0], "escaped sentence " );
59
60   v.clear();
61   s = string( "\"escaped \\\\sent\\\"ence \\\\\"" );
62   splitEscaped( s, std::back_inserter(v) );
63   BOOST_CHECK_EQUAL( v.size(), 1 );
64   BOOST_CHECK_EQUAL( v[0], "escaped \\sent\"ence \\" );
65
66   v.clear();
67   s = string( "escaped sentence\\ with\\ space" );
68   splitEscaped( s, std::back_inserter(v) );
69   BOOST_CHECK_EQUAL( v.size(), 2 );
70   BOOST_CHECK_EQUAL( v[0], "escaped" );
71   BOOST_CHECK_EQUAL( v[1], "sentence with space" );
72
73   // split - join
74   v.clear();
75   s = "some line \"\" foo\\ a foo\\\\ b";
76   str::splitEscaped( s, std::back_inserter(v) );
77   BOOST_CHECK_EQUAL( v.size(), 6 );
78   BOOST_CHECK_EQUAL( v[0], "some" );
79   BOOST_CHECK_EQUAL( v[1], "line" );
80   BOOST_CHECK_EQUAL( v[2], "" );
81   BOOST_CHECK_EQUAL( v[3], "foo a" );
82   BOOST_CHECK_EQUAL( v[4], "foo\\" );
83   BOOST_CHECK_EQUAL( v[5], "b" );
84   BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end() ) );
85
86   // split - join using alternate sepchar
87   s = str::joinEscaped( v.begin(), v.end(), 'o' );
88   v.clear();
89   str::splitEscaped( s, std::back_inserter(v), "o" );
90   BOOST_CHECK_EQUAL( v.size(), 6 );
91   BOOST_CHECK_EQUAL( v[0], "some" );
92   BOOST_CHECK_EQUAL( v[1], "line" );
93   BOOST_CHECK_EQUAL( v[2], "" );
94   BOOST_CHECK_EQUAL( v[3], "foo a" );
95   BOOST_CHECK_EQUAL( v[4], "foo\\" );
96   BOOST_CHECK_EQUAL( v[5], "b" );
97   BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end(), 'o' ) );
98 }
99
100 BOOST_AUTO_TEST_CASE(bnc_909772)
101 {
102   // While \-escaping processes single-quote, double-quote, backslash and sepchar[ ]
103   // deescaping failed to process the quotes correctly.
104   std::string s;
105   std::vector<std::string> v;
106
107   v.clear();
108   v.push_back("");
109   v.push_back("'\" \\");
110   v.push_back("\\'\\\"\\ \\\\");
111   s = str::joinEscaped( v.begin(), v.end() );
112   BOOST_CHECK_EQUAL( s, "\"\""  " "  "\\'\\\"\\ \\\\"  " "  "\\\\\\'\\\\\\\"\\\\\\ \\\\\\\\" );
113
114   s += " ";
115   s += "'"   "\\\\\" \\ \\\\"   "'\\ single";   // single quote: all literal, no ' inside
116
117   s += " ";
118   s += "\""   "\\'\\\" \\ \\\\"   "\"\\ double";// double quote: all literal except \\ \"
119
120   v.clear();
121   splitEscaped( s, std::back_inserter(v) );
122   BOOST_CHECK_EQUAL( v.size(), 5 );
123   BOOST_CHECK_EQUAL( v[0], "" );
124   BOOST_CHECK_EQUAL( v[1], "'\" \\" );
125   BOOST_CHECK_EQUAL( v[2], "\\'\\\"\\ \\\\" );
126   BOOST_CHECK_EQUAL( v[3], "\\\\\" \\ \\\\ single" );
127   BOOST_CHECK_EQUAL( v[4], "\\'\" \\ \\ double" );
128 }
129
130 BOOST_AUTO_TEST_CASE(testsplitEscapedWithEmpty)
131 {
132   string s( "simple:non-escaped:string" );
133   vector<string> v;
134
135   BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
136   BOOST_CHECK_EQUAL(v.size(), 3);
137
138   v.clear();
139   s = "non-escaped:with::spaces:";
140   BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 5);
141   BOOST_CHECK_EQUAL(v.size(), 5);
142
143   v.clear();
144   s = "::";
145   BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 3);
146   BOOST_CHECK_EQUAL(v.size(), 3);
147
148   v.clear();
149   s = ":escaped::with\\:spaces";
150   BOOST_CHECK_EQUAL(splitFieldsEscaped(s, std::back_inserter(v)), 4);
151   BOOST_CHECK_EQUAL(v.size(), 4);
152 }
153
154 BOOST_AUTO_TEST_CASE(test_escape)
155 {
156   string badass = "bad|ass\\|worse";
157   string escaped = str::escape(badass, '|');
158
159   BOOST_CHECK_EQUAL( escaped, "bad\\|ass\\\\\\|worse" );
160 }
161
162 BOOST_AUTO_TEST_CASE(conversions)
163 {
164     BOOST_CHECK_EQUAL(str::numstring(42),     "42");
165     BOOST_CHECK_EQUAL(str::numstring(42, 6),  "    42");
166     BOOST_CHECK_EQUAL(str::numstring(42, -6), "42    ");
167
168     BOOST_CHECK_EQUAL(str::hexstring(42),     "0x0000002a");
169     BOOST_CHECK_EQUAL(str::hexstring(42, 6),  "0x002a");
170     BOOST_CHECK_EQUAL(str::hexstring(42, -6), "0x2a  ");
171
172     BOOST_CHECK_EQUAL(str::octstring(42),     "00052");
173     BOOST_CHECK_EQUAL(str::octstring(42, 6),  "000052");
174     BOOST_CHECK_EQUAL(str::octstring(42, -6), "052   ");
175
176     BOOST_CHECK_EQUAL(str::strtonum<int>("42"), 42);
177
178     BOOST_CHECK_EQUAL(str::toLower("This IS A TeST"), "this is a test");
179     BOOST_CHECK_EQUAL(str::toUpper("This IS A TeST"), "THIS IS A TEST");
180     BOOST_CHECK_EQUAL(str::compareCI("TeST", "test"), 0);
181
182     BOOST_CHECK_EQUAL(str::compareCI("TeST", "test"), 0);
183     BOOST_CHECK_EQUAL(str::compareCI("TeST", "test"), 0);
184 }
185
186 BOOST_AUTO_TEST_CASE(conversions_to_bool)
187 {
188   // true iff true-string {1,on,yes,true}
189   BOOST_CHECK_EQUAL( str::strToTrue("1"),     true );
190   BOOST_CHECK_EQUAL( str::strToTrue("42"),    true );
191   BOOST_CHECK_EQUAL( str::strToTrue("ON"),    true );
192   BOOST_CHECK_EQUAL( str::strToTrue("YES"),   true );
193   BOOST_CHECK_EQUAL( str::strToTrue("TRUE"),  true );
194   BOOST_CHECK_EQUAL( str::strToTrue("0"),     false );
195   BOOST_CHECK_EQUAL( str::strToTrue("OFF"),   false );
196   BOOST_CHECK_EQUAL( str::strToTrue("NO"),    false );
197   BOOST_CHECK_EQUAL( str::strToTrue("FALSE"), false );
198   BOOST_CHECK_EQUAL( str::strToTrue(""),      false );
199   BOOST_CHECK_EQUAL( str::strToTrue("foo"),   false );
200
201   // false iff false-string {0,off,no,false}
202   BOOST_CHECK_EQUAL( str::strToFalse("1"),     true );
203   BOOST_CHECK_EQUAL( str::strToFalse("42"),    true );
204   BOOST_CHECK_EQUAL( str::strToFalse("ON"),    true );
205   BOOST_CHECK_EQUAL( str::strToFalse("YES"),   true );
206   BOOST_CHECK_EQUAL( str::strToFalse("TRUE"),  true );
207   BOOST_CHECK_EQUAL( str::strToFalse("0"),     false );
208   BOOST_CHECK_EQUAL( str::strToFalse("OFF"),   false );
209   BOOST_CHECK_EQUAL( str::strToFalse("NO"),    false );
210   BOOST_CHECK_EQUAL( str::strToFalse("FALSE"), false );
211   BOOST_CHECK_EQUAL( str::strToFalse(""),      true );
212   BOOST_CHECK_EQUAL( str::strToFalse("foo"),   true );
213
214   // true iff true-string
215   BOOST_CHECK_EQUAL( str::strToBool("TRUE",  false), true );
216   BOOST_CHECK_EQUAL( str::strToBool("FALSE", false), false );
217   BOOST_CHECK_EQUAL( str::strToBool("",      false), false );
218   BOOST_CHECK_EQUAL( str::strToBool("foo",   false), false );
219
220   // false iff false-string
221   BOOST_CHECK_EQUAL( str::strToBool("TRUE",  true),  true );
222   BOOST_CHECK_EQUAL( str::strToBool("FALSE", true),  false );
223   BOOST_CHECK_EQUAL( str::strToBool("",      true),  true );
224   BOOST_CHECK_EQUAL( str::strToBool("foo",   true),  true );
225
226   // true/false iff true/false-string, else unchanged
227   bool ret;
228   ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("TRUE",  ret),  true );
229   ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("FALSE", ret),  false );
230   ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("",      ret),  true );
231   ret = true; BOOST_CHECK_EQUAL( str::strToBoolNodefault("foo",   ret),  true );
232
233   ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("TRUE",  ret),  true );
234   ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("FALSE", ret),  false );
235   ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("",      ret),  false );
236   ret = false; BOOST_CHECK_EQUAL( str::strToBoolNodefault("foo",   ret),  false );
237 }
238
239 BOOST_AUTO_TEST_CASE(operations)
240 {
241     BOOST_CHECK_EQUAL(str::ltrim(" \t f \t ffo \t "), "f \t ffo \t ");
242     BOOST_CHECK_EQUAL(str::rtrim(" \t f \t ffo \t "), " \t f \t ffo");
243     BOOST_CHECK_EQUAL(str::trim(" \t f \t ffo \t "),  "f \t ffo");
244
245     // strip first
246     {
247         string tostrip(" Oh! la la ");
248         string word( str::stripFirstWord(tostrip, true) ); // ltrim first
249         BOOST_CHECK_EQUAL(word, "Oh!");
250         BOOST_CHECK_EQUAL(tostrip, "la la ");
251     }
252     {
253         string tostrip(" Oh! la la ");
254         string word( str::stripFirstWord(tostrip, false) ); // no ltrim first
255         BOOST_CHECK_EQUAL(word, "");
256         BOOST_CHECK_EQUAL(tostrip, "Oh! la la ");
257     }
258
259     // strip last
260     {
261         string tostrip(" Oh! la la ");
262         string word( str::stripLastWord(tostrip, true) ); // rtrim first
263         BOOST_CHECK_EQUAL(word, "la");
264         BOOST_CHECK_EQUAL(tostrip, " Oh! la");
265     }
266     {
267         string tostrip(" Oh! la la ");
268         string word( str::stripLastWord(tostrip, false) ); // no rtrim first
269         BOOST_CHECK_EQUAL(word, "");
270         BOOST_CHECK_EQUAL(tostrip, " Oh! la la");
271     }
272 }
273
274 BOOST_AUTO_TEST_CASE(prefix_suffix)
275 {
276   BOOST_CHECK( str::hasPrefix("abcXabcYabc", "abcX") );
277   BOOST_CHECK( str::hasSuffix("abcXabcYabc", "Yabc") );
278
279   BOOST_CHECK_EQUAL( str::stripPrefix("abcXabcYabc", "abcX"),  "abcYabc" );
280   BOOST_CHECK_EQUAL( str::stripSuffix("abcXabcYabc", "Yabc"),  "abcXabc" );
281
282   BOOST_CHECK( ! str::hasPrefix("abcXabcYabc", "ac") );
283   BOOST_CHECK( ! str::hasSuffix("abcXabcYabc", "ac") );
284
285   BOOST_CHECK_EQUAL( str::stripPrefix("abcXabcYabc", "ac"),  "abcXabcYabc" );
286   BOOST_CHECK_EQUAL( str::stripSuffix("abcXabcYabc", "ac"),  "abcXabcYabc" );
287
288   BOOST_CHECK( str::startsWith("abcXabcYabc", "abc") );
289   BOOST_CHECK( str::endsWith("abcXabcYabc", "abc") );
290
291   BOOST_CHECK( str::contains("abcXabcYabc", "XabcY") );
292   BOOST_CHECK( ! str::contains("abcXabcYabc", "xabcy") );
293   BOOST_CHECK( str::containsCI("abcXabcYabc", "xabcy") );
294
295   BOOST_CHECK_EQUAL( str::commonPrefix("", ""),         0 );
296   BOOST_CHECK_EQUAL( str::commonPrefix("a", ""),        0 );
297   BOOST_CHECK_EQUAL( str::commonPrefix("", "b"),        0 );
298   BOOST_CHECK_EQUAL( str::commonPrefix("a", "b"),       0 );
299   BOOST_CHECK_EQUAL( str::commonPrefix("c", "c"),       1 );
300   BOOST_CHECK_EQUAL( str::commonPrefix("ca", "cb"),     1 );
301 }
302
303 BOOST_AUTO_TEST_CASE(hexencode_hexdecode)
304 {
305   std::string o;
306   o.reserve( 256 );
307   for ( unsigned i = 1; i < 256; ++i )
308     o += i;
309
310   std::string e( str::hexencode( o ) );
311   // encoded contains nothing but [%a-zA-Z0-9]
312   for ( unsigned i = 0; i < 255; ++i )
313   {
314     char ch = e[i];
315     BOOST_CHECK( ch == '%'
316                  || ( 'a' <= ch && ch <= 'z' )
317                  || ( 'A' <= ch && ch <= 'Z' )
318                  || ( '0' <= ch && ch <= '9' ) );
319   }
320
321   std::string d( str::hexdecode( e ) );
322   // decoded equals original
323   BOOST_CHECK( o == d );
324
325   // Test %XX is decoded for hexdigits only
326   const char *const dig = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
327   for ( const char * d1 = dig; *d1; ++d1 )
328     for ( const char * d2 = dig; *d2; ++d2 )
329     {
330       std::string eu( "%" );
331       eu += *d1; eu += *d2;
332       std::string el( str::toLower(eu) );
333
334       std::string u( str::hexdecode( eu ) );
335       std::string l( str::hexdecode( el ) );
336
337       if ( *d1 <= 'F' &&  *d2 <= 'F' )
338       {
339         BOOST_CHECK_EQUAL( u, l );              // no matter if upper or lower case hexdigit
340         BOOST_CHECK_EQUAL( u.size(), 1 );       // size 1 == decoded
341       }
342       else
343       {
344         BOOST_CHECK_EQUAL( u, eu );             // no hexdigits remain unchanged
345         BOOST_CHECK_EQUAL( l, el );
346      }
347     }
348 }