7771b5529cdbcb7cb9aae6079dc7f10cd5119bb5
[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(ConversionStringInt)
731 {
732     std::string s1("24");
733     std::string s1x("25x");
734     int i1=0;
735     bool res= false;
736
737     i1= string_to<int>(s1);
738     BOOST_CHECK_EQUAL( 24, i1 );
739     i1= string_to<int>(s1x);
740     BOOST_CHECK_EQUAL( 25, i1 );
741
742     res= string_to<int>(s1,i1);
743     BOOST_CHECK_EQUAL( true, res );
744     BOOST_CHECK_EQUAL( 24, i1 );
745
746     res= string_to<int>(s1x,i1);
747     BOOST_CHECK_EQUAL( false, res );
748
749     std::string ss1= to_string( 24 );
750     BOOST_CHECK_EQUAL( std::string("24"), ss1);
751
752 } // eo ConversionStringInt()
753
754
755
756 BOOST_AUTO_TEST_CASE(HexBinaryConversion)
757 {
758     std::string hex1("49324E");
759     std::string bin1("I2N");
760
761     BOOST_CHECK_EQUAL( hex1, convert_binary_to_hex(bin1,true) );
762     BOOST_CHECK_EQUAL( bin1, convert_hex_to_binary(hex1) );
763     BOOST_CHECK_EQUAL( to_lower(hex1), convert_binary_to_hex(bin1) );
764
765     std::string hex2("0001");
766     std::string hex2a("00 01");
767     std::string hex2b("00:01");
768     std::string bin2("\0\1",2);
769
770     BOOST_CHECK_EQUAL( hex2, convert_binary_to_hex(bin2) );
771     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2) );
772     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2a) );
773     BOOST_CHECK_EQUAL( bin2, convert_hex_to_binary(hex2b) );
774
775     BOOST_REQUIRE_THROW( convert_hex_to_binary("01 kein hex"), std::runtime_error);
776 } // eo HexConversion()
777
778 BOOST_AUTO_TEST_CASE(HexIntConversion)
779 {
780     BOOST_CHECK_EQUAL( 255 , hex_string_to<uint32_t>("ff") );
781     BOOST_CHECK_EQUAL( 18866985 , hex_string_to<uint32_t>("11FE329") );
782     BOOST_CHECK_EQUAL( 44 , hex_string_to<uint32_t>("0x2C") );
783 }
784
785 BOOST_AUTO_TEST_CASE(sanitize_for_logging1)
786 {
787     string output = sanitize_for_logging("normaler string ohne aerger");
788
789     BOOST_CHECK_EQUAL(string("normaler string ohne aerger"), output);
790 }
791
792 BOOST_AUTO_TEST_CASE(sanitize_for_logging2)
793 {
794     string to_test="fiese";
795     to_test.push_back(0);
796     to_test+="null";
797
798     string output = sanitize_for_logging(to_test);
799
800     BOOST_CHECK_EQUAL(string("fiese?null"), output);
801 }
802
803 BOOST_AUTO_TEST_CASE(sanitize_for_logging3)
804 {
805     string output = sanitize_for_logging("läuter ümlaute utf8");
806
807     BOOST_CHECK_EQUAL(string("l??uter ??mlaute utf8"), output);
808 }
809
810 BOOST_AUTO_TEST_CASE(find_html_comments_test)
811 {
812     string text = "bla-->"  // ==> (npos, 6)
813                //  0     6
814                   "bla<!--bla<!--bla-->bla-->"  // ==> (16, 26), (9, 32)
815                //  6  9     16        26     32
816                   "bla<!--bla-->"  // ==> (35, 45)
817                // 32 35        45
818                   "--><!----><!--"    // ==> (npos, 48), (48, 55), (55, npos)
819                // 45 48      55 59
820                   "bla<!--bla-->";  // ==> (62, 72)
821                // 59 62        72
822     BOOST_REQUIRE_EQUAL(text.length(), 72);
823     vector<CommentZone> expect;
824     expect.push_back(CommentZone(string::npos, 6));
825     expect.push_back(CommentZone(16, 26));
826     expect.push_back(CommentZone( 9, 32));
827     expect.push_back(CommentZone(35, 45));
828     expect.push_back(CommentZone(string::npos, 48));
829     expect.push_back(CommentZone(48, 55));
830     expect.push_back(CommentZone(55, string::npos));
831     expect.push_back(CommentZone(62, 72));
832     vector<CommentZone> result = find_html_comments(text);
833     //BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(),   not working, requires ...
834     //                              expect.begin(), expect.end());  ... operator<<(CommentZone)
835     BOOST_CHECK_EQUAL(result.size(), expect.size());
836     BOOST_FOREACH(const CommentZone &comment, expect)
837         BOOST_CHECK_MESSAGE(find(result.begin(), result.end(), comment) != result.end(),
838                             "Find (" << comment.first << "-" << comment.second << ")");
839 }
840
841 BOOST_AUTO_TEST_CASE(remove_html_comments_test)
842 {
843     const string original = "First line outside\n"
844                             "text <!--FOO\n"
845                             "Inside foo\n"
846                             "<!--BAR\n"
847                             "foo bar, what a surprise.\n"
848                             "<!-- short tag-less comment -->\n"
849                             " Html cannot handle this, thinks that FOO ended above\n"
850                             "BAR-->\n"
851                             "This, neither. No nested comments\n"
852                             "some text <!--BAZ more text\n"
853                             "Aaarggh!"
854                             "more text BAZ--> even more\n"
855                             "FOO--> text\n"
856                             "second line outside\n"
857                             "<!-- second comment -->";
858     string text = original;
859     string expect = "First line outside\n"
860                     "text  text\n"
861                     "second line outside\n";
862     remove_html_comments(text);
863     BOOST_CHECK_EQUAL(text, expect);
864     remove_html_comments(text);   // should not have any effect
865     BOOST_CHECK_EQUAL(text, expect);
866
867     text = string("test<!--") + original;
868     remove_html_comments(text);
869     BOOST_CHECK_EQUAL(text, "test");
870
871     text = original + "-->test";
872     remove_html_comments(text);
873     BOOST_CHECK_EQUAL(text, "test");
874 }
875
876 BOOST_AUTO_TEST_CASE(shorten_stl_types_string)
877 {
878     BOOST_CHECK_EQUAL(shorten_stl_types("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
879                       "std::string");
880 }
881
882 BOOST_AUTO_TEST_CASE(shorten_stl_types_simple)
883 {
884     BOOST_CHECK_EQUAL(shorten_stl_types("std::list<some_type, std::allocator<some_type> >"),
885                       "std::list<some_type, _alloc_>");
886 }
887
888 BOOST_AUTO_TEST_CASE(shorten_stl_types_multiple)
889 {
890     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> >)"),
891                       "std::string my_func(std::list<some_type, _alloc_>, std::vector<int, _alloc_>)");
892 }
893
894 BOOST_AUTO_TEST_CASE(shorten_stl_types_complex)
895 {
896     BOOST_CHECK_EQUAL(shorten_stl_types("std::list<boost::shared_ptr<some_type>, std::allocator<boost::shared_ptr<some_type> > >"),
897                       "std::list<boost::shared_ptr<some_type>, _alloc_>");
898 }
899
900 BOOST_AUTO_TEST_CASE(shorten_stl_types_nested)
901 {
902               //"std::list<int, std::allocator<int> >"
903     //"std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > >"
904     BOOST_CHECK_EQUAL(shorten_stl_types("std::list<std::list<int, std::allocator<int> >, std::allocator<std::list<int, std::allocator<int> > > >"),
905                       "std::list<std::list<int, _alloc_>, _alloc_>");
906 }
907
908 BOOST_AUTO_TEST_CASE(shorten_stl_types_nothing)
909 {
910     string text = "";
911     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
912     text = "int f(void)";
913     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
914     text = "std::cout << \"Test\" << std::endl;";
915     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
916     text = "bla<blubb>";
917     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
918     text = "std::list<> is a class template";
919     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
920     text = "std::list<int, std::allocator<int>\n>";
921     BOOST_CHECK_EQUAL(shorten_stl_types(text), text);
922 }
923
924 BOOST_AUTO_TEST_CASE(base64_encode_decode)
925 {
926     string text = "Hello World\n";
927
928     string encoded = base64_encode(text);
929
930     BOOST_CHECK_EQUAL("SGVsbG8gV29ybGQK", encoded);
931     BOOST_CHECK_EQUAL(text, base64_decode(encoded));
932 }
933
934 BOOST_AUTO_TEST_CASE(base64_empty_string)
935 {
936     string text = "";
937     string encoded = base64_encode(text);
938
939     BOOST_CHECK_EQUAL("", encoded);
940     BOOST_CHECK_EQUAL(text, base64_decode(encoded));
941 }
942
943 BOOST_AUTO_TEST_CASE(base64_large_string_with_zero)
944 {
945     // 10 MB data
946     int data_size = 1024 * 1024 * 10;
947
948     string large_binary_data(data_size, 0);
949     BOOST_CHECK_EQUAL(data_size, large_binary_data.size());
950
951     string encoded = base64_encode(large_binary_data);
952
953     string decoded = base64_decode(encoded);
954     BOOST_CHECK_EQUAL(large_binary_data, decoded);
955 }
956
957 BOOST_AUTO_TEST_CASE(base64_large_string_with_zero_encode_linefeeds)
958 {
959     // 10 MB data
960     int data_size = 1024 * 1024 * 10;
961
962     string large_binary_data(data_size, 0);
963     BOOST_CHECK_EQUAL(data_size, large_binary_data.size());
964
965     const bool one_line_mode = false;
966     string encoded = base64_encode(large_binary_data, one_line_mode);
967
968     string decoded = base64_decode(encoded, one_line_mode);
969     BOOST_CHECK_EQUAL(large_binary_data, decoded);
970 }
971
972 BOOST_AUTO_TEST_CASE(base64_decode_garbage)
973 {
974     std::string data = "Hello World, this is unencoded data";
975     string decoded = base64_decode(data);
976
977     // garbage turns out to be an empty string
978     BOOST_CHECK_EQUAL(0, decoded.size());
979 }
980
981 BOOST_AUTO_TEST_CASE(base64_encode_with_linefeeds)
982 {
983     const string data = string("Hello World\n")
984                        + "Hello World\n"
985                        + "Hello World\n"
986                        + "Hello World\n"
987                        + "Hello World\n"
988                        + "Hello World\n"
989                        + "Hello World\n";
990
991     const string encoded = base64_encode(data, false);
992
993     const std::string expected = string("SGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQK\n")
994                                  + "SGVsbG8gV29ybGQKSGVsbG8gV29ybGQKSGVsbG8gV29ybGQK\n";
995     BOOST_CHECK_EQUAL(expected, encoded);
996
997     // decode and compare
998     BOOST_CHECK_EQUAL(data, base64_decode(encoded, false));
999
1000     // expected empty string when switching on single line base64 mode
1001     // (openssl is very strict about this)
1002     BOOST_CHECK_EQUAL("", base64_decode(encoded, true));
1003 }
1004
1005 BOOST_AUTO_TEST_SUITE_END()