The Battle for Wesnoth  1.19.6+dev
test_serialization.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2024
3  by Karol Nowak <grywacz@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-test"
17 
18 #include <array>
19 #include <vector>
20 #include <string>
21 #include "serialization/base64.hpp"
24 #include <boost/test/unit_test.hpp>
25 
26 namespace std {
27 static std::ostream& operator<<(std::ostream& str, const std::pair<const std::string, std::string>& p)
28 {
29  return str << '(' << p.first << " => " << p.second << ')';
30 }
31 }
32 
33 BOOST_AUTO_TEST_SUITE ( test_serialization_utils_and_unicode )
34 
35 BOOST_AUTO_TEST_CASE( utils_join_test )
36 {
37  std::vector<std::string> fruit;
38 
39  BOOST_CHECK( utils::join(fruit).empty() );
40  BOOST_CHECK( utils::join(fruit, "---").empty() );
41 
42  fruit.push_back("apples");
43 
44  BOOST_CHECK( utils::join(fruit) == "apples" );
45  BOOST_CHECK( utils::join(fruit, "---") == "apples" );
46 
47  fruit.push_back("oranges");
48  fruit.push_back("lemons");
49 
50  BOOST_CHECK( utils::join(fruit) == "apples,oranges,lemons" );
51  BOOST_CHECK( utils::join(fruit, "---") == "apples---oranges---lemons" );
52 }
53 
54 BOOST_AUTO_TEST_CASE( utils_split_test )
55 {
56  const std::string test_string = "a, , bb, ccc || d, ee,, fff | | g, , hh, iii";
57 
58  {
59  auto split = utils::split(test_string);
60  std::array expect = {"a", "bb", "ccc || d", "ee", "fff | | g", "hh", "iii"};
61  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
62  }
63  {
64  auto split = utils::split(test_string, ',', utils::REMOVE_EMPTY | utils::STRIP_SPACES);
65  std::array expect = {"a", "bb", "ccc || d", "ee", "fff | | g", "hh", "iii"};
66  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
67  }
68  {
69  auto split = utils::split(test_string, ',', utils::REMOVE_EMPTY);
70  std::array expect = {"a", " ", " bb", " ccc || d", " ee", " fff | | g", " ", " hh", " iii"};
71  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
72  }
73  {
74  auto split = utils::split(test_string, ',', utils::STRIP_SPACES);
75  std::array expect = {"a", "", "bb", "ccc || d", "ee", "", "fff | | g", "", "hh", "iii"};
76  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
77  }
78  {
79  auto split = utils::split(test_string, ',', 0);
80  std::array expect = {"a", " ", " bb", " ccc || d", " ee", "", " fff | | g", " ", " hh", " iii"};
81  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
82  }
83  {
84  auto split = utils::split(test_string, '|');
85  std::array expect = {"a, , bb, ccc", "d, ee,, fff", "g, , hh, iii"};
86  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
87  }
88  {
89  auto split = utils::split(test_string, '|', utils::REMOVE_EMPTY | utils::STRIP_SPACES);
90  std::array expect = {"a, , bb, ccc", "d, ee,, fff", "g, , hh, iii"};
91  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
92  }
93  {
94  auto split = utils::split(test_string, '|', utils::REMOVE_EMPTY);
95  std::array expect = {"a, , bb, ccc ", " d, ee,, fff ", " ", " g, , hh, iii"};
96  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
97  }
98  {
99  auto split = utils::split(test_string, '|', utils::STRIP_SPACES);
100  std::array expect = {"a, , bb, ccc", "", "d, ee,, fff", "", "g, , hh, iii"};
101  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
102  }
103  {
104  auto split = utils::split(test_string, '|', 0);
105  std::array expect = {"a, , bb, ccc ", "", " d, ee,, fff ", " ", " g, , hh, iii"};
106  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
107  }
108 }
109 
110 BOOST_AUTO_TEST_CASE( utils_quoted_split_test )
111 {
112  const std::string test_string = "a, `, bb, ccc || d, ee,, fff | `| g, `, hh, iii";
113 
114  {
115  auto split = utils::quoted_split(test_string, ',', utils::REMOVE_EMPTY | utils::STRIP_SPACES, '`');
116  std::array expect = {"a", "`, bb", "ccc || d", "ee", "fff | `| g", "`, hh", "iii"};
117  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
118  }
119  {
120  auto split = utils::quoted_split(test_string, ',', utils::REMOVE_EMPTY, '`');
121  std::array expect = {"a", " `, bb", " ccc || d", " ee", " fff | `| g", " `, hh", " iii"};
122  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
123  }
124  {
125  auto split = utils::quoted_split(test_string, ',', utils::STRIP_SPACES, '`');
126  std::array expect = {"a", "`, bb", "ccc || d", "ee", "", "fff | `| g", "`, hh", "iii"};
127  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
128  }
129  {
130  auto split = utils::quoted_split(test_string, ',', 0, '`');
131  std::array expect = {"a", " `, bb", " ccc || d", " ee", "", " fff | `| g", " `, hh", " iii"};
132  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
133  }
134  {
135  auto split = utils::quoted_split(test_string, '|', utils::REMOVE_EMPTY | utils::STRIP_SPACES, '`');
136  std::array expect = {"a, `, bb, ccc", "d, ee,, fff", "`| g, `, hh, iii"};
137  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
138  }
139  {
140  auto split = utils::quoted_split(test_string, '|', utils::REMOVE_EMPTY, '`');
141  std::array expect = {"a, `, bb, ccc ", " d, ee,, fff ", " `| g, `, hh, iii"};
142  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
143  }
144  {
145  auto split = utils::quoted_split(test_string, '|', utils::STRIP_SPACES, '`');
146  std::array expect = {"a, `, bb, ccc", "", "d, ee,, fff", "`| g, `, hh, iii"};
147  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
148  }
149  {
150  auto split = utils::quoted_split(test_string, '|', 0, '`');
151  std::array expect = {"a, `, bb, ccc ", "", " d, ee,, fff ", " `| g, `, hh, iii"};
152  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
153  }
154 }
155 
156 BOOST_AUTO_TEST_CASE( utils_map_split_test )
157 {
158  const std::string test_string = "a = b:2,, c = d:.9, e = f:5;; x = r:12, y = b:9.2,, z = g:45";
159 
160  {
161  auto split = utils::map_split(test_string);
162  std::map<std::string, std::string> expect = {
163  {"a = b", "2"},
164  {"c = d", ".9"},
165  {"e = f", "5;; x = r:12"},
166  {"y = b", "9.2"},
167  {"z = g", "45"}
168  };
169  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
170  }
171 
172  {
173  auto split = utils::map_split(test_string, ',', ':', utils::REMOVE_EMPTY | utils::STRIP_SPACES);
174  std::map<std::string, std::string> expect = {
175  {"a = b", "2"},
176  {"c = d", ".9"},
177  {"e = f", "5;; x = r:12"},
178  {"y = b", "9.2"},
179  {"z = g", "45"},
180  };
181  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
182  }
183  {
184  auto split = utils::map_split(test_string, ';', ':', utils::REMOVE_EMPTY | utils::STRIP_SPACES);
185  std::map<std::string, std::string> expect = {
186  {"a = b", "2,, c = d:.9, e = f:5"},
187  {"x = r", "12, y = b:9.2,, z = g:45"},
188  };
189  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
190  }
191  {
192  auto split = utils::map_split(test_string, ',', '=', utils::REMOVE_EMPTY | utils::STRIP_SPACES);
193  std::map<std::string, std::string> expect = {
194  {"a ", " b:2"},
195  {"c ", " d:.9"},
196  {"e ", " f:5;; x = r:12"},
197  {"y ", " b:9.2"},
198  {"z ", " g:45"},
199  };
200  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
201  }
202  {
203  auto split = utils::map_split(test_string, ';', '.', utils::REMOVE_EMPTY | utils::STRIP_SPACES);
204  std::map<std::string, std::string> expect = {
205  {"a = b:2,, c = d:", "9, e = f:5"},
206  {"x = r:12, y = b:9", "2,, z = g:45"}
207  };
208  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
209  }
210 
211  {
212  auto split = utils::map_split(test_string, ',', ':', utils::REMOVE_EMPTY);
213  std::map<std::string, std::string> expect = {
214  {"a = b", "2"},
215  {" c = d", ".9"},
216  {" e = f", "5;; x = r:12"},
217  {" y = b", "9.2"},
218  {" z = g", "45"},
219  };
220  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
221  }
222  {
223  auto split = utils::map_split(test_string, ';', ':', utils::REMOVE_EMPTY);
224  std::map<std::string, std::string> expect = {
225  {"a = b", "2,, c = d:.9, e = f:5"},
226  {" x = r", "12, y = b:9.2,, z = g:45"},
227  };
228  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
229  }
230  {
231  auto split = utils::map_split(test_string, ',', '=', utils::REMOVE_EMPTY);
232  std::map<std::string, std::string> expect = {
233  {"a ", " b:2"},
234  {" c ", " d:.9"},
235  {" e ", " f:5;; x = r:12"},
236  {" y ", " b:9.2"},
237  {" z ", " g:45"},
238  };
239  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
240  }
241  {
242  auto split = utils::map_split(test_string, ';', '.', utils::REMOVE_EMPTY);
243  std::map<std::string, std::string> expect = {
244  {"a = b:2,, c = d:", "9, e = f:5"},
245  {" x = r:12, y = b:9", "2,, z = g:45"}
246  };
247  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
248  }
249 
250  {
251  auto split = utils::map_split(test_string, ',', ':', utils::STRIP_SPACES);
252  std::map<std::string, std::string> expect = {
253  {"a = b", "2"},
254  {"", ""},
255  {"c = d", ".9"},
256  {"e = f", "5;; x = r:12"},
257  {"y = b", "9.2"},
258  {"", ""},
259  {"z = g", "45"},
260  };
261  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
262  }
263  {
264  auto split = utils::map_split(test_string, ';', ':', utils::STRIP_SPACES);
265  std::map<std::string, std::string> expect = {
266  {"a = b", "2,, c = d:.9, e = f:5"},
267  {"", ""},
268  {"x = r", "12, y = b:9.2,, z = g:45"},
269  };
270  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
271  }
272  {
273  auto split = utils::map_split(test_string, ',', '=', utils::STRIP_SPACES);
274  std::map<std::string, std::string> expect = {
275  {"a ", " b:2"},
276  {"", ""},
277  {"c ", " d:.9"},
278  {"e ", " f:5;; x = r:12"},
279  {"y ", " b:9.2"},
280  {"", ""},
281  {"z ", " g:45"},
282  };
283  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
284  }
285  {
286  auto split = utils::map_split(test_string, ';', '.', utils::STRIP_SPACES);
287  std::map<std::string, std::string> expect = {
288  {"a = b:2,, c = d:", "9, e = f:5"},
289  {"", ""},
290  {"x = r:12, y = b:9", "2,, z = g:45"}
291  };
292  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
293  }
294 
295  {
296  auto split = utils::map_split(test_string, ',', ':', 0);
297  std::map<std::string, std::string> expect = {
298  {"a = b", "2"},
299  {"", ""},
300  {" c = d", ".9"},
301  {" e = f", "5;; x = r:12"},
302  {" y = b", "9.2"},
303  {"", ""},
304  {" z = g", "45"},
305  };
306  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
307  }
308  {
309  auto split = utils::map_split(test_string, ';', ':', 0);
310  std::map<std::string, std::string> expect = {
311  {"a = b", "2,, c = d:.9, e = f:5"},
312  {"", ""},
313  {" x = r", "12, y = b:9.2,, z = g:45"},
314  };
315  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
316  }
317  {
318  auto split = utils::map_split(test_string, ',', '=', 0);
319  std::map<std::string, std::string> expect = {
320  {"a ", " b:2"},
321  {"", ""},
322  {" c ", " d:.9"},
323  {" e ", " f:5;; x = r:12"},
324  {" y ", " b:9.2"},
325  {"", ""},
326  {" z ", " g:45"},
327  };
328  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
329  }
330  {
331  auto split = utils::map_split(test_string, ';', '.', 0);
332  std::map<std::string, std::string> expect = {
333  {"a = b:2,, c = d:", "9, e = f:5"},
334  {"", ""},
335  {" x = r:12, y = b:9", "2,, z = g:45"}
336  };
337  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
338  }
339 }
340 
341 BOOST_AUTO_TEST_CASE( utils_parenthetical_split_test )
342 {
343  {
344  auto split = utils::parenthetical_split("a ( b ) c { d } e ( f { g } ) h", 0, "({", ")}");
345  std::array expect = {"a", "b", "c", "d", "e", "f { g }", "h"};
346  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
347  }
348  {
349  auto split = utils::parenthetical_split("a ( b ) c { d } e ( f { g } ) h", 0, "({", ")}", utils::STRIP_SPACES);
350  std::array expect = {"a", "b", "c", "d", "e", "f { g }", "h"};
351  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
352  }
353  {
354  auto split = utils::parenthetical_split("a ( b ) c { d } e ( f { g } ) h", 0, "({", ")}", 0);
355  std::array expect = {"a ", " b ", " c ", " d ", " e ", " f { g } ", " h"};
356  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
357  }
358 
359  {
360  auto split = utils::parenthetical_split("a, (b, c), {d, e},, f(g,g), h{i,i}", ',', "({", ")}");
361  std::array expect = {"a", "(b, c)", "{d, e}", "f(g,g)", "h{i,i}"};
362  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
363  }
364  {
365  auto split = utils::parenthetical_split("a, (b, c), {d, e},, f(g,g), h{i,i}", ',', "({", ")}", utils::REMOVE_EMPTY | utils::STRIP_SPACES);
366  std::array expect = {"a", "(b, c)", "{d, e}", "f(g,g)", "h{i,i}"};
367  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
368  }
369  {
370  auto split = utils::parenthetical_split("a, (b, c), {d, e},, f(g,g), h{i,i}", ',', "({", ")}", utils::REMOVE_EMPTY);
371  std::array expect = {"a", " (b, c)", " {d, e}", " f(g,g)", " h{i,i}"};
372  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
373  }
374  {
375  auto split = utils::parenthetical_split("a, (b, c), {d, e},, f(g,g), h{i,i}", ',', "({", ")}", utils::STRIP_SPACES);
376  std::array expect = {"a", "(b, c)", "{d, e}", "", "f(g,g)", "h{i,i}"};
377  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
378  }
379  {
380  auto split = utils::parenthetical_split("a, (b, c), {d, e},, f(g,g), h{i,i}", ',', "({", ")}", 0);
381  std::array expect = {"a", " (b, c)", " {d, e}", "", " f(g,g)", " h{i,i}"};
382  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
383  }
384 }
385 
386 BOOST_AUTO_TEST_CASE( utils_square_parenthetical_split )
387 {
388  {
389  auto split = utils::square_parenthetical_split(" a ,, b ,, c ");
390  std::array expect = {"a", "b", "c"};
391  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
392  }
393  {
394  auto split = utils::square_parenthetical_split(" a ,, b ,, c ", ',', "([", ")]", utils::REMOVE_EMPTY | utils::STRIP_SPACES);
395  std::array expect = {"a", "b", "c"};
396  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
397  }
398  {
399  auto split = utils::square_parenthetical_split(" a ,, b ,, c ", ',', "([", ")]", utils::REMOVE_EMPTY);
400  std::array expect = {" a ", " b ", " c "};
401  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
402  }
403  {
404  auto split = utils::square_parenthetical_split(" a ,, b ,, c ", ',', "([", ")]", utils::STRIP_SPACES);
405  std::array expect = {"a", "", "b", "", "c"};
406  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
407  }
408  {
409  auto split = utils::square_parenthetical_split(" a ,, b ,, c ", ',', "([", ")]", 0);
410  std::array expect = {" a ", "", " b ", "", " c "};
411  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
412  }
413  {
415  std::array expect = {"a", "a", "a"};
416  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
417  }
418  {
419  auto split = utils::square_parenthetical_split("q[a*3,b,c*2]");
420  std::array expect = {"qa", "qa", "qa", "qb", "qc", "qc"};
421  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
422  }
423  {
424  auto split = utils::square_parenthetical_split("q[a,b,c]");
425  std::array expect = {"qa", "qb", "qc"};
426  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
427  }
428  {
429  auto split = utils::square_parenthetical_split("q[1~5]");
430  std::array expect = {"q1", "q2", "q3", "q4", "q5"};
431  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
432  }
433  {
434  auto split = utils::square_parenthetical_split("q[5~1]");
435  std::array expect = {"q5", "q4", "q3", "q2", "q1"};
436  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
437  }
438  {
439  auto split = utils::square_parenthetical_split("q[001~005]");
440  std::array expect = {"q001", "q002", "q003", "q004", "q005"};
441  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
442  }
443  {
444  auto split = utils::square_parenthetical_split("q[007~012]");
445  std::array expect = {"q007", "q008", "q009", "q010", "q011", "q012"};
446  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
447  }
448  {
449  auto split = utils::square_parenthetical_split("a[1~3](1,[5,6,7]),b[8,9]");
450  std::array expect = {"a1(1,5)", "a2(1,6)", "a3(1,7)", "b8", "b9"};
451  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
452  }
453  {
454  auto split = utils::square_parenthetical_split("abc[07~10]");
455  std::array expect = {"abc07", "abc08", "abc09", "abc10"};
456  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
457  }
458  {
459  auto split = utils::square_parenthetical_split("a[1,2]b[3~4]:c[5,6]");
460  std::array expect = {"a1b3:c5", "a2b4:c6"};
461  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
462  }
463  {
464  auto split = utils::square_parenthetical_split("abc[3~1].png");
465  std::array expect = {"abc3.png", "abc2.png", "abc1.png"};
466  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
467  }
468  {
469  auto split = utils::square_parenthetical_split("abc[3,1].png");
470  std::array expect = {"abc3.png", "abc1.png"};
471  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
472  }
473  {
474  auto split = utils::square_parenthetical_split("abc[de,xyz]");
475  std::array expect = {"abcde", "abcxyz"};
476  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
477  }
478  {
479  auto split = utils::square_parenthetical_split("abc[1*3]");
480  std::array expect = {"abc1", "abc1", "abc1"};
481  BOOST_CHECK_EQUAL_COLLECTIONS(split.begin(), split.end(), expect.begin(), expect.end());
482  }
483 }
484 
485 BOOST_AUTO_TEST_CASE( utils_unicode_test )
486 {
487  std::string unicode = "ünicod€ check";
488  BOOST_CHECK( utf8::size(unicode) == 13 );
489 
490  int euro = utf8::index(unicode,6);
491  BOOST_CHECK( unicode.substr(euro,utf8::index(unicode,7)-euro) == "€" );
492 
493  BOOST_CHECK( utf8::truncate(unicode,3) == "üni");
494 
495  std::string apple_u8("apple");
496  std::u32string apple_u4 = unicode_cast<std::u32string>(apple_u8);
497  std::u16string apple_u16 = unicode_cast<std::u16string>(apple_u4);
498 
499  BOOST_CHECK( apple_u4.size() == 5 );
500  BOOST_CHECK_EQUAL( apple_u8, unicode_cast<std::string>(apple_u4) );
501  BOOST_CHECK_EQUAL( apple_u8, unicode_cast<std::string>(apple_u16) );
502  BOOST_CHECK( apple_u4 == unicode_cast<std::u32string>(apple_u16) );
503  BOOST_CHECK( apple_u16 == unicode_cast<std::u16string>(apple_u4) );
504  BOOST_CHECK_EQUAL( apple_u8.size(), apple_u16.size() );
505 
506  std::u32string water_u4;
507  water_u4.push_back(0x6C34);
508  std::string water_u8 = unicode_cast<std::string>(water_u4);
509 
510 #if defined(_WIN32) || defined(_WIN64)
511  // Windows complains it can't be represented in the currentl code-page.
512  // So instead, check directly for its UTF-8 representation.
513  BOOST_CHECK_EQUAL(water_u8, "\xE6\xB0\xB4");
514 #else
515  BOOST_CHECK_EQUAL(water_u8, "\u6C34");
516 #endif
517 
518 #if defined(_WIN32) || defined(_WIN64)
519  // Same as above.
520  std::string nonbmp_u8("\xF0\x90\x80\x80");
521 #else
522  std::string nonbmp_u8("\U00010000");
523 #endif
524  std::u32string nonbmp_u4 = unicode_cast<std::u32string>(nonbmp_u8);
525  std::u16string nonbmp_u16 = unicode_cast<std::u16string>(nonbmp_u4);
526 
527  BOOST_CHECK_EQUAL(nonbmp_u8.size(), 4u);
528  BOOST_CHECK_EQUAL(nonbmp_u8, unicode_cast<std::string>(nonbmp_u4));
529  BOOST_CHECK_EQUAL(nonbmp_u8, unicode_cast<std::string>(nonbmp_u16));
530  BOOST_CHECK(nonbmp_u16 == unicode_cast<std::u16string>(nonbmp_u4));
531  BOOST_CHECK(nonbmp_u4 == unicode_cast<std::u32string>(nonbmp_u16));
532 }
533 
534 BOOST_AUTO_TEST_CASE( test_lowercase )
535 {
536  BOOST_CHECK_EQUAL ( utf8::lowercase("FOO") , "foo" );
537  BOOST_CHECK_EQUAL ( utf8::lowercase("foo") , "foo" );
538  BOOST_CHECK_EQUAL ( utf8::lowercase("FoO") , "foo" );
539  BOOST_CHECK_EQUAL ( utf8::lowercase("fO0") , "fo0" );
540 }
541 
542 BOOST_AUTO_TEST_CASE( test_wildcard_string_match )
543 {
544  const std::string str = "foo bar baz";
545 
546  BOOST_CHECK(utils::wildcard_string_match(str, "*bar*"));
547  BOOST_CHECK(utils::wildcard_string_match(str, "+bar+"));
548 
549  BOOST_CHECK(!utils::wildcard_string_match(str, "*BAR*"));
550  BOOST_CHECK(!utils::wildcard_string_match(str, "+BAR+"));
551  BOOST_CHECK(!utils::wildcard_string_match(str, "bar"));
552 
553  BOOST_CHECK(utils::wildcard_string_match(str, "*ba? b*"));
554  BOOST_CHECK(utils::wildcard_string_match(str, "+ba? b+"));
555  BOOST_CHECK(utils::wildcard_string_match(str, "*?a?*"));
556  BOOST_CHECK(utils::wildcard_string_match(str, "+?a?+"));
557 
558  BOOST_CHECK(!utils::wildcard_string_match(str, "foo? "));
559  BOOST_CHECK(!utils::wildcard_string_match(str, "?foo"));
560 
561  std::string superfluous_mask;
562 
563  superfluous_mask = std::string(str.length(), '?');
564  BOOST_CHECK(utils::wildcard_string_match(str, superfluous_mask));
565  BOOST_CHECK(utils::wildcard_string_match(str, superfluous_mask + '?'));
566 
567  superfluous_mask = std::string(str.length(), '*');
568  BOOST_CHECK(utils::wildcard_string_match(str, superfluous_mask));
569  BOOST_CHECK(utils::wildcard_string_match(str, superfluous_mask + '*'));
570 
571  superfluous_mask = std::string(str.length(), '+');
572  BOOST_CHECK(utils::wildcard_string_match(str, superfluous_mask));
573  BOOST_CHECK(!utils::wildcard_string_match(str, superfluous_mask + '+'));
574 
575  BOOST_CHECK(utils::wildcard_string_match("", ""));
576  BOOST_CHECK(!utils::wildcard_string_match(str, ""));
577 
578  BOOST_CHECK(utils::wildcard_string_match("", "*"));
579  BOOST_CHECK(utils::wildcard_string_match("", "***"));
580  BOOST_CHECK(!utils::wildcard_string_match("", "+"));
581  BOOST_CHECK(!utils::wildcard_string_match("", "*bar"));
582  BOOST_CHECK(!utils::wildcard_string_match("", "***?**"));
583  BOOST_CHECK(!utils::wildcard_string_match("", "+++?++"));
584  BOOST_CHECK(!utils::wildcard_string_match("", "?"));
585  BOOST_CHECK(!utils::wildcard_string_match("", "???"));
586 }
587 
588 BOOST_AUTO_TEST_CASE( test_base64_encodings )
589 {
590  const std::vector<uint8_t> empty;
591  const std::string empty_b64;
592  const std::string empty_c64;
593  const std::vector<uint8_t> foo = {'f', 'o', 'o'};
594  const std::string foo_b64 = "Zm9v";
595  const std::string foo_c64 = "axqP";
596  const std::vector<uint8_t> foob = {'f', 'o', 'o', 'b'};
597  const std::string foob_b64 = "Zm9vYg==";
598  const std::string foob_c64 = "axqPW/";
599 
600  std::vector<uint8_t> many_bytes;
601 
602  many_bytes.resize(1024);
603  for(int i = 0; i < 1024; ++i) {
604  many_bytes[i] = i % 256;
605  }
606 
607  BOOST_CHECK(base64::encode({empty.data(), empty.size()}).empty());
608  BOOST_CHECK_EQUAL(base64::encode({foo.data(), foo.size()}), foo_b64);
609  BOOST_CHECK_EQUAL(base64::encode({foob.data(), foob.size()}), foob_b64);
610 
611  BOOST_CHECK(base64::decode(empty_b64).empty());
612  // Not using CHECK_EQUAL because vector<uint8_t> is not printable
613  BOOST_CHECK(base64::decode(foo_b64) == foo);
614  BOOST_CHECK(base64::decode(foob_b64) == foob);
615 
616  BOOST_CHECK(crypt64::encode({empty.data(), empty.size()}).empty());
617  BOOST_CHECK_EQUAL(crypt64::encode({foo.data(), foo.size()}), foo_c64);
618  BOOST_CHECK_EQUAL(crypt64::encode({foob.data(), foob.size()}), foob_c64);
619 
620  BOOST_CHECK(crypt64::decode(empty_c64).empty());
621  // Not using CHECK_EQUAL because vector<uint8_t> is not printable
622  BOOST_CHECK(crypt64::decode(foo_c64) == foo);
623  BOOST_CHECK(crypt64::decode(foob_c64) == foob);
624 
625  BOOST_CHECK_EQUAL(crypt64::decode('.'), 0);
626  BOOST_CHECK_EQUAL(crypt64::decode('z'), 63);
627  BOOST_CHECK_EQUAL(crypt64::encode(0), '.');
628  BOOST_CHECK_EQUAL(crypt64::encode(63), 'z');
629 
630  BOOST_CHECK(base64::decode(base64::encode({many_bytes.data(), many_bytes.size()})) == many_bytes);
631  BOOST_CHECK(crypt64::decode(crypt64::encode({many_bytes.data(), many_bytes.size()})) == many_bytes);
632 }
633 
634 BOOST_AUTO_TEST_SUITE_END()
std::ostream & operator<<(std::ostream &s, const ai::attack_result &r)
Definition: actions.cpp:1118
std::size_t i
Definition: function.cpp:1029
std::string encode(utils::byte_string_view bytes)
Definition: base64.cpp:225
std::vector< uint8_t > decode(std::string_view in)
Definition: base64.cpp:221
std::string encode(utils::byte_string_view bytes)
Definition: base64.cpp:235
std::vector< uint8_t > decode(std::string_view in)
Definition: base64.cpp:231
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
std::string lowercase(const std::string &s)
Returns a lowercased version of the string.
Definition: unicode.cpp:50
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
std::string & truncate(std::string &str, const std::size_t size)
Truncates a UTF-8 string to the specified number of characters.
Definition: unicode.cpp:116
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
@ REMOVE_EMPTY
std::map< std::string, std::string > map_split(const std::string &val, char major, char minor, int flags, const std::string &default_value)
Splits a string based on two separators into a map.
std::vector< std::string > quoted_split(const std::string &val, char c, int flags, char quote)
This function is identical to split(), except it does not split when it otherwise would if the previo...
std::vector< std::string > parenthetical_split(std::string_view val, const char separator, std::string_view left, std::string_view right, const int flags)
Splits a string based either on a separator, except then the text appears within specified parenthesi...
bool wildcard_string_match(const std::string &str, const std::string &match)
Match using '*' as any number of characters (including none), '+' as one or more characters,...
std::vector< std::string > square_parenthetical_split(const std::string &val, const char separator, const std::string &left, const std::string &right, const int flags)
Similar to parenthetical_split, but also expands embedded square brackets.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::vector< std::string > split(const config_attribute_value &val)
BOOST_AUTO_TEST_SUITE(filesystem)
mock_party p
BOOST_AUTO_TEST_CASE(utils_join_test)