Tizen 2.0 Release
[framework/web/wrt-commons.git] / tests / dpl / core / test_string.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        test_string.cpp
18  * @author      Piotr Marcinkiewicz (p.marcinkiew@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of string tests
21  */
22 #include <stdlib.h>
23 #include <cmath>
24 #include <cstring>
25 #include <vector>
26 #include <dpl/test/test_runner.h>
27 #include <dpl/string.h>
28 #include <dpl/sstream.h>
29
30 RUNNER_TEST_GROUP_INIT(DPL)
31
32 unsigned char GetBaseCode(int index);
33 unsigned char GetBaseCode(int index)
34 {
35     /* aaaack but it's fast and const should make it shared text page. */
36     static const unsigned char pr2six[256] = {
37         /* ASCII table */
38         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
39         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
40         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
41         52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
42         64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
43         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
44         64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
45         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
46         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
47         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
48         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
49         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
50         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
51         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
52         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
53         64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
54     };
55     return pr2six[index];
56 }
57
58 /* Function adapted from APR library (http://apr.apache.org/) */
59 int wbxml_base64_decode(const char *buffer, char **result);
60 int wbxml_base64_decode(const char *buffer, char **result)
61 {
62     int nbytesdecoded = 0, nprbytes = 0;
63     const char *bufin = NULL;
64     char *bufout = NULL;
65
66     if ((buffer == NULL) || (result == NULL)) {
67         return 0;
68     }
69
70     /* Initialize output buffer */
71     *result = NULL;
72
73     bufin = buffer;
74     while (GetBaseCode(*(bufin++)) <= 63) {}
75
76     nprbytes = (bufin - buffer) - 1;
77     nbytesdecoded = ((nprbytes + 3) / 4) * 3;
78
79     /* Malloc result buffer */
80     if ((*result = (char*) malloc(nbytesdecoded + 1)) == NULL) {
81         return 0;
82     }
83     memset(*result, 0, nbytesdecoded + 1);
84
85     bufout = *result;
86     bufin = buffer;
87
88     while (nprbytes > 4) {
89         *(bufout++) =
90             (char)(GetBaseCode(*bufin) << 2 | GetBaseCode(bufin[1]) >> 4);
91         *(bufout++) =
92             (char)(GetBaseCode(bufin[1]) << 4 | GetBaseCode(bufin[2]) >> 2);
93         *(bufout++) = (char)(GetBaseCode(bufin[2]) << 6 | GetBaseCode(bufin[3]));
94         bufin += 4;
95         nprbytes -= 4;
96     }
97
98     /* Note: (nprbytes == 1) would be an error, so just ingore that case */
99     if (nprbytes > 1) {
100         *(bufout++) =
101             (char)(GetBaseCode(*bufin) << 2 | GetBaseCode(bufin[1]) >> 4);
102     }
103     if (nprbytes > 2) {
104         *(bufout++) =
105             (char)(GetBaseCode(bufin[1]) << 4 | GetBaseCode(bufin[2]) >> 2);
106     }
107     if (nprbytes > 3) {
108         *(bufout++) = (char)(GetBaseCode(bufin[2]) << 6 | GetBaseCode(bufin[3]));
109     }
110
111     nbytesdecoded -= (4 - nprbytes) & 3;
112
113     return nbytesdecoded;
114 }
115
116 //#define TEST_CONVERSION(in_string, out_string, buffer_type, function
117
118 const char utf32Encoded[] =
119     "RDAAAI0wAABvMAAAazAAAHswAAB4MAAAaDAAAAAwAABhMAAAijAAAGwwAACLMAAAkjAAAAAwAACP\
120 MAAASzAAAIgwAABfMAAAjDAAAF0wAAAAMAAAZDAAAG0wAABqMAAAiTAAAIAwAAAAMAAARjAAAJAw\
121 AABuMAAASjAAAE8wAACEMAAAfjAAAAAwAABRMAAAdTAAAFMwAABIMAAAZjAAAAAwAABCMAAAVTAA\
122 AE0wAACGMAAAgTAAAH8wAABXMAAAADAAAJEwAAByMAAAgjAAAFswAABZMAAACgAAANsFAADaBQAA\
123 IAAAANQFAADqBQAA6AUAAOEFAADnBQAAIAAAAOAFAADkBQAA5QUAACAAAADiBQAA3AUAACAAAADS\
124 BQAA1QUAANYFAADcBQAAIAAAAOcFAADYBQAA3wUAACwAAAAgAAAA6QUAANMFAADXBQAA4wUAACAA\
125 AADQBQAA6gUAACAAAADmBQAA0QUAANkFAAAgAAAA3AUAAN4FAADZBQAA3QUAAAoAAACk0AAApMIA\
126 AFjHAAAgAAAA4KwAACDHAABwyAAAdKwAAEDHAAAgAAAAhccAACDCAAB8sAAArLkAACAAAADMuQAA\
127 mLAAAHzFAAAgAAAAWNUAAOCsAAAgAAAAudIAAMS8AABc1QAAIAAAADCuAAAgwgAAQMcAACAAAABE\
128 1QAAlMYAAFjOAAAgAAAASsUAAOSyAAAKAAAAUAAAAGMAAABoAAAAbgAAAAUBAAAHAQAAIAAAAHcA\
129 AAAgAAAAdAAAABkBAAAgAAAAQgEAAPMAAABkAAAAegEAACAAAABqAAAAZQAAAHwBAABhAAAAIAAA\
130 AGwAAAB1AAAAYgAAACAAAABvAAAAWwEAAG0AAAAgAAAAcwAAAGsAAAByAAAAegAAAHkAAABEAQAA\
131 IAAAAGYAAABpAAAAZwAAAC4AAAAKAAAAQgAAAGwAAABvAAAAdwAAAHoAAAB5AAAAIAAAAG4AAABp\
132 AAAAZwAAAGgAAAB0AAAALQAAAGYAAAByAAAAdQAAAG0AAABwAAAAcwAAACAAAAB2AAAAZQAAAHgA\
133 AAAnAAAAZAAAACAAAABKAAAAYQAAAGMAAABrAAAAIAAAAFEAAAAuAAAACgAAAEYGAAA1BgAAIAAA\
134 AC0GAABDBgAASgYAAEUGAAAgAAAARAYAAEcGAAAgAAAAMwYAADEGAAAgAAAAQgYAACcGAAA3BgAA\
135 OQYAACAAAABIBgAAMAYAAEgGAAAgAAAANAYAACMGAABGBgAAIAAAADkGAAA4BgAASgYAAEUGAAAg\
136 AAAARQYAAEMGAAAqBgAASAYAACgGAAAgAAAAOQYAAEQGAABJBgAAIAAAACsGAABIBgAAKAYAACAA\
137 AAAjBgAALgYAADYGAAAxBgAAIAAAAEgGAABFBgAAOgYAAEQGAABBBgAAIAAAACgGAAAsBgAARAYA\
138 AC8GAAAgAAAAIwYAADIGAAAxBgAAQgYAACAAAAAKAAAAEgQAACAAAABHBAAAMAQAAEkEAAAwBAAA\
139 RQQAACAAAABOBAAAMwQAADAEAAAgAAAANgQAADgEAAA7BAAAIAAAADEEAABLBAAAIAAAAEYEAAA4\
140 BAAAQgQAAEAEAABDBAAAQQQAAD8AAAAgAAAAFAQAADAEAAAsAAAAIAAAAD0EAAA+BAAAIAAAAEQE\
141 AAAwBAAAOwQAAEwEAABIBAAAOAQAADIEAABLBAAAOQQAACAAAABNBAAAOgQAADcEAAA1BAAAPAQA\
142 AD8EAAA7BAAATwQAAEAEAAAhAAAACgAAAKQDAACsAwAAxwMAALkDAADDAwAAxAMAALcDAAAgAAAA\
143 sQMAALsDAADOAwAAwAMAALcDAAC+AwAAIAAAALIDAACxAwAAxgMAAK4DAADCAwAAIAAAAMgDAAC3\
144 AwAAvAMAAK0DAAC9AwAAtwMAACAAAACzAwAAtwMAACwAAAAgAAAAtAMAAMEDAACxAwAAwwMAALoD\
145 AAC1AwAAuwMAAK8DAAC2AwAAtQMAALkDAAAgAAAAxQMAAMADAACtAwAAwQMAACAAAAC9AwAAyQMA\
146 ALgDAADBAwAAvwMAAM0DAAAgAAAAugMAAMUDAAC9AwAAzAMAAMIDAAAKAAAAVgAAAGkAAABjAAAA\
147 dAAAAG8AAAByAAAAIAAAAGoAAABhAAAAZwAAAHQAAAAgAAAAegAAAHcAAAD2AAAAbAAAAGYAAAAg\
148 AAAAQgAAAG8AAAB4AAAAawAAAOQAAABtAAAAcAAAAGYAAABlAAAAcgAAACAAAABxAAAAdQAAAGUA\
149 AAByAAAAIAAAAPwAAABiAAAAZQAAAHIAAAAgAAAAZAAAAGUAAABuAAAAIAAAAGcAAAByAAAAbwAA\
150 AN8AAABlAAAAbgAAACAAAABTAAAAeQAAAGwAAAB0AAAAZQAAAHIAAAAgAAAARAAAAGUAAABpAAAA\
151 YwAAAGgAAAAKAAAAlokAAM6RAAAhcQAAUJYAAONeAAAM/wAAl3oAABZZAAAJZwAAzYUAAClZAAAK\
152 AAAACgAAAAAAAAA=";
153
154 const char utf8Encoded[] =
155     "44GE44KN44Gv44Gr44G744G444Go44CA44Gh44KK44Gs44KL44KS44CA44KP44GL44KI44Gf44KM\
156 44Gd44CA44Gk44Gt44Gq44KJ44KA44CA44GG44KQ44Gu44GK44GP44KE44G+44CA44GR44G144GT\
157 44GI44Gm44CA44GC44GV44GN44KG44KB44G/44GX44CA44KR44Gy44KC44Gb44GZCteb15og15TX\
158 qteo16HXpyDXoNek16Ug16LXnCDXkteV15bXnCDXp9eY158sINep15PXl9ejINeQ16og16bXkdeZ\
159 INec157XmdedCu2CpOyKpOydmCDqs6DsnKDsobDqsbTsnYAg7J6F7Iig64G866asIOunjOuCmOyV\
160 vCDtlZjqs6Ag7Yq567OE7ZWcIOq4sOyIoOydgCDtlYTsmpTsuZgg7JWK64ukClBjaG7EhcSHIHcg\
161 dMSZIMWCw7NkxbogamXFvGEgbHViIG/Fm20gc2tyennFhCBmaWcuCkJsb3d6eSBuaWdodC1mcnVt\
162 cHMgdmV4J2QgSmFjayBRLgrZhti1INit2YPZitmFINmE2Ycg2LPYsSDZgtin2LfYuSDZiNiw2Ygg\
163 2LTYo9mGINi52LjZitmFINmF2YPYqtmI2Kgg2LnZhNmJINir2YjYqCDYo9iu2LbYsSDZiNmF2LrZ\
164 hNmBINio2KzZhNivINij2LLYsdmCIArQkiDRh9Cw0YnQsNGFINGO0LPQsCDQttC40Lsg0LHRiyDR\
165 htC40YLRgNGD0YE/INCU0LAsINC90L4g0YTQsNC70YzRiNC40LLRi9C5INGN0LrQt9C10LzQv9C7\
166 0Y/RgCEKzqTOrM+HzrnPg8+EzrcgzrHOu8+Oz4DOt86+IM6yzrHPhs6uz4Igz4jOt868zq3Ovc63\
167 IM6zzrcsIM60z4HOsc+DzrrOtc67zq/Ots61zrkgz4XPgM6tz4Egzr3Pic64z4HOv8+NIM66z4XO\
168 vc+Mz4IKVmljdG9yIGphZ3QgenfDtmxmIEJveGvDpG1wZmVyIHF1ZXIgw7xiZXIgZGVuIGdyb8Of\
169 ZW4gU3lsdGVyIERlaWNoCuimlumHjueEoemZkOW7o++8jOeql+WkluacieiXjeWkqQoKAA==";
170
171 const char asciiEncodedIso1[] =
172     "ISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZ\
173 WltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fgA=";
174
175 const char asciiEncodedUtf32[] =
176     "IQAAACIAAAAjAAAAJAAAACUAAAAmAAAAJwAAACgAAAApAAAAKgAAACsAAAAsAAAALQAAAC4AAAAv\
177 AAAAMAAAADEAAAAyAAAAMwAAADQAAAA1AAAANgAAADcAAAA4AAAAOQAAADoAAAA7AAAAPAAAAD0A\
178 AAA+AAAAPwAAAEAAAABBAAAAQgAAAEMAAABEAAAARQAAAEYAAABHAAAASAAAAEkAAABKAAAASwAA\
179 AEwAAABNAAAATgAAAE8AAABQAAAAUQAAAFIAAABTAAAAVAAAAFUAAABWAAAAVwAAAFgAAABZAAAA\
180 WgAAAFsAAABcAAAAXQAAAF4AAABfAAAAYAAAAGEAAABiAAAAYwAAAGQAAABlAAAAZgAAAGcAAABo\
181 AAAAaQAAAGoAAABrAAAAbAAAAG0AAABuAAAAbwAAAHAAAABxAAAAcgAAAHMAAAB0AAAAdQAAAHYA\
182 AAB3AAAAeAAAAHkAAAB6AAAAewAAAHwAAAB9AAAAfgAAAAAAAAA=";
183
184 /*
185 Name: String_ConverterFromASCII
186 Description: tests construction of string from ascii data
187 Expected: data stored in buffer should match expected
188 */
189 RUNNER_TEST(String_ConverterFromASCII)
190 {
191     char* inStr = NULL;
192     int inSize = wbxml_base64_decode(asciiEncodedIso1, &inStr);
193     RUNNER_ASSERT(inSize > 0);
194     RUNNER_ASSERT(NULL != inStr);
195     inStr[inSize] = '\0';
196     {
197         DPL::String asciiString = DPL::FromASCIIString(inStr);
198
199         std::string result = DPL::ToUTF8String(asciiString);
200
201         RUNNER_ASSERT(strlen(inStr) == result.size());
202
203         RUNNER_ASSERT(0 == memcmp(inStr, result.c_str(), result.size()));
204     }
205
206     free(inStr);
207 }
208
209 /*
210 Name: String_ConverterFromUTF8
211 Description: tests construction of string from UTF-8 data
212 Expected: data stored in buffer should match expected
213 */
214 RUNNER_TEST(String_ConverterFromUTF8)
215 {
216     char* inStr = NULL;
217     int inSize = wbxml_base64_decode(asciiEncodedIso1, &inStr);
218     RUNNER_ASSERT(inSize > 0);
219     RUNNER_ASSERT(NULL != inStr);
220     {
221         DPL::String asciiString = DPL::FromUTF8String(inStr);
222
223         std::string result = DPL::ToUTF8String(asciiString);
224
225         RUNNER_ASSERT(strlen(inStr) == result.size());
226
227         RUNNER_ASSERT(0 == memcmp(inStr, result.c_str(), result.size()));
228     }
229
230     free(inStr);
231 }
232
233 /*
234 Name: String_ConverterFromUTF32
235 Description: tests construction of string from UTF-32 data
236 Expected: data stored in buffer should match expected
237 */
238 RUNNER_TEST(String_ConverterFromUTF32)
239 {
240     wchar_t* inStr = NULL;
241     int inSize =
242         wbxml_base64_decode(utf32Encoded, reinterpret_cast<char**>(&inStr));
243     RUNNER_ASSERT(inSize > 0);
244     RUNNER_ASSERT(NULL != inStr);
245     char* outStr = NULL;
246     int outSize = wbxml_base64_decode(utf8Encoded, &outStr);
247     RUNNER_ASSERT(outSize > 0);
248     RUNNER_ASSERT(NULL != outStr);
249     outStr[outSize] = '\0';
250     {
251         DPL::String utfString = DPL::FromUTF32String(inStr);
252         std::string result = DPL::ToUTF8String(utfString);
253
254         RUNNER_ASSERT(strlen(outStr) == result.size());
255         RUNNER_ASSERT(0 == memcmp(outStr, result.c_str(), result.size()));
256
257         RUNNER_ASSERT(inSize / sizeof(wchar_t) - 1 == utfString.size());
258         RUNNER_ASSERT(0 ==
259                       memcmp(inStr, &(utfString[0]), utfString.size() *
260                              sizeof(wchar_t)));
261     }
262
263     free(inStr);
264 }
265
266 template<typename DelimiterType>
267 void String_TokenizeReal(const DelimiterType& delimiter)
268 {
269     DPL::String str(L".##..abc.#.");
270     std::vector<DPL::String> tokens;
271     DPL::Tokenize(str, delimiter, std::back_inserter(tokens));
272
273     std::vector<DPL::String> expectedTokens;
274     for (int i = 0; i < 5; i++) {
275         expectedTokens.push_back(L"");
276     }
277     expectedTokens.push_back(L"abc");
278     for (int i = 0; i < 3; i++) {
279         expectedTokens.push_back(L"");
280     }
281
282     RUNNER_ASSERT(expectedTokens == tokens);
283     tokens.clear();
284     expectedTokens.clear();
285
286     DPL::Tokenize(str, delimiter, std::back_inserter(tokens), true);
287     expectedTokens.push_back(L"abc");
288     RUNNER_ASSERT(expectedTokens == tokens);
289 }
290
291 /*
292 Name: String_Tokenize
293 Description: tests of string splitting
294 Expected: returned substring should match expected values
295 */
296 RUNNER_TEST(String_Tokenize)
297 {
298     String_TokenizeReal(L"#.");
299     String_TokenizeReal(L".#");
300     String_TokenizeReal(L".....####.###..");
301     String_TokenizeReal(DPL::String(L".#"));
302
303     std::vector<std::string> tokens;
304     DPL::Tokenize(std::string("abc.def"), '.', std::back_inserter(tokens));
305     std::vector<std::string> expectedTokens;
306     expectedTokens.push_back("abc");
307     expectedTokens.push_back("def");
308
309     RUNNER_ASSERT(tokens == expectedTokens);
310 }
311
312 template <typename TemplateArgumentCharTraits>
313 void TestInStreams(
314     std::basic_string<typename TemplateArgumentCharTraits::char_type,
315                       TemplateArgumentCharTraits> argumentInString,
316     std::basic_string<typename TemplateArgumentCharTraits::char_type,
317                       TemplateArgumentCharTraits> argumentResultString)
318 {
319     typedef std::basic_string<typename TemplateArgumentCharTraits::char_type,
320                               TemplateArgumentCharTraits>
321     String;
322     std::basic_istringstream<typename TemplateArgumentCharTraits::char_type,
323                              TemplateArgumentCharTraits>
324     istream(argumentInString);
325     int intValue = 0;
326     double doubleValue = 0.0;
327     float floatValue = 0.0;
328     String stringValue;
329
330     istream >> intValue;
331     RUNNER_ASSERT(!istream.fail());
332     istream >> doubleValue;
333     RUNNER_ASSERT(!istream.fail());
334     istream >> floatValue;
335     RUNNER_ASSERT(!istream.fail());
336     istream >> stringValue;
337     RUNNER_ASSERT(!istream.fail());
338
339     RUNNER_ASSERT(1 == intValue);
340     RUNNER_ASSERT(fabs(1.1f - doubleValue) < 0.00001);
341     RUNNER_ASSERT(fabs(1.1f - floatValue) < 0.00001);
342     RUNNER_ASSERT(argumentResultString == stringValue);
343 }
344
345 template <typename TemplateArgumentCharTraits>
346 void TestOutStreams(
347     std::basic_string<typename TemplateArgumentCharTraits::char_type,
348                       TemplateArgumentCharTraits> argumentInString,
349     std::basic_string<typename TemplateArgumentCharTraits::char_type,
350                       TemplateArgumentCharTraits> argumentResultString)
351 {
352     typedef std::basic_string<typename TemplateArgumentCharTraits::char_type,
353                               TemplateArgumentCharTraits>
354     String;
355
356     std::basic_ostringstream<typename TemplateArgumentCharTraits::char_type,
357                              TemplateArgumentCharTraits>
358     ostream;
359
360     int intValue = 1;
361     double doubleValue = 1.1;
362     float floatValue = 1.1f;
363     String stringValue = argumentInString;
364
365     ostream << intValue;
366     RUNNER_ASSERT(!ostream.fail());
367     ostream << doubleValue;
368     RUNNER_ASSERT(!ostream.fail());
369     ostream << floatValue;
370     RUNNER_ASSERT(!ostream.fail());
371     ostream << stringValue;
372     RUNNER_ASSERT(!ostream.fail());
373
374     RUNNER_ASSERT(ostream.str() == argumentResultString);
375 }
376
377 /*
378 Name: String_Streams
379 Description: tests of input/output stream
380 Expected: returned substrign should match expected values
381 */
382 RUNNER_TEST(String_Streams)
383 {
384     TestInStreams<std::char_traits<char> >("1 1.1 1.1 test", "test");
385     TestInStreams<std::char_traits<wchar_t> >(L"1 1.1 1.1 test", L"test");
386     TestInStreams<DPL::CharTraits>(L"1 1.1 1.1 test", L"test");
387     TestOutStreams<std::char_traits<char> >("test", "11.11.1test");
388     TestOutStreams<std::char_traits<wchar_t> >(L"test", L"11.11.1test");
389     TestOutStreams<DPL::CharTraits>(L"test", L"11.11.1test");
390 }
391
392 /*
393 Name: String_CompareCaseSensitive
394 Description: tests case sensitive comparision
395 Expected: strings should be equal
396 */
397 RUNNER_TEST(String_CompareCaseSensitive)
398 {
399     RUNNER_ASSERT(
400         DPL::StringCompare(
401             DPL::FromUTF32String(L"Ala Makota ma żołądkówkę"),
402             DPL::FromUTF32String(L"Ala Makota ma żołądkówkę")) == 0);
403 }
404
405 /*
406 Name: String_CompareCaseInsensitive
407 Description: tests case insensitive comparision
408 Expected: strings should be equal
409 */
410 RUNNER_TEST(String_CompareCaseInsensitive)
411 {
412     RUNNER_ASSERT(
413         DPL::StringCompare(
414             DPL::FromUTF32String(L"Ala Makota ma żołądkówkę"),
415             DPL::FromUTF32String(L"AlA MakOTA ma ŻoŁąDKÓwkę"),
416             true) == 0);
417 }
418