add sanitize_for_logging() to stringfunc
[libi2ncommon] / test / stringfunc.cpp
1 /*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
13
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
16
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
19 */
20 /***************************************************************************
21  *   Copyright (C) 2006-2011 by Intra2net AG                               *
22  *                                                                         *
23  ***************************************************************************/
24
25 // #include <iostream>
26 #include <string>
27 // #include <sstream>
28 // #include <stdexcept>
29
30 #define BOOST_TEST_DYN_LINK
31 #include <boost/test/unit_test.hpp>
32
33 #include <stringfunc.hxx>
34 #include <containerfunc.hpp>
35
36 using namespace std;
37 using namespace I2n;
38
39 typedef std::list< std::string > StringList;
40
41 BOOST_AUTO_TEST_SUITE(stringfunc)
42
43 BOOST_AUTO_TEST_CASE(smart_html_entites1)
44 {
45     string output = smart_html_entities("Test");
46
47     BOOST_CHECK_EQUAL(string("Test"), output);
48 }
49
50 BOOST_AUTO_TEST_CASE(smart_html_entites2)
51 {
52     string output = smart_html_entities("Täst");
53
54     BOOST_CHECK_EQUAL(string("T&auml;st"), output);
55 }
56
57 BOOST_AUTO_TEST_CASE(smart_html_entites3)
58 {
59     string output = smart_html_entities("<>");
60
61     BOOST_CHECK_EQUAL(string("<>"), output);
62 }
63
64 BOOST_AUTO_TEST_CASE(smart_html_entites4)
65 {
66     string output = smart_html_entities("<ümlaut>");
67
68     BOOST_CHECK_EQUAL(string("<ümlaut>"), output);
69 }
70
71 BOOST_AUTO_TEST_CASE(smart_html_entites5)
72 {
73     string output = smart_html_entities("Test<ümlaut>Blä");
74
75     BOOST_CHECK_EQUAL(string("Test<ümlaut>Bl&auml;"), output);
76 }
77
78 BOOST_AUTO_TEST_CASE(smart_html_entites6)
79 {
80     string output = smart_html_entities("System > Einstellungen");
81
82     BOOST_CHECK_EQUAL(string("System &gt; Einstellungen"), output);
83 }
84
85 BOOST_AUTO_TEST_CASE(smart_html_entites7)
86 {
87     string output = smart_html_entities("Finden Sie <b>auf</b> der Seite <a href=\"fdslfsl\">\"System > Einstellungen\"</a>. Oder etwa nicht?");
88
89     BOOST_CHECK_EQUAL(string("Finden Sie <b>auf</b> der Seite <a href=\"fdslfsl\">&quot;System &gt; Einstellungen&quot;</a>. Oder etwa nicht?"), output);
90 }
91
92 BOOST_AUTO_TEST_CASE(strip_html_tags1)
93 {
94     string output = strip_html_tags("Was für ein schöner Tag, finden Sie nicht?");
95
96     BOOST_CHECK_EQUAL(string("Was für ein schöner Tag, finden Sie nicht?"), output);
97 }
98
99 BOOST_AUTO_TEST_CASE(strip_html_tags2)
100 {
101     string output = strip_html_tags("Was für ein <a href=\"wikipedia\" target=\"new\">schöner Tag</a>, finden Sie nicht?");
102
103     BOOST_CHECK_EQUAL(string("Was für ein schöner Tag, finden Sie nicht?"), output);
104 }
105
106
107
108 BOOST_AUTO_TEST_CASE(html_entities1)
109 {
110     string output = html_entities("\xC3\xA4\xC3\xB6\xC3\xBC");
111     BOOST_CHECK_EQUAL(string("&auml;&ouml;&uuml;"), output);
112 }
113
114 BOOST_AUTO_TEST_CASE(html_entities2)
115 {
116     string output = html_entities("\xC3\xA5 \xC3\xB5 \xC3\xBF");
117     BOOST_CHECK_EQUAL(string("&#229; &#245; &#255;"), output);
118 }
119
120 BOOST_AUTO_TEST_CASE(html_entities3)
121 {
122     string output = html_entities("\xC4\x8E \xE0\xBC\xB1 \xE8\x82\x88");
123     BOOST_CHECK_EQUAL(string("&#270; &#3889; &#32904;"), output);
124 }
125
126
127
128 BOOST_AUTO_TEST_CASE(nice_unit_format1)
129 {
130     const int64_t two_bytes = 2;
131
132     string output = nice_unit_format(two_bytes, LongUnitFormat, UnitBase1000);
133     BOOST_CHECK_EQUAL(string("2.00 Bytes"), output);
134
135     output = nice_unit_format(two_bytes);
136     BOOST_CHECK_EQUAL(string("2.0 B"), output);
137 }
138
139 BOOST_AUTO_TEST_CASE(nice_unit_format2)
140 {
141     const int64_t two_kilobytes = 2000;
142
143     string output = nice_unit_format(two_kilobytes, LongUnitFormat, UnitBase1000);
144     BOOST_CHECK_EQUAL(string("2.00 KBytes"), output);
145
146     output = nice_unit_format(two_kilobytes);
147     BOOST_CHECK_EQUAL(string("2.0 KB"), output);
148
149     const int64_t two_and_half_kilobytes = 2500;
150
151     output = nice_unit_format(two_and_half_kilobytes, LongUnitFormat, UnitBase1000);
152     BOOST_CHECK_EQUAL(string("2.50 KBytes"), output);
153
154     output = nice_unit_format(two_and_half_kilobytes);
155     BOOST_CHECK_EQUAL(string("2.4 KB"), output);
156 }
157
158 BOOST_AUTO_TEST_CASE(nice_unit_format3)
159 {
160     const int64_t two_megabytes = 2000000;
161
162     string output = nice_unit_format(two_megabytes, LongUnitFormat, UnitBase1000);
163     BOOST_CHECK_EQUAL(string("2.00 MBytes"), output);
164
165     output = nice_unit_format(two_megabytes);
166     BOOST_CHECK_EQUAL(string("1.9 MB"), output);
167
168     const int64_t two_and_half_megabytes = 2500000;
169
170     output = nice_unit_format(two_and_half_megabytes, LongUnitFormat, UnitBase1000);
171     BOOST_CHECK_EQUAL(string("2.50 MBytes"), output);
172
173     output = nice_unit_format(two_and_half_megabytes);
174     BOOST_CHECK_EQUAL(string("2.4 MB"), output);
175
176 }
177
178 BOOST_AUTO_TEST_CASE(nice_unit_format4)
179 {
180     const int64_t two_gigabytes = 2000000000LL;
181
182     string output = nice_unit_format(two_gigabytes, LongUnitFormat, UnitBase1000);
183     BOOST_CHECK_EQUAL(string("2.00 GBytes"), output);
184
185     output = nice_unit_format(two_gigabytes);
186     BOOST_CHECK_EQUAL(string("1.9 GB"), output);
187
188     const int64_t two_and_half_gigabytes = 2500000000LL;
189
190     output = nice_unit_format(two_and_half_gigabytes, LongUnitFormat, UnitBase1000);
191     BOOST_CHECK_EQUAL(string("2.50 GBytes"), output);
192
193     output = nice_unit_format(two_and_half_gigabytes);
194     BOOST_CHECK_EQUAL(string("2.3 GB"), output);
195 }
196
197 BOOST_AUTO_TEST_CASE(nice_unit_format5)
198 {
199     const int64_t two_terabytes = 2000000000000LL;
200
201     string output = nice_unit_format(two_terabytes, LongUnitFormat, UnitBase1000);
202     BOOST_CHECK_EQUAL(string("2.00 TBytes"), output);
203
204     output = nice_unit_format(two_terabytes);
205     BOOST_CHECK_EQUAL(string("1.8 TB"), output);
206
207     const int64_t two_and_half_terabytes = 2500000000000LL;
208
209     output = nice_unit_format(two_and_half_terabytes, LongUnitFormat, UnitBase1000);
210     BOOST_CHECK_EQUAL(string("2.50 TBytes"), output);
211
212     output = nice_unit_format(two_and_half_terabytes);
213     BOOST_CHECK_EQUAL(string("2.3 TB"), output);
214 }
215
216 BOOST_AUTO_TEST_CASE(nice_unit_format6)
217 {
218     const int64_t two_petabytes = 2000000000000000LL;
219
220     string output = nice_unit_format(two_petabytes, LongUnitFormat, UnitBase1000);
221     BOOST_CHECK_EQUAL(string("2.00 PBytes"), output);
222
223     output = nice_unit_format(two_petabytes);
224     BOOST_CHECK_EQUAL(string("1.8 PB"), output);
225
226     const int64_t two_and_half_petabytes = 2500000000000000LL;
227
228     output = nice_unit_format(two_and_half_petabytes, LongUnitFormat, UnitBase1000);
229     BOOST_CHECK_EQUAL(string("2.50 PBytes"), output);
230
231     output = nice_unit_format(two_and_half_petabytes);
232     BOOST_CHECK_EQUAL(string("2.2 PB"), output);
233 }
234
235 BOOST_AUTO_TEST_CASE(nice_unit_format7)
236 {
237     const int64_t two_exabytes = 2000000000000000000LL;
238
239     string output = nice_unit_format(two_exabytes, LongUnitFormat, UnitBase1000);
240     BOOST_CHECK_EQUAL(string("2000.00 PBytes"), output);
241
242     output = nice_unit_format(two_exabytes);
243     BOOST_CHECK_EQUAL(string("1776.4 PB"), output);
244
245     const int64_t two_and_half_exabytes = 2500000000000000000LL;
246
247     output = nice_unit_format(two_and_half_exabytes, LongUnitFormat, UnitBase1000);
248     BOOST_CHECK_EQUAL(string("2500.00 PBytes"), output);
249
250     output = nice_unit_format(two_and_half_exabytes);
251     BOOST_CHECK_EQUAL(string("2220.4 PB"), output);
252 }
253
254 BOOST_AUTO_TEST_CASE(nice_unit_format8)
255 {
256     const int64_t max_representable_64bits_number = 9223372036854775807LL;
257
258     string output = nice_unit_format(max_representable_64bits_number, LongUnitFormat, UnitBase1000);
259     BOOST_CHECK_EQUAL(string("9223.40 PBytes"), output);
260
261     output = nice_unit_format(max_representable_64bits_number);
262     BOOST_CHECK_EQUAL(string("8192.0 PB"), output);
263 }
264
265 BOOST_AUTO_TEST_CASE(TestTrim)
266 {
267     std::string s("s1");
268     trim_mod(s);
269     BOOST_CHECK_EQUAL( std::string("s1"), s );
270
271     s="  s2";
272     trim_mod(s);
273     BOOST_CHECK_EQUAL( std::string("s2"), s );
274
275     s="s3   ";
276     trim_mod(s);
277     BOOST_CHECK_EQUAL( std::string("s3"), s );
278
279     s="::s4:s4::++--aa";
280     trim_mod(s,":+-a");
281     BOOST_CHECK_EQUAL( std::string("s4:s4"), s);
282
283     /* non modifying version */
284
285     s= "s1";
286     BOOST_CHECK_EQUAL( std::string("s1"), trim(s) );
287
288     s="  s2";
289     BOOST_CHECK_EQUAL( std::string("s2"), trim(s) );
290     BOOST_CHECK_EQUAL( std::string("  s2"), s );
291
292     s="s3   ";
293     BOOST_CHECK_EQUAL( std::string("s3"), trim(s) );
294     BOOST_CHECK_EQUAL( std::string("s3   "), s );
295
296     s="::s4:s4::++--aa";
297     BOOST_CHECK_EQUAL( std::string("s4:s4"), trim(s,":+-a") );
298 } // eo TestTrim()
299
300
301
302 BOOST_AUTO_TEST_CASE(TestChomp)
303 {
304     std::string s("s1");
305
306     chomp_mod(s);
307     BOOST_CHECK_EQUAL( std::string("s1"), s );
308
309     s="s2\n";
310     chomp_mod(s);
311     BOOST_CHECK_EQUAL( std::string("s2"), s );
312
313     s="s3:";
314     chomp_mod(s,":");
315     BOOST_CHECK_EQUAL( std::string("s3"), s );
316
317     s=":s4::";
318     chomp_mod(s,"s:");
319     BOOST_CHECK_EQUAL( std::string(":s4:"), s);
320
321     /* non modifiying versions */
322     s= "s1";
323
324     BOOST_CHECK_EQUAL( std::string("s1"), chomp(s) );
325
326     s="s2\n";
327     BOOST_CHECK_EQUAL( std::string("s2"), chomp(s) );
328     BOOST_CHECK_EQUAL( std::string("s2\n"), s);
329
330     s="s3:";
331     BOOST_CHECK_EQUAL( std::string("s3"), chomp(s,":") );
332     BOOST_CHECK_EQUAL( std::string("s3:"), s);
333
334     s=":s4::";
335     BOOST_CHECK_EQUAL( std::string(":s4:"), chomp(s,"s:") );
336     BOOST_CHECK_EQUAL( std::string(":s4::"), s);
337 } // eo TestChomp()
338
339
340
341 BOOST_AUTO_TEST_CASE(TestSuffixFuncs)
342 {
343     std::string s1("12.cpp");
344
345     BOOST_CHECK_EQUAL( true, has_suffix(s1,".cpp") );
346     BOOST_CHECK_EQUAL( true, has_suffix(s1,"pp") );
347     BOOST_CHECK_EQUAL( false, has_suffix(s1,"hpp") );
348     BOOST_CHECK_EQUAL( false, has_suffix(s1,"cp") );
349     BOOST_CHECK_EQUAL( false, has_suffix(s1,"") );
350
351     std::string s1c1= remove_suffix(s1,".cpp");
352     BOOST_CHECK_EQUAL( std::string("12"), s1c1 );
353
354     std::string s1c2= remove_suffix(s1,"p");
355     BOOST_CHECK_EQUAL( std::string("12.cp"), s1c2 );
356
357     std::string s1c3= remove_suffix(s1,"cp");
358     BOOST_CHECK_EQUAL( std::string("12.cpp"), s1c3 );
359
360     std::string s2(".cpp");
361     BOOST_CHECK_EQUAL( true, has_suffix(s2,".cpp") );
362
363     std::string s2c1= remove_suffix(s2,".cpp");
364     BOOST_CHECK_EQUAL( std::string(""), s2c1 );
365
366 } // eo TestSuffixFuncs()
367
368
369
370 BOOST_AUTO_TEST_CASE(TestPrefixFuncs)
371 {
372     std::string s1("12.cpp");
373
374     BOOST_CHECK_EQUAL( true, has_prefix(s1,"12") );
375     BOOST_CHECK_EQUAL( true, has_prefix(s1, "1") );
376     BOOST_CHECK_EQUAL( false, has_prefix(s1, "2") );
377     BOOST_CHECK_EQUAL( false, has_prefix(s1, "") );
378
379     std::string s1c1= remove_prefix(s1, "12");
380     BOOST_CHECK_EQUAL( std::string(".cpp"), s1c1);
381 } // eo TestPrefixFuncs()
382
383
384
385 BOOST_AUTO_TEST_CASE(TestLowerUpperFuncs)
386 {
387     std::string u1("CASE CONVERSION TEST..");
388     std::string l1("case conversion test..");
389
390     std::string test1(l1);
391
392     to_upper_mod(test1);
393     BOOST_CHECK_EQUAL( u1, test1 );
394
395     to_lower_mod(test1);
396     BOOST_CHECK_EQUAL( l1, test1 );
397
398
399     BOOST_CHECK_EQUAL( u1, to_upper(l1) );
400     BOOST_CHECK_EQUAL( l1, to_lower(u1) );
401 } // eo TestLowerUpper
402
403
404
405 BOOST_AUTO_TEST_CASE(PairSplit1)
406 {
407     StringList str_list;
408     get_push_back_filler(str_list)
409         ("a=11")("a= 11")("a =11 ")("a =  11 ")("  a    =    11   ")
410     ;
411     BOOST_CHECK_EQUAL( 5u, str_list.size() );
412     for(StringList::iterator it= str_list.begin();
413         it != str_list.end();
414         ++it)
415     {
416         std::string key, value;
417         bool res= pair_split( *it, key, value);
418
419         BOOST_CHECK_EQUAL( true , res );
420         BOOST_CHECK_EQUAL( std::string("a"), key );
421         BOOST_CHECK_EQUAL( std::string("11"), value );
422     }
423
424     std::string key, value;
425     bool res;
426
427     res= pair_split(" 1 : 2 ", key, value, ':');
428     BOOST_CHECK_EQUAL( true, res );
429     BOOST_CHECK_EQUAL( std::string("1"), key);
430     BOOST_CHECK_EQUAL( std::string("2"), value);
431 } // eo PairSplit1
432
433
434
435 BOOST_AUTO_TEST_CASE(SplitString1)
436 {
437     std::string block(
438         "Zeile 1\n"
439         "++Zeile-2--\n"
440         "Zeile 3\n"
441         "\n"
442         "Zeile 5\n"
443     );
444
445     StringList list1;
446
447     split_string(block, list1, "\n");
448     // since the blocks ends with \n we should have 6 lines (the last one empty):
449     BOOST_CHECK_EQUAL( 6u, list1.size() );
450     BOOST_CHECK_EQUAL( std::string(), list1.back() );
451     BOOST_CHECK_EQUAL( std::string("Zeile 1"), list1.front() );
452
453     StringList list2;
454
455     split_string(block, list2, "\n", true);
456
457     // now we omitted empty lines, now we should have only 4 lines left:
458     BOOST_CHECK_EQUAL( 4u, list2.size() );
459     BOOST_CHECK_EQUAL( std::string("Zeile 5"), list2.back() );
460     BOOST_CHECK_EQUAL( std::string("Zeile 1"), list2.front() );
461
462     list2= split_string(block, "\n", true, "+-");
463
464     // again, we omitted empty lines, but also trimmed away leading and trailing "+" and "-"
465     BOOST_CHECK_EQUAL( 4u, list2.size() );
466     BOOST_CHECK_EQUAL( std::string("Zeile 5"), list2.back() );
467     BOOST_CHECK_EQUAL( std::string("Zeile 1"), list2.front() );
468     BOOST_CHECK_EQUAL( std::string("Zeile-2"), *(++list2.begin()) );
469 } // eo SplitString1
470
471
472
473 BOOST_AUTO_TEST_CASE(SplitString2)
474 {
475     std::string line("172.16.0.0/16 dev eth0  scope link  src 172.16.1.111");
476
477     StringList list1;
478
479     split_string(line, list1, " ", true, Whitespaces);
480
481     BOOST_CHECK_EQUAL( 7u, list1.size() );
482
483 } // eo SplitString2
484
485
486
487 BOOST_AUTO_TEST_CASE(SplitStringEmpty)
488 {
489     std::string line("");
490
491     StringList list1;
492
493     split_string(line, list1, " ", true, Whitespaces);
494
495     BOOST_CHECK_EQUAL( 0u, list1.size() );
496 } // eo SplitStringEmpty
497
498
499 BOOST_AUTO_TEST_CASE(SplitStringDelimiterOnly)
500 {
501     std::string line(" ");
502
503     StringList list1;
504
505     split_string(line, list1, " ", true, Whitespaces);
506
507     BOOST_CHECK_EQUAL( 0u, list1.size() );
508 } // eo SplitStringDelimiterOnly
509
510
511
512 BOOST_AUTO_TEST_CASE(JoinString1)
513 {
514     std::list< std::string > parts;
515     get_push_back_filler(parts)("1")("2")("drei");
516
517     std::string joined_string= join_string(parts,"/");
518     // we should have slashes between the strings:
519     BOOST_CHECK_EQUAL( std::string("1/2/drei") , joined_string );
520
521     parts.push_back( std::string() );
522     joined_string= join_string(parts,"/");
523     // now we should have an additional trailing slash:
524     BOOST_CHECK_EQUAL( std::string("1/2/drei/") , joined_string );
525
526     parts.push_front( std::string() );
527     joined_string= join_string(parts,"/");
528     // now we should have an additional leading slash:
529     BOOST_CHECK_EQUAL( std::string("/1/2/drei/") , joined_string );
530
531 } // eo JoinString1
532
533
534
535 BOOST_AUTO_TEST_CASE(ConversionStringInt)
536 {
537     std::string s1("24");
538     std::string s1x("25x");
539     int i1=0;
540     bool res= false;
541
542     i1= string_to<int>(s1);
543     BOOST_CHECK_EQUAL( 24, i1 );
544     i1= string_to<int>(s1x);
545     BOOST_CHECK_EQUAL( 25, i1 );
546
547     res= string_to<int>(s1,i1);
548     BOOST_CHECK_EQUAL( true, res );
549     BOOST_CHECK_EQUAL( 24, i1 );
550
551     res= string_to<int>(s1x,i1);
552     BOOST_CHECK_EQUAL( false, res );
553
554     std::string ss1= to_string( 24 );
555     BOOST_CHECK_EQUAL( std::string("24"), ss1);
556
557 } // eo ConversionStringInt()
558
559
560
561 BOOST_AUTO_TEST_CASE(HexConversion)
562 {
563     std::string hex1("49324E");
564     std::string bin1("I2N");
565
566     BOOST_CHECK_EQUAL( hex1, convert_binary_to_hex(bin1,true) );
567     BOOST_CHECK_EQUAL( bin1, convert_hex_to_binary(hex1) );
568     BOOST_CHECK_EQUAL( to_lower(hex1), convert_binary_to_hex(bin1) );
569
570     std::string hex2("0001");
571     std::string hex2a("00 01");
572     std::string hex2b("00:01");
573     std::string bin2("\0\1",2);
574
575     BOOST_CHECK_EQUAL( hex2, convert_binary_to_hex(bin2) );
576     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2) );
577     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2a) );
578     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2b) );
579
580     BOOST_REQUIRE_THROW( convert_hex_to_binary("01 kein hex"), std::runtime_error);
581 } // eo HexConversion()
582
583 BOOST_AUTO_TEST_CASE(sanitize_for_logging1)
584 {
585     string output = sanitize_for_logging("normaler string ohne aerger");
586
587     BOOST_CHECK_EQUAL(string("normaler string ohne aerger"), output);
588 }
589
590 BOOST_AUTO_TEST_CASE(sanitize_for_logging2)
591 {
592     string to_test="fiese";
593     to_test.push_back(0);
594     to_test+="null";
595
596     string output = sanitize_for_logging(to_test);
597
598     BOOST_CHECK_EQUAL(string("fiese?null"), output);
599 }
600
601 BOOST_AUTO_TEST_CASE(sanitize_for_logging3)
602 {
603     string output = sanitize_for_logging("läuter ümlaute utf8");
604
605     BOOST_CHECK_EQUAL(string("l??uter ??mlaute utf8"), output);
606 }
607
608 BOOST_AUTO_TEST_SUITE_END()