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