[Cycles/MSVC/Testing] Fix broken test code.
[blender.git] / tests / gtests / blenlib / BLI_string_test.cc
1 /* Apache License, Version 2.0 */
2
3 #include "testing/testing.h"
4
5 extern "C" {
6 #include "BLI_utildefines.h"
7 #include "BLI_string.h"
8 #include "BLI_string_utf8.h"
9 }
10
11 /* -------------------------------------------------------------------- */
12 /* stubs */
13
14 extern "C" {
15
16 int mk_wcwidth(wchar_t ucs);
17 int mk_wcswidth(const wchar_t *pwcs, size_t n);
18
19 int mk_wcwidth(wchar_t ucs)
20 {
21         return 0;
22 }
23
24 int mk_wcswidth(const wchar_t *pwcs, size_t n)
25 {
26         return 0;
27 }
28
29 }
30
31
32 /* -------------------------------------------------------------------- */
33 /* tests */
34
35 /* BLI_str_partition */
36 TEST(string, StrPartition)
37 {
38         const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
39         const char *sep, *suf;
40         size_t pre_ln;
41
42         {
43                 const char *str = "mat.e-r_ial";
44
45                 /* "mat.e-r_ial" -> "mat", '.', "e-r_ial", 3 */
46                 pre_ln = BLI_str_partition(str, delim, &sep, &suf);
47                 EXPECT_EQ(3, pre_ln);
48                 EXPECT_EQ(&str[3], sep);
49                 EXPECT_STREQ("e-r_ial", suf);
50         }
51
52         /* Corner cases. */
53         {
54                 const char *str = ".mate-rial--";
55
56                 /* ".mate-rial--" -> "", '.', "mate-rial--", 0 */
57                 pre_ln = BLI_str_partition(str, delim, &sep, &suf);
58                 EXPECT_EQ(0, pre_ln);
59                 EXPECT_EQ(&str[0], sep);
60                 EXPECT_STREQ("mate-rial--", suf);
61         }
62
63         {
64                 const char *str = ".__.--_";
65
66                 /* ".__.--_" -> "", '.', "__.--_", 0 */
67                 pre_ln = BLI_str_partition(str, delim, &sep, &suf);
68                 EXPECT_EQ(0, pre_ln);
69                 EXPECT_EQ(&str[0], sep);
70                 EXPECT_STREQ("__.--_", suf);
71         }
72
73         {
74                 const char *str = "";
75
76                 /* "" -> "", NULL, NULL, 0 */
77                 pre_ln = BLI_str_partition(str, delim, &sep, &suf);
78                 EXPECT_EQ(0, pre_ln);
79                 EXPECT_EQ(NULL, sep);
80                 EXPECT_EQ(NULL, suf);
81         }
82
83         {
84                 const char *str = "material";
85
86                 /* "material" -> "material", NULL, NULL, 8 */
87                 pre_ln = BLI_str_partition(str, delim, &sep, &suf);
88                 EXPECT_EQ(8, pre_ln);
89                 EXPECT_EQ(NULL, sep);
90                 EXPECT_EQ(NULL, suf);
91         }
92 }
93
94 /* BLI_str_rpartition */
95 TEST(string, StrRPartition)
96 {
97         const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
98         const char *sep, *suf;
99         size_t pre_ln;
100
101         {
102                 const char *str = "mat.e-r_ial";
103
104                 /* "mat.e-r_ial" -> "mat.e-r", '_', "ial", 7 */
105                 pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
106                 EXPECT_EQ(7, pre_ln);
107                 EXPECT_EQ(&str[7], sep);
108                 EXPECT_STREQ("ial", suf);
109         }
110
111         /* Corner cases. */
112         {
113                 const char *str = ".mate-rial--";
114
115                 /* ".mate-rial--" -> ".mate-rial-", '-', "", 11 */
116                 pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
117                 EXPECT_EQ(11, pre_ln);
118                 EXPECT_EQ(&str[11], sep);
119                 EXPECT_STREQ("", suf);
120         }
121
122         {
123                 const char *str = ".__.--_";
124
125                 /* ".__.--_" -> ".__.--", '_', "", 6 */
126                 pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
127                 EXPECT_EQ(6, pre_ln);
128                 EXPECT_EQ(&str[6], sep);
129                 EXPECT_STREQ("", suf);
130         }
131
132         {
133                 const char *str = "";
134
135                 /* "" -> "", NULL, NULL, 0 */
136                 pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
137                 EXPECT_EQ(0, pre_ln);
138                 EXPECT_EQ(NULL, sep);
139                 EXPECT_EQ(NULL, suf);
140         }
141
142         {
143                 const char *str = "material";
144
145                 /* "material" -> "material", NULL, NULL, 8 */
146                 pre_ln = BLI_str_rpartition(str, delim, &sep, &suf);
147                 EXPECT_EQ(8, pre_ln);
148                 EXPECT_EQ(NULL, sep);
149                 EXPECT_EQ(NULL, suf);
150         }
151 }
152
153 /* BLI_str_partition_ex */
154 TEST(string, StrPartitionEx)
155 {
156         const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
157         const char *sep, *suf;
158         size_t pre_ln;
159
160         /* Only considering 'from_right' cases here. */
161
162         {
163                 const char *str = "mat.e-r_ia.l";
164
165                 /* "mat.e-r_ia.l" over "mat.e-r" -> "mat.e", '.', "r_ia.l", 3 */
166                 pre_ln = BLI_str_partition_ex(str, str + 6, delim, &sep, &suf, true);
167                 EXPECT_EQ(5, pre_ln);
168                 EXPECT_EQ(&str[5], sep);
169                 EXPECT_STREQ("r_ia.l", suf);
170         }
171
172         /* Corner cases. */
173         {
174                 const char *str = "mate.rial";
175
176                 /* "mate.rial" over "mate" -> "mate.rial", NULL, NULL, 4 */
177                 pre_ln = BLI_str_partition_ex(str, str + 4, delim, &sep, &suf, true);
178                 EXPECT_EQ(4, pre_ln);
179                 EXPECT_EQ(NULL, sep);
180                 EXPECT_EQ(NULL, suf);
181         }
182 }
183
184 /* BLI_str_partition_utf8 */
185 TEST(string, StrPartitionUtf8)
186 {
187         const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
188         const char *sep, *suf;
189         size_t pre_ln;
190
191         {
192                 const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
193
194                 /* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
195                 pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
196                 EXPECT_EQ(2, pre_ln);
197                 EXPECT_EQ(&str[2], sep);
198                 EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
199         }
200
201         /* Corner cases. */
202         {
203                 const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
204
205                 /* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "", '\xe2\x98\xaf', "mate-rial-\xc3\xb1", 0 */
206                 pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
207                 EXPECT_EQ(0, pre_ln);
208                 EXPECT_EQ(&str[0], sep);
209                 EXPECT_STREQ("mate-rial-\xc3\xb1", suf);
210         }
211
212         {
213                 const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
214
215                 /* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "", '\xe2\x98\xaf', ".\xc3\xb1_.--\xc3\xb1", 0 */
216                 pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
217                 EXPECT_EQ(0, pre_ln);
218                 EXPECT_EQ(&str[0], sep);
219                 EXPECT_STREQ(".\xc3\xb1_.--\xc3\xb1", suf);
220         }
221
222         {
223                 const char *str = "";
224
225                 /* "" -> "", NULL, NULL, 0 */
226                 pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
227                 EXPECT_EQ(0, pre_ln);
228                 EXPECT_EQ(NULL, sep);
229                 EXPECT_EQ(NULL, suf);
230         }
231
232         {
233                 const char *str = "material";
234
235                 /* "material" -> "material", NULL, NULL, 8 */
236                 pre_ln = BLI_str_partition_utf8(str, delim, &sep, &suf);
237                 EXPECT_EQ(8, pre_ln);
238                 EXPECT_EQ(NULL, sep);
239                 EXPECT_EQ(NULL, suf);
240         }
241 }
242
243 /* BLI_str_rpartition_utf8 */
244 TEST(string, StrRPartitionUtf8)
245 {
246         const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
247         const char *sep, *suf;
248         size_t pre_ln;
249
250         {
251                 const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
252
253                 /* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "mat\xc3\xb1te-r", '\xe2\x98\xaf', "ial", 8 */
254                 pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
255                 EXPECT_EQ(8, pre_ln);
256                 EXPECT_EQ(&str[8], sep);
257                 EXPECT_STREQ("ial", suf);
258         }
259
260         /* Corner cases. */
261         {
262                 const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
263
264                 /* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "\xe2\x98\xafmate-rial-", '\xc3\xb1', "", 13 */
265                 pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
266                 EXPECT_EQ(13, pre_ln);
267                 EXPECT_EQ(&str[13], sep);
268                 EXPECT_STREQ("", suf);
269         }
270
271         {
272                 const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
273
274                 /* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "\xe2\x98\xaf.\xc3\xb1_.--", '\xc3\xb1', "", 10 */
275                 pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
276                 EXPECT_EQ(10, pre_ln);
277                 EXPECT_EQ(&str[10], sep);
278                 EXPECT_STREQ("", suf);
279         }
280
281         {
282                 const char *str = "";
283
284                 /* "" -> "", NULL, NULL, 0 */
285                 pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
286                 EXPECT_EQ(0, pre_ln);
287                 EXPECT_EQ(NULL, sep);
288                 EXPECT_EQ(NULL, suf);
289         }
290
291         {
292                 const char *str = "material";
293
294                 /* "material" -> "material", NULL, NULL, 8 */
295                 pre_ln = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
296                 EXPECT_EQ(8, pre_ln);
297                 EXPECT_EQ(NULL, sep);
298                 EXPECT_EQ(NULL, suf);
299         }
300 }
301
302 /* BLI_str_partition_ex_utf8 */
303 TEST(string, StrPartitionExUtf8)
304 {
305         const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
306         const char *sep, *suf;
307         size_t pre_ln;
308
309         /* Only considering 'from_right' cases here. */
310
311         {
312                 const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
313
314                 /* "ma\xc3\xb1te-r\xe2\x98\xafial" over "ma\xc3\xb1te" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
315                 pre_ln = BLI_str_partition_ex_utf8(str, str + 6, delim, &sep, &suf, true);
316                 EXPECT_EQ(2, pre_ln);
317                 EXPECT_EQ(&str[2], sep);
318                 EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
319         }
320
321         /* Corner cases. */
322         {
323                 const char *str = "mate\xe2\x98\xafrial";
324
325                 /* "mate\xe2\x98\xafrial" over "mate" -> "mate\xe2\x98\xafrial", NULL, NULL, 4 */
326                 pre_ln = BLI_str_partition_ex_utf8(str, str + 4, delim, &sep, &suf, true);
327                 EXPECT_EQ(4, pre_ln);
328                 EXPECT_EQ(NULL, sep);
329                 EXPECT_EQ(NULL, suf);
330         }
331 }
332
333 /* BLI_str_format_int_grouped */
334 TEST(string, StrFormatIntGrouped)
335 {
336         char num_str[16];
337         int num;
338
339         BLI_str_format_int_grouped(num_str, num = 0);
340         EXPECT_STREQ("0", num_str);
341
342         BLI_str_format_int_grouped(num_str, num = 1);
343         EXPECT_STREQ("1", num_str);
344
345         BLI_str_format_int_grouped(num_str, num = -1);
346         EXPECT_STREQ("-1", num_str);
347
348         BLI_str_format_int_grouped(num_str, num = -2147483648);
349         EXPECT_STREQ("-2,147,483,648", num_str);
350
351         BLI_str_format_int_grouped(num_str, num = 2147483647);
352         EXPECT_STREQ("2,147,483,647", num_str);
353
354         BLI_str_format_int_grouped(num_str, num = 1000);
355         EXPECT_STREQ("1,000", num_str);
356
357         BLI_str_format_int_grouped(num_str, num = -1000);
358         EXPECT_STREQ("-1,000", num_str);
359
360         BLI_str_format_int_grouped(num_str, num = 999);
361         EXPECT_STREQ("999", num_str);
362
363         BLI_str_format_int_grouped(num_str, num = -999);
364         EXPECT_STREQ("-999", num_str);
365 }
366
367 #define STRING_FIND_SPLIT_WORDS_EX(word_str_src, word_str_src_len, limit_words, ...) \
368 { \
369         int word_info[][2] = \
370                 {{-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}}; \
371         const int word_cmp[][2] = __VA_ARGS__; \
372         const int word_cmp_size_input = ARRAY_SIZE(word_cmp) - (limit_words ? 1 : 0); \
373         const int word_cmp_size = ARRAY_SIZE(word_cmp); \
374         const int word_num = BLI_string_find_split_words( \
375                 word_str_src, word_str_src_len, ' ', word_info, word_cmp_size_input); \
376         EXPECT_EQ(word_num, word_cmp_size - 1); \
377         EXPECT_EQ_ARRAY_ND<const int[2]>(word_cmp, word_info, word_cmp_size, 2); \
378 } ((void)0)
379
380 #define STRING_FIND_SPLIT_WORDS(word_str_src, ...) \
381         STRING_FIND_SPLIT_WORDS_EX(word_str_src, strlen(word_str_src), false, __VA_ARGS__)
382
383 /* BLI_string_find_split_words */
384 TEST(string, StringFindSplitWords_Single)
385 {
386         STRING_FIND_SPLIT_WORDS("t",    {{0, 1}, {-1, -1}});
387         STRING_FIND_SPLIT_WORDS("test", {{0, 4}, {-1, -1}});
388 }
389 TEST(string, StringFindSplitWords_Triple)
390 {
391         STRING_FIND_SPLIT_WORDS("f t w",            {{0, 1}, {2, 1}, {4, 1}, {-1, -1}});
392         STRING_FIND_SPLIT_WORDS("find three words", {{0, 4}, {5, 5}, {11, 5}, {-1, -1}});
393 }
394 TEST(string, StringFindSplitWords_Spacing)
395 {
396         STRING_FIND_SPLIT_WORDS("# ## ### ####",   {{0, 1}, {2, 2}, {5, 3}, {9, 4}, {-1, -1}});
397         STRING_FIND_SPLIT_WORDS("#  #   #    #",   {{0, 1}, {3, 1}, {7, 1}, {12, 1}, {-1, -1}});
398 }
399 TEST(string, StringFindSplitWords_Trailing_Left)
400 {
401         STRING_FIND_SPLIT_WORDS("   t",    {{3, 1}, {-1, -1}});
402         STRING_FIND_SPLIT_WORDS("   test", {{3, 4}, {-1, -1}});
403 }
404 TEST(string, StringFindSplitWords_Trailing_Right)
405 {
406         STRING_FIND_SPLIT_WORDS("t   ",    {{0, 1}, {-1, -1}});
407         STRING_FIND_SPLIT_WORDS("test   ", {{0, 4}, {-1, -1}});
408 }
409 TEST(string, StringFindSplitWords_Trailing_LeftRight)
410 {
411         STRING_FIND_SPLIT_WORDS("   surrounding space test   123   ", {{3, 11}, {15, 5}, {21, 4}, {28, 3}, {-1, -1}});
412 }
413 TEST(string, StringFindSplitWords_Blank)
414 {
415         STRING_FIND_SPLIT_WORDS("", {{-1, -1}});
416 }
417 TEST(string, StringFindSplitWords_Whitespace)
418 {
419         STRING_FIND_SPLIT_WORDS(" ",    {{-1, -1}});
420         STRING_FIND_SPLIT_WORDS("    ", {{-1, -1}});
421 }
422 TEST(string, StringFindSplitWords_LimitWords)
423 {
424         const char *words = "too many words";
425         const int words_len = strlen(words);
426         STRING_FIND_SPLIT_WORDS_EX(words, words_len, false, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}});
427         STRING_FIND_SPLIT_WORDS_EX(words, words_len, true,  {{0, 3}, {4, 4}, {-1, -1}});
428         STRING_FIND_SPLIT_WORDS_EX(words, words_len, true,  {{0, 3}, {-1, -1}});
429         STRING_FIND_SPLIT_WORDS_EX(words, words_len, true,  {{-1, -1}});
430 }
431 TEST(string, StringFindSplitWords_LimitChars)
432 {
433         const char *words = "too many chars";
434         const int words_len = strlen(words);
435         STRING_FIND_SPLIT_WORDS_EX(words, words_len,      false, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}});
436         STRING_FIND_SPLIT_WORDS_EX(words, words_len -  1, false, {{0, 3}, {4, 4}, {9, 4}, {-1, -1}});
437         STRING_FIND_SPLIT_WORDS_EX(words, words_len -  5, false, {{0, 3}, {4, 4}, {-1, -1}});
438         STRING_FIND_SPLIT_WORDS_EX(words, 1,              false, {{0, 1}, {-1, -1}});
439         STRING_FIND_SPLIT_WORDS_EX(words, 0,              false, {{-1, -1}});
440 }
441
442 #undef STRING_FIND_SPLIT_WORDS
443
444
445 /* BLI_strncasestr */
446 TEST(string, StringStrncasestr)
447 {
448         const char *str_test0 = "search here";
449         const char *res;
450
451         res = BLI_strncasestr(str_test0, "", 0);
452         EXPECT_EQ(str_test0, res);
453
454         res = BLI_strncasestr(str_test0, " ", 1);
455         EXPECT_EQ(str_test0 + 6, res);
456
457         res = BLI_strncasestr(str_test0, "her", 3);
458         EXPECT_EQ(str_test0 + 7, res);
459
460         res = BLI_strncasestr(str_test0, "ARCh", 4);
461         EXPECT_EQ(str_test0 + 2, res);
462
463         res = BLI_strncasestr(str_test0, "earcq", 4);
464         EXPECT_EQ(str_test0 + 1, res);
465
466         res = BLI_strncasestr(str_test0, "not there", 9);
467         EXPECT_EQ(NULL, res);
468 }