Merge branch 'daemon-ext'
[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 <cmath>
28 // #include <sstream>
29 // #include <stdexcept>
30
31 #define BOOST_TEST_DYN_LINK
32 #include <boost/test/unit_test.hpp>
33 #include <boost/foreach.hpp>
34 #include <boost/numeric/conversion/cast.hpp>
35
36 #include <stringfunc.hxx>
37 #include <containerfunc.hpp>
38 #include <iostream>
39 #include <stdint.h>
40
41 using namespace std;
42 using namespace I2n;
43
44 typedef std::list< std::string > StringList;
45
46 BOOST_AUTO_TEST_SUITE(stringfunc)
47
48 BOOST_AUTO_TEST_CASE(smart_html_entities1)
49 {
50     string output = smart_html_entities("Test");
51
52     BOOST_CHECK_EQUAL(string("Test"), output);
53 }
54
55 BOOST_AUTO_TEST_CASE(smart_html_entities2)
56 {
57     string output = smart_html_entities("Täst");
58
59     BOOST_CHECK_EQUAL(string("T&auml;st"), output);
60 }
61
62 BOOST_AUTO_TEST_CASE(smart_html_entities3)
63 {
64     string output = smart_html_entities("<>");
65
66     BOOST_CHECK_EQUAL(string("<>"), output);
67 }
68
69 BOOST_AUTO_TEST_CASE(smart_html_entities4)
70 {
71     string output = smart_html_entities("<ümlaut>");
72
73     BOOST_CHECK_EQUAL(string("<ümlaut>"), output);
74 }
75
76 BOOST_AUTO_TEST_CASE(smart_html_entities5)
77 {
78     string output = smart_html_entities("Test<ümlaut>Blä");
79
80     BOOST_CHECK_EQUAL(string("Test<ümlaut>Bl&auml;"), output);
81 }
82
83 BOOST_AUTO_TEST_CASE(smart_html_entities6)
84 {
85     string output = smart_html_entities("System > Einstellungen");
86
87     BOOST_CHECK_EQUAL(string("System &gt; Einstellungen"), output);
88 }
89
90 BOOST_AUTO_TEST_CASE(smart_html_entities7)
91 {
92     string output = smart_html_entities("Finden Sie <b>auf</b> der Seite <a href=\"fdslfsl\">\"System > Einstellungen\"</a>. Oder etwa nicht?");
93
94     BOOST_CHECK_EQUAL(string("Finden Sie <b>auf</b> der Seite <a href=\"fdslfsl\">&quot;System &gt; Einstellungen&quot;</a>. Oder etwa nicht?"), output);
95 }
96
97 BOOST_AUTO_TEST_CASE(strip_html_tags1)
98 {
99     string output = strip_html_tags("Was für ein schöner Tag, finden Sie nicht?");
100
101     BOOST_CHECK_EQUAL(string("Was für ein schöner Tag, finden Sie nicht?"), output);
102 }
103
104 BOOST_AUTO_TEST_CASE(strip_html_tags2)
105 {
106     string output = strip_html_tags("Was für ein <a href=\"wikipedia\" target=\"new\">schöner Tag</a>, finden Sie nicht?");
107
108     BOOST_CHECK_EQUAL(string("Was für ein schöner Tag, finden Sie nicht?"), output);
109 }
110
111
112
113 BOOST_AUTO_TEST_CASE(html_entities1)
114 {
115     string output = html_entities("\xC3\xA4\xC3\xB6\xC3\xBC");
116     BOOST_CHECK_EQUAL(string("&auml;&ouml;&uuml;"), output);
117 }
118
119 BOOST_AUTO_TEST_CASE(html_entities2)
120 {
121     string output = html_entities("\xC3\xA5 \xC3\xB5 \xC3\xBF");
122     BOOST_CHECK_EQUAL(string("&#229; &#245; &#255;"), output);
123 }
124
125 BOOST_AUTO_TEST_CASE(html_entities3)
126 {
127     string output = html_entities("\xC4\x8E \xE0\xBC\xB1 \xE8\x82\x88");
128     BOOST_CHECK_EQUAL(string("&#270; &#3889; &#32904;"), output);
129 }
130
131 BOOST_AUTO_TEST_CASE(entities_latin1)
132 {
133     BOOST_CHECK_EQUAL((std::string)"noop", html_entities_iso ("noop"));
134     BOOST_CHECK_EQUAL((std::string)"t&auml;st", html_entities_iso ("t\xe4st"));
135     BOOST_CHECK_EQUAL((std::string)"T&Auml;ST", html_entities_iso ("T\xc4ST"));
136 }
137
138
139 BOOST_AUTO_TEST_CASE(nice_unit_format1)
140 {
141     const int64_t two_bytes = 2;
142
143     string output = nice_unit_format(two_bytes, LongUnitFormat, UnitBase1000);
144     BOOST_CHECK_EQUAL(string("2.00 Bytes"), output);
145
146     output = nice_unit_format(two_bytes);
147     BOOST_CHECK_EQUAL(string("2.0 B"), output);
148 }
149
150 BOOST_AUTO_TEST_CASE(nice_unit_format2)
151 {
152     const int64_t two_kilobytes = 2000;
153
154     string output = nice_unit_format(two_kilobytes, LongUnitFormat, UnitBase1000);
155     BOOST_CHECK_EQUAL(string("2.00 KBytes"), output);
156
157     output = nice_unit_format(two_kilobytes);
158     BOOST_CHECK_EQUAL(string("2.0 KB"), output);
159
160     output = nice_unit_format(boost::numeric_cast<double>(two_kilobytes), LongUnitFormat, UnitBase1000);
161     BOOST_CHECK_EQUAL(string("2.00 KBytes"), output);
162
163     output = nice_unit_format(boost::numeric_cast<double>(two_kilobytes));
164     BOOST_CHECK_EQUAL(string("2.0 KB"), output);
165
166     const int64_t two_and_half_kilobytes = 2500;
167
168     output = nice_unit_format(two_and_half_kilobytes, LongUnitFormat, UnitBase1000);
169     BOOST_CHECK_EQUAL(string("2.50 KBytes"), output);
170
171     output = nice_unit_format(two_and_half_kilobytes);
172     BOOST_CHECK_EQUAL(string("2.4 KB"), output);
173
174     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_kilobytes), LongUnitFormat, UnitBase1000);
175     BOOST_CHECK_EQUAL(string("2.50 KBytes"), output);
176
177     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_kilobytes));
178     BOOST_CHECK_EQUAL(string("2.4 KB"), output);
179 }
180
181 BOOST_AUTO_TEST_CASE(nice_unit_format3)
182 {
183     const int64_t two_megabytes = 2000000;
184
185     string output = nice_unit_format(two_megabytes, LongUnitFormat, UnitBase1000);
186     BOOST_CHECK_EQUAL(string("2.00 MBytes"), output);
187
188     output = nice_unit_format(two_megabytes);
189     BOOST_CHECK_EQUAL(string("1.9 MB"), output);
190
191     output = nice_unit_format(boost::numeric_cast<double>(two_megabytes), LongUnitFormat, UnitBase1000);
192     BOOST_CHECK_EQUAL(string("2.00 MBytes"), output);
193
194     output = nice_unit_format(boost::numeric_cast<double>(two_megabytes));
195     BOOST_CHECK_EQUAL(string("1.9 MB"), output);
196
197     const int64_t two_and_half_megabytes = 2500000;
198
199     output = nice_unit_format(two_and_half_megabytes, LongUnitFormat, UnitBase1000);
200     BOOST_CHECK_EQUAL(string("2.50 MBytes"), output);
201
202     output = nice_unit_format(two_and_half_megabytes);
203     BOOST_CHECK_EQUAL(string("2.4 MB"), output);
204
205     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_megabytes), LongUnitFormat, UnitBase1000);
206     BOOST_CHECK_EQUAL(string("2.50 MBytes"), output);
207
208     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_megabytes));
209     BOOST_CHECK_EQUAL(string("2.4 MB"), output);
210
211 }
212
213 BOOST_AUTO_TEST_CASE(nice_unit_format4)
214 {
215     const int64_t two_gigabytes = 2000000000LL;
216
217     string output = nice_unit_format(two_gigabytes, LongUnitFormat, UnitBase1000);
218     BOOST_CHECK_EQUAL(string("2.00 GBytes"), output);
219
220     output = nice_unit_format(two_gigabytes);
221     BOOST_CHECK_EQUAL(string("1.9 GB"), output);
222
223     output = nice_unit_format(boost::numeric_cast<double>(two_gigabytes), LongUnitFormat, UnitBase1000);
224     BOOST_CHECK_EQUAL(string("2.00 GBytes"), output);
225
226     output = nice_unit_format(boost::numeric_cast<double>(two_gigabytes));
227     BOOST_CHECK_EQUAL(string("1.9 GB"), output);
228
229     const int64_t two_and_half_gigabytes = 2500000000LL;
230
231     output = nice_unit_format(two_and_half_gigabytes, LongUnitFormat, UnitBase1000);
232     BOOST_CHECK_EQUAL(string("2.50 GBytes"), output);
233
234     output = nice_unit_format(two_and_half_gigabytes);
235     BOOST_CHECK_EQUAL(string("2.3 GB"), output);
236
237     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_gigabytes), LongUnitFormat, UnitBase1000);
238     BOOST_CHECK_EQUAL(string("2.50 GBytes"), output);
239
240     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_gigabytes));
241     BOOST_CHECK_EQUAL(string("2.3 GB"), output);
242 }
243
244 BOOST_AUTO_TEST_CASE(nice_unit_format5)
245 {
246     const int64_t two_terabytes = 2000000000000LL;
247
248     string output = nice_unit_format(two_terabytes, LongUnitFormat, UnitBase1000);
249     BOOST_CHECK_EQUAL(string("2.00 TBytes"), output);
250
251     output = nice_unit_format(two_terabytes);
252     BOOST_CHECK_EQUAL(string("1.8 TB"), output);
253
254     output = nice_unit_format(boost::numeric_cast<double>(two_terabytes), LongUnitFormat, UnitBase1000);
255     BOOST_CHECK_EQUAL(string("2.00 TBytes"), output);
256
257     output = nice_unit_format(boost::numeric_cast<double>(two_terabytes));
258     BOOST_CHECK_EQUAL(string("1.8 TB"), output);
259
260     const int64_t two_and_half_terabytes = 2500000000000LL;
261
262     output = nice_unit_format(two_and_half_terabytes, LongUnitFormat, UnitBase1000);
263     BOOST_CHECK_EQUAL(string("2.50 TBytes"), output);
264
265     output = nice_unit_format(two_and_half_terabytes);
266     BOOST_CHECK_EQUAL(string("2.3 TB"), output);
267
268     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_terabytes), LongUnitFormat, UnitBase1000);
269     BOOST_CHECK_EQUAL(string("2.50 TBytes"), output);
270
271     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_terabytes));
272     BOOST_CHECK_EQUAL(string("2.3 TB"), output);
273 }
274
275 BOOST_AUTO_TEST_CASE(nice_unit_format6)
276 {
277     const int64_t two_petabytes = 2000000000000000LL;
278
279     string output = nice_unit_format(two_petabytes, LongUnitFormat, UnitBase1000);
280     BOOST_CHECK_EQUAL(string("2.00 PBytes"), output);
281
282     output = nice_unit_format(two_petabytes);
283     BOOST_CHECK_EQUAL(string("1.8 PB"), output);
284
285     output = nice_unit_format(boost::numeric_cast<double>(two_petabytes), LongUnitFormat, UnitBase1000);
286     BOOST_CHECK_EQUAL(string("2.00 PBytes"), output);
287
288     output = nice_unit_format(boost::numeric_cast<double>(two_petabytes));
289     BOOST_CHECK_EQUAL(string("1.8 PB"), output);
290
291     const int64_t two_and_half_petabytes = 2500000000000000LL;
292
293     output = nice_unit_format(two_and_half_petabytes, LongUnitFormat, UnitBase1000);
294     BOOST_CHECK_EQUAL(string("2.50 PBytes"), output);
295
296     output = nice_unit_format(two_and_half_petabytes);
297     BOOST_CHECK_EQUAL(string("2.2 PB"), output);
298
299     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_petabytes), LongUnitFormat, UnitBase1000);
300     BOOST_CHECK_EQUAL(string("2.50 PBytes"), output);
301
302     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_petabytes));
303     BOOST_CHECK_EQUAL(string("2.2 PB"), output);
304 }
305
306 BOOST_AUTO_TEST_CASE(nice_unit_format7)
307 {
308     const int64_t two_exabytes = 2000000000000000000LL;
309
310     string output = nice_unit_format(two_exabytes, LongUnitFormat, UnitBase1000);
311     BOOST_CHECK_EQUAL(string("2000.00 PBytes"), output);
312
313     output = nice_unit_format(two_exabytes);
314     BOOST_CHECK_EQUAL(string("1776.4 PB"), output);
315
316     output = nice_unit_format(boost::numeric_cast<double>(two_exabytes), LongUnitFormat, UnitBase1000);
317     BOOST_CHECK_EQUAL(string("2000.00 PBytes"), output);
318
319     output = nice_unit_format(boost::numeric_cast<double>(two_exabytes));
320     BOOST_CHECK_EQUAL(string("1776.4 PB"), output);
321
322     const int64_t two_and_half_exabytes = 2500000000000000000LL;
323
324     output = nice_unit_format(two_and_half_exabytes, LongUnitFormat, UnitBase1000);
325     BOOST_CHECK_EQUAL(string("2500.00 PBytes"), output);
326
327     output = nice_unit_format(two_and_half_exabytes);
328     BOOST_CHECK_EQUAL(string("2220.4 PB"), output);
329
330     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_exabytes), LongUnitFormat, UnitBase1000);
331     BOOST_CHECK_EQUAL(string("2500.00 PBytes"), output);
332
333     output = nice_unit_format(boost::numeric_cast<double>(two_and_half_exabytes));
334     BOOST_CHECK_EQUAL(string("2220.4 PB"), output);
335 }
336
337 BOOST_AUTO_TEST_CASE(nice_unit_format8)
338 {
339     const int64_t max_representable_64bits_number = 9223372036854775807LL;
340
341     string output = nice_unit_format(max_representable_64bits_number, LongUnitFormat, UnitBase1000);
342     BOOST_CHECK_EQUAL(string("9223.40 PBytes"), output);
343
344     output = nice_unit_format(max_representable_64bits_number);
345     BOOST_CHECK_EQUAL(string("8192.0 PB"), output);
346
347     /*
348     double val = boost::numeric_cast<double>(max_representable_64bits_number);
349     BOOST_MESSAGE("val as int64 is " << max_representable_64bits_number << " and as double is " << val);
350     BOOST_MESSAGE("val rounded is " << round(val));
351     BOOST_CHECK_EQUAL(val, round(val));
352     BOOST_MESSAGE("half as int64 is " << boost::numeric_cast<int64_t>(round(val/2)));   // ok
353     BOOST_MESSAGE("cast back is " << boost::numeric_cast<int64_t>(round(val)));  // throws a positive overflow
354     output = nice_unit_format(boost::numeric_cast<double>(max_representable_64bits_number), LongUnitFormat, UnitBase1000);
355     BOOST_CHECK_EQUAL(string("9223.40 PBytes"), output);
356
357     output = nice_unit_format(boost::numeric_cast<double>(max_representable_64bits_number));
358     BOOST_CHECK_EQUAL(string("8192.0 PB"), output);
359     */
360 }
361
362 BOOST_AUTO_TEST_CASE(TestTrim)
363 {
364     std::string s("s1");
365     trim_mod(s);
366     BOOST_CHECK_EQUAL( std::string("s1"), s );
367
368     s="  s2";
369     trim_mod(s);
370     BOOST_CHECK_EQUAL( std::string("s2"), s );
371
372     s="s3   ";
373     trim_mod(s);
374     BOOST_CHECK_EQUAL( std::string("s3"), s );
375
376     s="::s4:s4::++--aa";
377     trim_mod(s,":+-a");
378     BOOST_CHECK_EQUAL( std::string("s4:s4"), s);
379
380     /* non modifying version */
381
382     s= "s1";
383     BOOST_CHECK_EQUAL( std::string("s1"), trim(s) );
384
385     s="  s2";
386     BOOST_CHECK_EQUAL( std::string("s2"), trim(s) );
387     BOOST_CHECK_EQUAL( std::string("  s2"), s );
388
389     s="s3   ";
390     BOOST_CHECK_EQUAL( std::string("s3"), trim(s) );
391     BOOST_CHECK_EQUAL( std::string("s3   "), s );
392
393     s="::s4:s4::++--aa";
394     BOOST_CHECK_EQUAL( std::string("s4:s4"), trim(s,":+-a") );
395 } // eo TestTrim()
396
397
398
399 BOOST_AUTO_TEST_CASE(TestChomp)
400 {
401     std::string s("s1");
402
403     chomp_mod(s);
404     BOOST_CHECK_EQUAL( std::string("s1"), s );
405
406     s="s2\n";
407     chomp_mod(s);
408     BOOST_CHECK_EQUAL( std::string("s2"), s );
409
410     s="s3:";
411     chomp_mod(s,":");
412     BOOST_CHECK_EQUAL( std::string("s3"), s );
413
414     s=":s4::";
415     chomp_mod(s,"s:");
416     BOOST_CHECK_EQUAL( std::string(":s4:"), s);
417
418     /* non modifiying versions */
419     s= "s1";
420
421     BOOST_CHECK_EQUAL( std::string("s1"), chomp(s) );
422
423     s="s2\n";
424     BOOST_CHECK_EQUAL( std::string("s2"), chomp(s) );
425     BOOST_CHECK_EQUAL( std::string("s2\n"), s);
426
427     s="s3:";
428     BOOST_CHECK_EQUAL( std::string("s3"), chomp(s,":") );
429     BOOST_CHECK_EQUAL( std::string("s3:"), s);
430
431     s=":s4::";
432     BOOST_CHECK_EQUAL( std::string(":s4:"), chomp(s,"s:") );
433     BOOST_CHECK_EQUAL( std::string(":s4::"), s);
434 } // eo TestChomp()
435
436
437
438 BOOST_AUTO_TEST_CASE(TestSuffixFuncs)
439 {
440     std::string s1("12.cpp");
441
442     BOOST_CHECK_EQUAL( true, has_suffix(s1,".cpp") );
443     BOOST_CHECK_EQUAL( true, has_suffix(s1,"pp") );
444     BOOST_CHECK_EQUAL( false, has_suffix(s1,"hpp") );
445     BOOST_CHECK_EQUAL( false, has_suffix(s1,"cp") );
446     BOOST_CHECK_EQUAL( false, has_suffix(s1,"") );
447
448     std::string s1c1= remove_suffix(s1,".cpp");
449     BOOST_CHECK_EQUAL( std::string("12"), s1c1 );
450
451     std::string s1c2= remove_suffix(s1,"p");
452     BOOST_CHECK_EQUAL( std::string("12.cp"), s1c2 );
453
454     std::string s1c3= remove_suffix(s1,"cp");
455     BOOST_CHECK_EQUAL( std::string("12.cpp"), s1c3 );
456
457     std::string s2(".cpp");
458     BOOST_CHECK_EQUAL( true, has_suffix(s2,".cpp") );
459
460     std::string s2c1= remove_suffix(s2,".cpp");
461     BOOST_CHECK_EQUAL( std::string(""), s2c1 );
462
463 } // eo TestSuffixFuncs()
464
465
466
467 BOOST_AUTO_TEST_CASE(TestPrefixFuncs)
468 {
469     std::string s1("12.cpp");
470
471     BOOST_CHECK_EQUAL( true, has_prefix(s1,"12") );
472     BOOST_CHECK_EQUAL( true, has_prefix(s1, "1") );
473     BOOST_CHECK_EQUAL( false, has_prefix(s1, "2") );
474     BOOST_CHECK_EQUAL( false, has_prefix(s1, "") );
475
476     std::string s1c1= remove_prefix(s1, "12");
477     BOOST_CHECK_EQUAL( std::string(".cpp"), s1c1);
478 } // eo TestPrefixFuncs()
479
480
481
482 BOOST_AUTO_TEST_CASE(TestLowerUpperFuncs)
483 {
484     std::string u1("CASE CONVERSION TEST..");
485     std::string l1("case conversion test..");
486
487     std::string test1(l1);
488
489     to_upper_mod(test1);
490     BOOST_CHECK_EQUAL( u1, test1 );
491
492     to_lower_mod(test1);
493     BOOST_CHECK_EQUAL( l1, test1 );
494
495
496     BOOST_CHECK_EQUAL( u1, to_upper(l1) );
497     BOOST_CHECK_EQUAL( l1, to_lower(u1) );
498 } // eo TestLowerUpper
499
500
501
502 BOOST_AUTO_TEST_CASE(PairSplit1)
503 {
504     StringList str_list;
505     get_push_back_filler(str_list)
506         ("a=11")("a= 11")("a =11 ")("a =  11 ")("  a    =    11   ")
507     ;
508     BOOST_CHECK_EQUAL( 5u, str_list.size() );
509     for(StringList::iterator it= str_list.begin();
510         it != str_list.end();
511         ++it)
512     {
513         std::string key, value;
514         bool res= pair_split( *it, key, value);
515
516         BOOST_CHECK_EQUAL( true , res );
517         BOOST_CHECK_EQUAL( std::string("a"), key );
518         BOOST_CHECK_EQUAL( std::string("11"), value );
519     }
520
521     std::string key, value;
522     bool res;
523
524     res= pair_split(" 1 : 2 ", key, value, ':');
525     BOOST_CHECK_EQUAL( true, res );
526     BOOST_CHECK_EQUAL( std::string("1"), key);
527     BOOST_CHECK_EQUAL( std::string("2"), value);
528 } // eo PairSplit1
529
530
531
532 BOOST_AUTO_TEST_CASE(SplitString1)
533 {
534     std::string block(
535         "Zeile 1\n"
536         "++Zeile-2--\n"
537         "Zeile 3\n"
538         "\n"
539         "Zeile 5\n"
540     );
541
542     StringList list1;
543
544     split_string(block, list1, "\n");
545     // since the blocks ends with \n we should have 6 lines (the last one empty):
546     BOOST_CHECK_EQUAL( 6u, list1.size() );
547     BOOST_CHECK_EQUAL( std::string(), list1.back() );
548     BOOST_CHECK_EQUAL( std::string("Zeile 1"), list1.front() );
549
550     StringList list2;
551
552     split_string(block, list2, "\n", true);
553
554     // now we omitted empty lines, now we should have only 4 lines left:
555     BOOST_CHECK_EQUAL( 4u, list2.size() );
556     BOOST_CHECK_EQUAL( std::string("Zeile 5"), list2.back() );
557     BOOST_CHECK_EQUAL( std::string("Zeile 1"), list2.front() );
558
559     list2= split_string(block, "\n", true, "+-");
560
561     // again, we omitted empty lines, but also trimmed away leading and trailing "+" and "-"
562     BOOST_CHECK_EQUAL( 4u, list2.size() );
563     BOOST_CHECK_EQUAL( std::string("Zeile 5"), list2.back() );
564     BOOST_CHECK_EQUAL( std::string("Zeile 1"), list2.front() );
565     BOOST_CHECK_EQUAL( std::string("Zeile-2"), *(++list2.begin()) );
566 } // eo SplitString1
567
568
569
570 BOOST_AUTO_TEST_CASE(SplitString2)
571 {
572     std::string line("172.16.0.0/16 dev eth0  scope link  src 172.16.1.111");
573
574     StringList list1;
575
576     split_string(line, list1, " ", true, Whitespaces);
577
578     BOOST_CHECK_EQUAL( 7u, list1.size() );
579
580 } // eo SplitString2
581
582
583
584 BOOST_AUTO_TEST_CASE(SplitStringEmpty)
585 {
586     std::string line("");
587
588     StringList list1;
589
590     split_string(line, list1, " ", true, Whitespaces);
591
592     BOOST_CHECK_EQUAL( 0u, list1.size() );
593 } // eo SplitStringEmpty
594
595
596 BOOST_AUTO_TEST_CASE(SplitStringDelimiterOnly)
597 {
598     std::string line(" ");
599
600     StringList list1;
601
602     split_string(line, list1, " ", true, Whitespaces);
603
604     BOOST_CHECK_EQUAL( 0u, list1.size() );
605 } // eo SplitStringDelimiterOnly
606
607
608 BOOST_AUTO_TEST_CASE(SplitToVector)
609 {
610     std::string line("0;1;2;3;4;5;6;7;8;9");
611     std::vector<std::string> result;
612     split_string(line, result, ";");
613     BOOST_REQUIRE_EQUAL(result.size(), 10);
614     BOOST_CHECK_EQUAL(result[0], "0");
615     BOOST_CHECK_EQUAL(result[4], "4");
616     BOOST_CHECK_EQUAL(result[9], "9");
617 }
618
619
620 BOOST_AUTO_TEST_CASE(JoinString1)
621 {
622     std::list< std::string > parts;
623     std::string joined_string= join_string(parts,"/");
624     BOOST_CHECK_EQUAL( std::string("") , joined_string );
625
626     parts.push_back ("1");
627     joined_string= join_string(parts,"/");
628     // we should have slashes between the strings:
629     BOOST_CHECK_EQUAL( std::string("1") , joined_string );
630
631     get_push_back_filler(parts)("2")("drei");
632
633     joined_string= join_string(parts,"/");
634     // we should have slashes between the strings:
635     BOOST_CHECK_EQUAL( std::string("1/2/drei") , joined_string );
636
637     parts.push_back( std::string() );
638     joined_string= join_string(parts,"/");
639     // now we should have an additional trailing slash:
640     BOOST_CHECK_EQUAL( std::string("1/2/drei/") , joined_string );
641
642     parts.push_front( std::string() );
643     joined_string= join_string(parts,"/");
644     // now we should have an additional leading slash:
645     BOOST_CHECK_EQUAL( std::string("/1/2/drei/") , joined_string );
646
647 } // eo JoinString1
648
649
650 BOOST_AUTO_TEST_CASE(JoinStringVector)
651 {
652     std::vector< std::string > parts;
653     get_push_back_filler(parts)("1")("2")("drei");
654
655     std::string joined_string= join_string(parts,"/");
656     // we should have slashes between the strings:
657     BOOST_CHECK_EQUAL( std::string("1/2/drei") , joined_string );
658
659     parts.push_back( std::string() );
660     joined_string= join_string(parts,"/");
661     // now we should have an additional trailing slash:
662     BOOST_CHECK_EQUAL( std::string("1/2/drei/") , joined_string );
663
664     parts.insert(parts.begin(), "");
665     joined_string= join_string(parts,"/");
666     // now we should have an additional leading slash:
667     BOOST_CHECK_EQUAL( std::string("/1/2/drei/") , joined_string );
668
669 } // eo JoinStringVector
670
671
672 BOOST_AUTO_TEST_CASE(JoinStringSet)
673 {
674     std::set< std::string > parts;
675
676     std::string joined_string= join_string(parts,"/");
677     BOOST_CHECK_EQUAL( std::string() , joined_string );
678
679     parts.insert ("foo");
680     joined_string= join_string(parts,"/");
681     BOOST_CHECK_EQUAL( std::string("foo") , joined_string );
682
683     parts.insert ("bar");
684     parts.insert ("baz");
685
686     joined_string= join_string(parts,"/");
687     // we should have slashes between the strings:
688     BOOST_CHECK_EQUAL( std::string("bar/baz/foo") , joined_string );
689
690     parts.insert( std::string() );
691     joined_string= join_string(parts,"/");
692     // now we should have an additional trailing slash:
693     BOOST_CHECK_EQUAL( std::string("/bar/baz/foo") , joined_string );
694 } // eo JoinStringSet
695
696
697 BOOST_AUTO_TEST_CASE(JoinStringIterSet_Empty)
698 {
699     std::set< std::string > parts;
700
701     // empty sequence → empty string
702     BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end ()     ), "");
703     BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end (), "/"), "");
704 } // eo JoinStringSet
705
706 BOOST_AUTO_TEST_CASE(JoinStringIterSet_One)
707 {
708     std::set< std::string > parts;
709
710     parts.insert ("foo");
711
712     // cardinality == 1 → no delimiter
713     BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end ()     ), "foo");
714     BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end (), "/"), "foo");
715 } // eo JoinStringSet
716
717 BOOST_AUTO_TEST_CASE(JoinStringIterSet)
718 {
719     std::set< std::string > parts;
720
721     parts.insert ("foo");
722     parts.insert ("bar");
723     parts.insert ("baz");
724
725     std::string joined_string= join_string(parts.begin (), parts.end (), "/");
726     // we should have slashes between the strings:
727     BOOST_CHECK_EQUAL( std::string("bar/baz/foo") , joined_string );
728
729     parts.insert( std::string() );
730     joined_string= join_string(parts.begin (), parts.end (),"/");
731     // now we should have an additional trailing slash:
732     BOOST_CHECK_EQUAL( std::string("/bar/baz/foo") , joined_string );
733 } // eo JoinStringSet
734
735
736 BOOST_AUTO_TEST_CASE(JoinStringIterSet_Default)
737 {   /* default delimiter is newline */
738     std::set< std::string > parts;
739
740     parts.insert ("foo");
741     parts.insert ("bar");
742     parts.insert ("baz");
743
744     BOOST_CHECK_EQUAL(join_string (parts.begin (), parts.end ()), "bar\nbaz\nfoo");
745     BOOST_CHECK_EQUAL(join_string (parts                       ), "bar\nbaz\nfoo");
746
747 } // eo JoinStringSet
748
749
750 BOOST_AUTO_TEST_CASE(JoinStringArray_Empty)
751 {
752     const char *const parts [] = { NULL };
753
754     BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [0], "/"), "");
755     BOOST_CHECK_EQUAL(join_string(parts                 , "/"), "");
756
757     BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [0]), "");
758     BOOST_CHECK_EQUAL(join_string(parts                 ), "");
759
760 } // eo JoinStringSet
761
762 BOOST_AUTO_TEST_CASE(JoinStringArray_One)
763 {
764     const char *const parts [] = { "one", NULL };
765
766     BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [1], "/"), "one");
767     BOOST_CHECK_EQUAL(join_string(parts                 , "/"), "one");
768
769     BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [1]), "one");
770     BOOST_CHECK_EQUAL(join_string(parts                 ), "one");
771
772 } // eo JoinStringSet
773
774 BOOST_AUTO_TEST_CASE(JoinStringArray_Many)
775 {
776     const char *const parts [5] = { "one", "two", "three", "many", NULL };
777
778     BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [4], "/"), "one/two/three/many");
779     BOOST_CHECK_EQUAL(join_string(parts                 , "/"), "one/two/three/many");
780
781     BOOST_CHECK_EQUAL(join_string(&parts [0], &parts [4]), "one\ntwo\nthree\nmany");
782     BOOST_CHECK_EQUAL(join_string(parts                 ), "one\ntwo\nthree\nmany");
783
784 } // eo JoinStringSet
785
786
787 BOOST_AUTO_TEST_CASE(ConversionStringInt)
788 {
789     std::string s1("24");
790     std::string s1x("25x");
791     int i1=0;
792     bool res= false;
793
794     i1= string_to<int>(s1);
795     BOOST_CHECK_EQUAL( 24, i1 );
796     i1= string_to<int>(s1x);
797     BOOST_CHECK_EQUAL( 25, i1 );
798
799     res= string_to<int>(s1,i1);
800     BOOST_CHECK_EQUAL( true, res );
801     BOOST_CHECK_EQUAL( 24, i1 );
802
803     res= string_to<int>(s1x,i1);
804     BOOST_CHECK_EQUAL( false, res );
805
806     std::string ss1= to_string( 24 );
807     BOOST_CHECK_EQUAL( std::string("24"), ss1);
808
809 } // eo ConversionStringInt()
810
811
812
813 BOOST_AUTO_TEST_CASE(HexBinaryConversion)
814 {
815     std::string hex1("49324E");
816     std::string bin1("I2N");
817
818     BOOST_CHECK_EQUAL( hex1, convert_binary_to_hex(bin1,true) );
819     BOOST_CHECK_EQUAL( bin1, convert_hex_to_binary(hex1) );
820     BOOST_CHECK_EQUAL( to_lower(hex1), convert_binary_to_hex(bin1) );
821
822     std::string hex2("0001");
823     std::string hex2a("00 01");
824     std::string hex2b("00:01");
825     std::string bin2("\0\1",2);
826
827     BOOST_CHECK_EQUAL( hex2, convert_binary_to_hex(bin2) );
828     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2) );
829     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2a) );
830     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2b) );
831
832     BOOST_REQUIRE_THROW( convert_hex_to_binary("01 kein hex"), std::runtime_error);
833 } // eo HexConversion()
834
835 BOOST_AUTO_TEST_CASE(HexIntConversion)
836 {
837     BOOST_CHECK_EQUAL( 255 , hex_string_to<uint32_t>("ff") );
838     BOOST_CHECK_EQUAL( 18866985 , hex_string_to<uint32_t>("11FE329") );
839     BOOST_CHECK_EQUAL( 44 , hex_string_to<uint32_t>("0x2C") );
840 }
841
842 BOOST_AUTO_TEST_CASE(sanitize_for_logging1)
843 {
844     string output = sanitize_for_logging("normaler string ohne aerger");
845
846     BOOST_CHECK_EQUAL(string("normaler string ohne aerger"), output);
847 }
848
849 BOOST_AUTO_TEST_CASE(sanitize_for_logging2)
850 {
851     string to_test="fiese";
852     to_test.push_back(0);
853     to_test+="null";
854
855     string output = sanitize_for_logging(to_test);
856
857     BOOST_CHECK_EQUAL(string("fiese?null"), output);
858 }
859
860 BOOST_AUTO_TEST_CASE(sanitize_for_logging3)
861 {
862     string output = sanitize_for_logging("läuter ümlaute utf8");
863
864     BOOST_CHECK_EQUAL(string("l??uter ??mlaute utf8"), output);
865 }
866
867 BOOST_AUTO_TEST_CASE(find_html_comments_test)
868 {
869     string text = "bla-->"  // ==> (npos, 6)
870                //  0     6
871                   "bla<!--bla<!--bla-->bla-->"  // ==> (16, 26), (9, 32)
872                //  6  9     16        26     32
873                   "bla<!--bla-->"  // ==> (35, 45)
874                // 32 35        45
875                   "--><!----><!--"    // ==> (npos, 48), (48, 55), (55, npos)
876                // 45 48      55 59
877                   "bla<!--bla-->";  // ==> (62, 72)
878                // 59 62        72
879     BOOST_REQUIRE_EQUAL(text.length(), 72);
880     vector<CommentZone> expect;
881     expect.push_back(CommentZone(string::npos, 6));
882     expect.push_back(CommentZone(16, 26));
883     expect.push_back(CommentZone( 9, 32));
884     expect.push_back(CommentZone(35, 45));
885     expect.push_back(CommentZone(string::npos, 48));
886     expect.push_back(CommentZone(48, 55));
887     expect.push_back(CommentZone(55, string::npos));
888     expect.push_back(CommentZone(62, 72));
889     vector<CommentZone> result = find_html_comments(text);
890     //BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(),   not working, requires ...
891     //                              expect.begin(), expect.end());  ... operator<<(CommentZone)
892     BOOST_CHECK_EQUAL(result.size(), expect.size());
893     BOOST_FOREACH(const CommentZone &comment, expect)
894         BOOST_CHECK_MESSAGE(find(result.begin(), result.end(), comment) != result.end(),
895                             "Find (" << comment.first << "-" << comment.second << ")");
896 }
897
898 BOOST_AUTO_TEST_CASE(remove_html_comments_test)
899 {
900     const string original = "First line outside\n"
901                             "text <!--FOO\n"
902                             "Inside foo\n"
903                             "<!--BAR\n"
904                             "foo bar, what a surprise.\n"
905                             "<!-- short tag-less comment -->\n"
906                             " Html cannot handle this, thinks that FOO ended above\n"
907                             "BAR-->\n"
908                             "This, neither. No nested comments\n"
909                             "some text <!--BAZ more text\n"
910                             "Aaarggh!"
911                             "more text BAZ--> even more\n"
912                             "FOO--> text\n"
913                             "second line outside\n"
914                             "<!-- second comment -->";
915     string text = original;
916     string expect = "First line outside\n"
917                     "text  text\n"
918                     "second line outside\n";
919     remove_html_comments(text);
920     BOOST_CHECK_EQUAL(text, expect);
921     remove_html_comments(text);   // should not have any effect
922     BOOST_CHECK_EQUAL(text, expect);
923
924     text = string("test<!--") + original;
925     remove_html_comments(text);
926     BOOST_CHECK_EQUAL(text, "test");
927
928     text = original + "-->test";
929     remove_html_comments(text);
930     BOOST_CHECK_EQUAL(text, "test");
931 }
932
933 BOOST_AUTO_TEST_CASE(shorten_stl_types_string)
934 {
935     BOOST_CHECK_EQUAL(shorten_stl_types("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
936                       "std::string");
937 }
938
939 BOOST_AUTO_TEST_CASE(shorten_stl_types_simple)
940 {
941     BOOST_CHECK_EQUAL(shorten_stl_types("std::list<some_type, std::allocator<some_type> >"),
942                       "std::list<some_type, _alloc_>");
943 }
944
945 BOOST_AUTO_TEST_CASE(shorten_stl_types_multiple)
946 {
947     BOOST_CHECK_EQUAL(shorten_stl_types("std::basic_string<char, std::char_traits<char>, std::allocator<char> > my_func(std::list<some_type, std::allocator<some_type> >, std::vector<int, std::allocator<int> >)"),
948                       "std::string my_func(std::list<some_type, _alloc_>, std::vector<int, _alloc_>)");
949 }
950
951 BOOST_AUTO_TEST_CASE(shorten_stl_types_complex)
952 {
953     BOOST_CHECK_EQUAL(shorten_stl_types("std::list<boost::shared_ptr<some_type>, std::allocator<boost::shared_ptr<some_type> > >"),
954                       "std::list<boost::shared_ptr<some_type>, _alloc_>");
955 }
956
957 BOOST_AUTO_TEST_CASE(shorten_stl_types_nested)
958 {
959               //"std::list<int, std::allocator<int> >"
960     //"std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > >"
961     BOOST_CHECK_EQUAL(shorten_stl_types("std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > >"),
962                       "std::list<std::list<int, _alloc_>, _alloc_>");
963 }
964
965 BOOST_AUTO_TEST_CASE(shorten_stl_types_nothing)
966 {
967     string text = "";
968     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
969     text = "int f(void)";
970     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
971     text = "std::cout << \"Test\" << std::endl;";
972     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
973     text = "bla<blubb>";
974     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
975     text = "std::list<> is a class template";
976     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
977     text = "std::list<int, std::allocator<int>\n>";
978     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
979 }
980
981 BOOST_AUTO_TEST_CASE(base64_encode_decode)
982 {
983     string text = "Hello World\n";
984
985     string encoded = base64_encode(text);
986
987     BOOST_CHECK_EQUAL("SGVsbG8gV29ybGQK", encoded);
988     BOOST_CHECK_EQUAL(text, base64_decode(encoded));
989 }
990
991 BOOST_AUTO_TEST_CASE(base64_empty_string)
992 {
993     string text = "";
994     string encoded = base64_encode(text);
995
996     BOOST_CHECK_EQUAL("", encoded);
997     BOOST_CHECK_EQUAL(text, base64_decode(encoded));
998 }
999
1000 BOOST_AUTO_TEST_CASE(base64_large_string_with_zero)
1001 {
1002     // 10 MB data
1003     int data_size = 1024 * 1024 * 10;
1004
1005     string large_binary_data(data_size, 0);
1006     BOOST_CHECK_EQUAL(data_size, large_binary_data.size());
1007
1008     string encoded = base64_encode(large_binary_data);
1009
1010     string decoded = base64_decode(encoded);
1011     BOOST_CHECK_EQUAL(large_binary_data, decoded);
1012 }
1013
1014 BOOST_AUTO_TEST_CASE(base64_large_string_with_zero_encode_linefeeds)
1015 {
1016     // 10 MB data
1017     int data_size = 1024 * 1024 * 10;
1018
1019     string large_binary_data(data_size, 0);
1020     BOOST_CHECK_EQUAL(data_size, large_binary_data.size());
1021
1022     const bool one_line_mode = false;
1023     string encoded = base64_encode(large_binary_data, one_line_mode);
1024
1025     string decoded = base64_decode(encoded, one_line_mode);
1026     BOOST_CHECK_EQUAL(large_binary_data, decoded);
1027 }
1028
1029 BOOST_AUTO_TEST_CASE(base64_decode_garbage)
1030 {
1031     std::string data = "Hello World, this is unencoded data";
1032     string decoded = base64_decode(data);
1033
1034     // garbage turns out to be an empty string
1035     BOOST_CHECK_EQUAL(0, decoded.size());
1036 }
1037
1038 BOOST_AUTO_TEST_CASE(base64_encode_with_linefeeds)
1039 {
1040     const string data = string("Hello World\n")
1041                        + "Hello World\n"
1042                        + "Hello World\n"
1043                        + "Hello World\n"
1044                        + "Hello World\n"
1045                        + "Hello World\n"
1046                        + "Hello World\n";
1047
1048     const string encoded = base64_encode(data, false);
1049
1050     const std::string expected = string("SGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQK\n")
1051                                  + "SGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQK\n";
1052     BOOST_CHECK_EQUAL(expected, encoded);
1053
1054     // decode and compare
1055     BOOST_CHECK_EQUAL(data, base64_decode(encoded, false));
1056
1057     // expected empty string when switching on single line base64 mode
1058     // (openssl is very strict about this)
1059     BOOST_CHECK_EQUAL("", base64_decode(encoded, true));
1060 }
1061
1062 BOOST_AUTO_TEST_SUITE_END()