Blender  V2.93
BLI_string_test.cc
Go to the documentation of this file.
1 /* Apache License, Version 2.0 */
2 
3 #include "testing/testing.h"
4 
5 #include <array>
6 #include <initializer_list>
7 #include <ostream> /* NOLINT */
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include "BLI_string.h"
13 #include "BLI_string_utf8.h"
14 #include "BLI_string_utils.h"
15 #include "BLI_utildefines.h"
16 
17 using std::initializer_list;
18 using std::pair;
19 using std::string;
20 using std::vector;
21 
22 /* -------------------------------------------------------------------- */
23 /* tests */
24 
25 /* BLI_str_partition */
26 TEST(string, StrPartition)
27 {
28  const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
29  const char *sep, *suf;
30  size_t pre_len;
31 
32  {
33  const char *str = "mat.e-r_ial";
34 
35  /* "mat.e-r_ial" -> "mat", '.', "e-r_ial", 3 */
36  pre_len = BLI_str_partition(str, delim, &sep, &suf);
37  EXPECT_EQ(pre_len, 3);
38  EXPECT_EQ(&str[3], sep);
39  EXPECT_STREQ("e-r_ial", suf);
40  }
41 
42  /* Corner cases. */
43  {
44  const char *str = ".mate-rial--";
45 
46  /* ".mate-rial--" -> "", '.', "mate-rial--", 0 */
47  pre_len = BLI_str_partition(str, delim, &sep, &suf);
48  EXPECT_EQ(pre_len, 0);
49  EXPECT_EQ(&str[0], sep);
50  EXPECT_STREQ("mate-rial--", suf);
51  }
52 
53  {
54  const char *str = ".__.--_";
55 
56  /* ".__.--_" -> "", '.', "__.--_", 0 */
57  pre_len = BLI_str_partition(str, delim, &sep, &suf);
58  EXPECT_EQ(pre_len, 0);
59  EXPECT_EQ(&str[0], sep);
60  EXPECT_STREQ("__.--_", suf);
61  }
62 
63  {
64  const char *str = "";
65 
66  /* "" -> "", NULL, NULL, 0 */
67  pre_len = BLI_str_partition(str, delim, &sep, &suf);
68  EXPECT_EQ(pre_len, 0);
69  EXPECT_EQ(sep, (void *)nullptr);
70  EXPECT_EQ(suf, (void *)nullptr);
71  }
72 
73  {
74  const char *str = "material";
75 
76  /* "material" -> "material", NULL, NULL, 8 */
77  pre_len = BLI_str_partition(str, delim, &sep, &suf);
78  EXPECT_EQ(pre_len, 8);
79  EXPECT_EQ(sep, (void *)nullptr);
80  EXPECT_EQ(suf, (void *)nullptr);
81  }
82 }
83 
84 /* BLI_str_rpartition */
85 TEST(string, StrRPartition)
86 {
87  const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
88  const char *sep, *suf;
89  size_t pre_len;
90 
91  {
92  const char *str = "mat.e-r_ial";
93 
94  /* "mat.e-r_ial" -> "mat.e-r", '_', "ial", 7 */
95  pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
96  EXPECT_EQ(pre_len, 7);
97  EXPECT_EQ(&str[7], sep);
98  EXPECT_STREQ("ial", suf);
99  }
100 
101  /* Corner cases. */
102  {
103  const char *str = ".mate-rial--";
104 
105  /* ".mate-rial--" -> ".mate-rial-", '-', "", 11 */
106  pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
107  EXPECT_EQ(pre_len, 11);
108  EXPECT_EQ(&str[11], sep);
109  EXPECT_STREQ("", suf);
110  }
111 
112  {
113  const char *str = ".__.--_";
114 
115  /* ".__.--_" -> ".__.--", '_', "", 6 */
116  pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
117  EXPECT_EQ(pre_len, 6);
118  EXPECT_EQ(&str[6], sep);
119  EXPECT_STREQ("", suf);
120  }
121 
122  {
123  const char *str = "";
124 
125  /* "" -> "", NULL, NULL, 0 */
126  pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
127  EXPECT_EQ(pre_len, 0);
128  EXPECT_EQ(sep, (void *)nullptr);
129  EXPECT_EQ(suf, (void *)nullptr);
130  }
131 
132  {
133  const char *str = "material";
134 
135  /* "material" -> "material", NULL, NULL, 8 */
136  pre_len = BLI_str_rpartition(str, delim, &sep, &suf);
137  EXPECT_EQ(pre_len, 8);
138  EXPECT_EQ(sep, (void *)nullptr);
139  EXPECT_EQ(suf, (void *)nullptr);
140  }
141 }
142 
143 /* BLI_str_partition_ex */
144 TEST(string, StrPartitionEx)
145 {
146  const char delim[] = {'-', '.', '_', '~', '\\', '\0'};
147  const char *sep, *suf;
148  size_t pre_len;
149 
150  /* Only considering 'from_right' cases here. */
151 
152  {
153  const char *str = "mat.e-r_ia.l";
154 
155  /* "mat.e-r_ia.l" over "mat.e-r" -> "mat.e", '.', "r_ia.l", 3 */
156  pre_len = BLI_str_partition_ex(str, str + 6, delim, &sep, &suf, true);
157  EXPECT_EQ(pre_len, 5);
158  EXPECT_EQ(&str[5], sep);
159  EXPECT_STREQ("r_ia.l", suf);
160  }
161 
162  /* Corner cases. */
163  {
164  const char *str = "mate.rial";
165 
166  /* "mate.rial" over "mate" -> "mate.rial", NULL, NULL, 4 */
167  pre_len = BLI_str_partition_ex(str, str + 4, delim, &sep, &suf, true);
168  EXPECT_EQ(pre_len, 4);
169  EXPECT_EQ(sep, (void *)nullptr);
170  EXPECT_EQ(suf, (void *)nullptr);
171  }
172 }
173 
174 /* BLI_str_partition_utf8 */
175 TEST(string, StrPartitionUtf8)
176 {
177  const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
178  const char *sep, *suf;
179  size_t pre_len;
180 
181  {
182  const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
183 
184  /* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
185  pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
186  EXPECT_EQ(pre_len, 2);
187  EXPECT_EQ(&str[2], sep);
188  EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
189  }
190 
191  /* Corner cases. */
192  {
193  const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
194 
195  /* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "", '\xe2\x98\xaf', "mate-rial-\xc3\xb1", 0 */
196  pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
197  EXPECT_EQ(pre_len, 0);
198  EXPECT_EQ(&str[0], sep);
199  EXPECT_STREQ("mate-rial-\xc3\xb1", suf);
200  }
201 
202  {
203  const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
204 
205  /* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "", '\xe2\x98\xaf', ".\xc3\xb1_.--\xc3\xb1", 0 */
206  pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
207  EXPECT_EQ(pre_len, 0);
208  EXPECT_EQ(&str[0], sep);
209  EXPECT_STREQ(".\xc3\xb1_.--\xc3\xb1", suf);
210  }
211 
212  {
213  const char *str = "";
214 
215  /* "" -> "", NULL, NULL, 0 */
216  pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
217  EXPECT_EQ(pre_len, 0);
218  EXPECT_EQ(sep, (void *)nullptr);
219  EXPECT_EQ(suf, (void *)nullptr);
220  }
221 
222  {
223  const char *str = "material";
224 
225  /* "material" -> "material", NULL, NULL, 8 */
226  pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf);
227  EXPECT_EQ(pre_len, 8);
228  EXPECT_EQ(sep, (void *)nullptr);
229  EXPECT_EQ(suf, (void *)nullptr);
230  }
231 }
232 
233 /* BLI_str_rpartition_utf8 */
234 TEST(string, StrRPartitionUtf8)
235 {
236  const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
237  const char *sep, *suf;
238  size_t pre_len;
239 
240  {
241  const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
242 
243  /* "ma\xc3\xb1te-r\xe2\x98\xafial" -> "mat\xc3\xb1te-r", '\xe2\x98\xaf', "ial", 8 */
244  pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
245  EXPECT_EQ(pre_len, 8);
246  EXPECT_EQ(&str[8], sep);
247  EXPECT_STREQ("ial", suf);
248  }
249 
250  /* Corner cases. */
251  {
252  const char *str = "\xe2\x98\xafmate-rial-\xc3\xb1";
253 
254  /* "\xe2\x98\xafmate-rial-\xc3\xb1" -> "\xe2\x98\xafmate-rial-", '\xc3\xb1', "", 13 */
255  pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
256  EXPECT_EQ(pre_len, 13);
257  EXPECT_EQ(&str[13], sep);
258  EXPECT_STREQ("", suf);
259  }
260 
261  {
262  const char *str = "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1";
263 
264  /* "\xe2\x98\xaf.\xc3\xb1_.--\xc3\xb1" -> "\xe2\x98\xaf.\xc3\xb1_.--", '\xc3\xb1', "", 10 */
265  pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
266  EXPECT_EQ(pre_len, 10);
267  EXPECT_EQ(&str[10], sep);
268  EXPECT_STREQ("", suf);
269  }
270 
271  {
272  const char *str = "";
273 
274  /* "" -> "", NULL, NULL, 0 */
275  pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
276  EXPECT_EQ(pre_len, 0);
277  EXPECT_EQ(sep, (void *)nullptr);
278  EXPECT_EQ(suf, (void *)nullptr);
279  }
280 
281  {
282  const char *str = "material";
283 
284  /* "material" -> "material", NULL, NULL, 8 */
285  pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf);
286  EXPECT_EQ(pre_len, 8);
287  EXPECT_EQ(sep, (void *)nullptr);
288  EXPECT_EQ(suf, (void *)nullptr);
289  }
290 }
291 
292 /* BLI_str_partition_ex_utf8 */
293 TEST(string, StrPartitionExUtf8)
294 {
295  const unsigned int delim[] = {'-', '.', '_', 0x00F1 /* n tilde */, 0x262F /* ying-yang */, '\0'};
296  const char *sep, *suf;
297  size_t pre_len;
298 
299  /* Only considering 'from_right' cases here. */
300 
301  {
302  const char *str = "ma\xc3\xb1te-r\xe2\x98\xafial";
303 
304  /* "ma\xc3\xb1te-r\xe2\x98\xafial" over
305  * "ma\xc3\xb1te" -> "ma", '\xc3\xb1', "te-r\xe2\x98\xafial", 2 */
306  pre_len = BLI_str_partition_ex_utf8(str, str + 6, delim, &sep, &suf, true);
307  EXPECT_EQ(pre_len, 2);
308  EXPECT_EQ(&str[2], sep);
309  EXPECT_STREQ("te-r\xe2\x98\xafial", suf);
310  }
311 
312  /* Corner cases. */
313  {
314  const char *str = "mate\xe2\x98\xafrial";
315 
316  /* "mate\xe2\x98\xafrial" over "mate" -> "mate\xe2\x98\xafrial", NULL, NULL, 4 */
317  pre_len = BLI_str_partition_ex_utf8(str, str + 4, delim, &sep, &suf, true);
318  EXPECT_EQ(pre_len, 4);
319  EXPECT_EQ(sep, (void *)nullptr);
320  EXPECT_EQ(suf, (void *)nullptr);
321  }
322 }
323 
324 /* BLI_str_format_int_grouped */
325 TEST(string, StrFormatIntGrouped)
326 {
327  char num_str[16];
328  int num;
329 
330  BLI_str_format_int_grouped(num_str, num = 0);
331  EXPECT_STREQ("0", num_str);
332 
333  BLI_str_format_int_grouped(num_str, num = 1);
334  EXPECT_STREQ("1", num_str);
335 
336  BLI_str_format_int_grouped(num_str, num = -1);
337  EXPECT_STREQ("-1", num_str);
338 
339  BLI_str_format_int_grouped(num_str, num = -2147483648);
340  EXPECT_STREQ("-2,147,483,648", num_str);
341 
342  BLI_str_format_int_grouped(num_str, num = 2147483647);
343  EXPECT_STREQ("2,147,483,647", num_str);
344 
345  BLI_str_format_int_grouped(num_str, num = 1000);
346  EXPECT_STREQ("1,000", num_str);
347 
348  BLI_str_format_int_grouped(num_str, num = -1000);
349  EXPECT_STREQ("-1,000", num_str);
350 
351  BLI_str_format_int_grouped(num_str, num = 999);
352  EXPECT_STREQ("999", num_str);
353 
354  BLI_str_format_int_grouped(num_str, num = -999);
355  EXPECT_STREQ("-999", num_str);
356 }
357 
358 /* BLI_str_format_byte_unit */
359 TEST(string, StrFormatByteUnits)
360 {
361  char size_str[15];
362  long long int size;
363 
364  /* Base 10 */
365  BLI_str_format_byte_unit(size_str, size = 0, true);
366  EXPECT_STREQ("0 B", size_str);
367  BLI_str_format_byte_unit(size_str, size = -0, true);
368  EXPECT_STREQ("0 B", size_str);
369 
370  BLI_str_format_byte_unit(size_str, size = 1, true);
371  EXPECT_STREQ("1 B", size_str);
372  BLI_str_format_byte_unit(size_str, size = -1, true);
373  EXPECT_STREQ("-1 B", size_str);
374 
375  BLI_str_format_byte_unit(size_str, size = 1000, true);
376  EXPECT_STREQ("1 KB", size_str);
377  BLI_str_format_byte_unit(size_str, size = -1000, true);
378  EXPECT_STREQ("-1 KB", size_str);
379 
380  BLI_str_format_byte_unit(size_str, size = 1024, true);
381  EXPECT_STREQ("1 KB", size_str);
382  BLI_str_format_byte_unit(size_str, size = -1024, true);
383  EXPECT_STREQ("-1 KB", size_str);
384 
385  /* LLONG_MAX - largest possible value */
386  BLI_str_format_byte_unit(size_str, size = 9223372036854775807, true);
387  EXPECT_STREQ("9223.372 PB", size_str);
388  BLI_str_format_byte_unit(size_str, size = -9223372036854775807, true);
389  EXPECT_STREQ("-9223.372 PB", size_str);
390 
391  /* Base 2 */
392  BLI_str_format_byte_unit(size_str, size = 0, false);
393  EXPECT_STREQ("0 B", size_str);
394  BLI_str_format_byte_unit(size_str, size = -0, false);
395  EXPECT_STREQ("0 B", size_str);
396 
397  BLI_str_format_byte_unit(size_str, size = 1, false);
398  EXPECT_STREQ("1 B", size_str);
399  BLI_str_format_byte_unit(size_str, size = -1, false);
400  EXPECT_STREQ("-1 B", size_str);
401 
402  BLI_str_format_byte_unit(size_str, size = 1000, false);
403  EXPECT_STREQ("1000 B", size_str);
404  BLI_str_format_byte_unit(size_str, size = -1000, false);
405  EXPECT_STREQ("-1000 B", size_str);
406 
407  BLI_str_format_byte_unit(size_str, size = 1024, false);
408  EXPECT_STREQ("1 KiB", size_str);
409  BLI_str_format_byte_unit(size_str, size = -1024, false);
410  EXPECT_STREQ("-1 KiB", size_str);
411 
412  /* LLONG_MAX - largest possible value */
413  BLI_str_format_byte_unit(size_str, size = 9223372036854775807, false);
414  EXPECT_STREQ("8192.0 PiB", size_str);
415  BLI_str_format_byte_unit(size_str, size = -9223372036854775807, false);
416  EXPECT_STREQ("-8192.0 PiB", size_str);
417 
418  /* Test maximum string length. */
419  BLI_str_format_byte_unit(size_str, size = -9223200000000000000, false);
420  EXPECT_STREQ("-8191.8472 PiB", size_str);
421 }
422 
423 struct WordInfo {
425  {
426  }
427  WordInfo(int start, int end) : start(start), end(end)
428  {
429  }
430  bool operator==(const WordInfo &other) const
431  {
432  return start == other.start && end == other.end;
433  }
434  int start, end;
435 };
436 static std::ostream &operator<<(std::ostream &os, const WordInfo &word_info)
437 {
438  os << "start: " << word_info.start << ", end: " << word_info.end;
439  return os;
440 }
441 
442 class StringFindSplitWords : public testing::Test {
443  protected:
445  {
446  }
447 
448  /* If max_words is -1 it will be initialized from the number of expected
449  * words +1. This way there is no need to pass an explicit number of words,
450  * but is also making it possible to catch situation when too many words
451  * are being returned. */
452  void testStringFindSplitWords(const string &str,
453  const size_t max_length,
454  initializer_list<WordInfo> expected_words_info_init,
455  int max_words = -1)
456  {
457  const vector<WordInfo> expected_words_info = expected_words_info_init;
458  if (max_words != -1) {
459  CHECK_LE(max_words, expected_words_info.size() - 1);
460  }
461  /* Since number of word info is used here, this makes it so we allow one
462  * extra word to be collected from the input. This allows to catch possible
463  * issues with word splitting not doing a correct thing. */
464  const int effective_max_words = (max_words == -1) ? expected_words_info.size() : max_words;
465  /* One extra element for the {-1, -1}. */
466  vector<WordInfo> actual_word_info(effective_max_words + 1, WordInfo(-1, -1));
467  const int actual_word_num = BLI_string_find_split_words(
468  str.c_str(),
469  max_length,
470  ' ',
471  reinterpret_cast<int(*)[2]>(actual_word_info.data()),
472  effective_max_words);
473  /* Schrink actual array to an actual number of words, so we can compare
474  * vectors as-is. */
475  EXPECT_LE(actual_word_num, actual_word_info.size() - 1);
476  actual_word_info.resize(actual_word_num + 1);
477  /* Perform actual comparison. */
478  EXPECT_EQ_VECTOR(actual_word_info, expected_words_info);
479  }
480 
481  void testStringFindSplitWords(const string &str,
482  initializer_list<WordInfo> expected_words_info_init)
483  {
484  testStringFindSplitWords(str, str.length(), expected_words_info_init);
485  }
486 };
487 
488 /* BLI_string_find_split_words */
490 {
491  testStringFindSplitWords("t", {{0, 1}, {-1, -1}});
492  testStringFindSplitWords("test", {{0, 4}, {-1, -1}});
493 }
495 {
496  testStringFindSplitWords("f t w", {{0, 1}, {2, 1}, {4, 1}, {-1, -1}});
497  testStringFindSplitWords("find three words", {{0, 4}, {5, 5}, {11, 5}, {-1, -1}});
498 }
500 {
501  testStringFindSplitWords("# ## ### ####", {{0, 1}, {2, 2}, {5, 3}, {9, 4}, {-1, -1}});
502  testStringFindSplitWords("# # # #", {{0, 1}, {3, 1}, {7, 1}, {12, 1}, {-1, -1}});
503 }
505 {
506  testStringFindSplitWords(" t", {{3, 1}, {-1, -1}});
507  testStringFindSplitWords(" test", {{3, 4}, {-1, -1}});
508 }
509 TEST_F(StringFindSplitWords, Trailing_Right)
510 {
511  testStringFindSplitWords("t ", {{0, 1}, {-1, -1}});
512  testStringFindSplitWords("test ", {{0, 4}, {-1, -1}});
513 }
514 TEST_F(StringFindSplitWords, Trailing_LeftRight)
515 {
516  testStringFindSplitWords(" surrounding space test 123 ",
517  {{3, 11}, {15, 5}, {21, 4}, {28, 3}, {-1, -1}});
518 }
520 {
521  testStringFindSplitWords("", {{-1, -1}});
522 }
524 {
525  testStringFindSplitWords(" ", {{-1, -1}});
526  testStringFindSplitWords(" ", {{-1, -1}});
527 }
529 {
530  const string words = "too many chars";
531  const int words_len = words.length();
532  testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}}, 3);
533  testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {-1, -1}}, 2);
534  testStringFindSplitWords(words, words_len, {{0, 3}, {-1, -1}}, 1);
535  testStringFindSplitWords(words, words_len, {{-1, -1}}, 0);
536 }
538 {
539  const string words = "too many chars";
540  const int words_len = words.length();
541  testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}});
542  testStringFindSplitWords(words, words_len - 1, {{0, 3}, {4, 4}, {9, 4}, {-1, -1}});
543  testStringFindSplitWords(words, words_len - 5, {{0, 3}, {4, 4}, {-1, -1}});
544  testStringFindSplitWords(words, 1, {{0, 1}, {-1, -1}});
545  testStringFindSplitWords(words, 0, {{-1, -1}});
546 }
547 
548 /* BLI_strncasestr */
549 TEST(string, StringStrncasestr)
550 {
551  const char *str_test0 = "search here";
552  const char *res;
553 
554  res = BLI_strncasestr(str_test0, "", 0);
555  EXPECT_EQ(res, str_test0);
556 
557  res = BLI_strncasestr(str_test0, " ", 1);
558  EXPECT_EQ(res, str_test0 + 6);
559 
560  res = BLI_strncasestr(str_test0, "her", 3);
561  EXPECT_EQ(res, str_test0 + 7);
562 
563  res = BLI_strncasestr(str_test0, "ARCh", 4);
564  EXPECT_EQ(res, str_test0 + 2);
565 
566  res = BLI_strncasestr(str_test0, "earcq", 4);
567  EXPECT_EQ(res, str_test0 + 1);
568 
569  res = BLI_strncasestr(str_test0, "not there", 9);
570  EXPECT_EQ(res, (void *)nullptr);
571 }
572 
573 /* BLI_string_max_possible_word_count */
574 TEST(string, StringMaxPossibleWordCount)
575 {
581 }
582 
583 /* BLI_string_is_decimal */
584 TEST(string, StrIsDecimal)
585 {
586  EXPECT_FALSE(BLI_string_is_decimal(""));
587  EXPECT_FALSE(BLI_string_is_decimal("je moeder"));
588  EXPECT_FALSE(BLI_string_is_decimal("je møder"));
589  EXPECT_FALSE(BLI_string_is_decimal("Agent 327"));
590  EXPECT_FALSE(BLI_string_is_decimal("Agent\000327"));
591  EXPECT_FALSE(BLI_string_is_decimal("\000327"));
592  EXPECT_FALSE(BLI_string_is_decimal("0x16"));
593  EXPECT_FALSE(BLI_string_is_decimal("16.4"));
594  EXPECT_FALSE(BLI_string_is_decimal("-1"));
595 
596  EXPECT_TRUE(BLI_string_is_decimal("0"));
597  EXPECT_TRUE(BLI_string_is_decimal("1"));
598  EXPECT_TRUE(BLI_string_is_decimal("001"));
599  EXPECT_TRUE(BLI_string_is_decimal("11342908713948713498745980171334059871345098713405981734"));
600 }
601 
602 /* BLI_strcasecmp_natural */
603 class StringCasecmpNatural : public testing::Test {
604  protected:
605  StringCasecmpNatural() = default;
606 
608 
610  {
611  for (const auto &item : items) {
612  int res = BLI_strcasecmp_natural(item[0], item[1]);
613  EXPECT_EQ(res, 0);
614  }
615  }
617  {
618  for (const auto &item : items) {
619  int res = BLI_strcasecmp_natural(item[0], item[1]);
620  EXPECT_LT(res, 0);
621  }
622  }
624  {
625  for (const auto &item : items) {
626  int res = BLI_strcasecmp_natural(item[0], item[1]);
627  EXPECT_GT(res, 0);
628  }
629  }
630 
632  {
633  CompareWordsArray ret_array;
634 
635  /* E.g. {{"a", "b"}, {"ab", "cd"}} becomes {{"b", "a"}, {"cd", "ab"}} */
636 
637  ret_array.reserve(items.size());
638  for (const auto &item : items) {
639  ret_array.push_back({item[1], item[0]});
640  }
641 
642  return ret_array;
643  }
644 };
645 
647 {
648  const CompareWordsArray equal{
649  {"", ""},
650  };
651  const CompareWordsArray negative{
652  {"", "a"},
653  {"", "A"},
654  };
655  CompareWordsArray positive = copyWithSwappedWords(negative);
656 
657  testReturnsZeroForAll(equal);
658  testReturnsLessThanZeroForAll(negative);
659  testReturnsMoreThanZeroForAll(positive);
660 }
661 
663 {
664  const CompareWordsArray equal{
665  {" ", " "},
666  {" a", " a"},
667  {" a ", " a "},
668  };
669  const CompareWordsArray negative{
670  {"", " "},
671  {"", " a"},
672  {"", " a "},
673  {" ", " a"},
674  };
675  CompareWordsArray positive = copyWithSwappedWords(negative);
676 
677  testReturnsZeroForAll(equal);
678  testReturnsLessThanZeroForAll(negative);
679  testReturnsMoreThanZeroForAll(positive);
680 }
681 
682 TEST_F(StringCasecmpNatural, TextOnlyLowerCase)
683 {
684  const CompareWordsArray equal{
685  {"a", "a"},
686  {"aa", "aa"},
687  {"ab", "ab"},
688  {"ba", "ba"},
689  {"je møder", "je møder"},
690  };
691  const CompareWordsArray negative{
692  {"a", "b"},
693  {"a", "aa"},
694  {"a", "ab"},
695  {"aa", "b"},
696  {"je møda", "je møder"},
697  };
698  CompareWordsArray positive = copyWithSwappedWords(negative);
699 
700  testReturnsZeroForAll(equal);
701  testReturnsLessThanZeroForAll(negative);
702  testReturnsMoreThanZeroForAll(positive);
703 }
704 
706 {
707  const CompareWordsArray equal{
708  {"A", "A"},
709  {"AA", "AA"},
710  {"AB", "AB"},
711  {"Ab", "Ab"},
712  {"aB", "aB"},
713  };
714  const CompareWordsArray negative{
715  {"A", "a"},
716  {"A", "B"},
717  {"A", "b"},
718  {"a", "B"},
719  {"AA", "aA"},
720  {"AA", "aA"},
721  {"Ab", "ab"},
722  {"AB", "Ab"},
723  /* Different lengths */
724  {"A", "ab"},
725  {"Aa", "b"},
726  {"aA", "b"},
727  {"AA", "b"},
728  {"A", "Ab"},
729  {"A", "aB"},
730  {"Aa", "B"},
731  {"aA", "B"},
732  {"AA", "B"},
733  };
734  CompareWordsArray positive = copyWithSwappedWords(negative);
735 
736  testReturnsZeroForAll(equal);
737  testReturnsLessThanZeroForAll(negative);
738  testReturnsMoreThanZeroForAll(positive);
739 }
740 
742 {
743  const CompareWordsArray equal{
744  {".", "."},
745  {". ", ". "},
746  {" .", " ."},
747  {" . ", " . "},
748  };
749  const CompareWordsArray negative{
750  {".", ". "},
751  {" .", " . "},
752  {"foo.bar", "foo 1.bar"},
753  };
754  CompareWordsArray positive = copyWithSwappedWords(negative);
755 
756  testReturnsZeroForAll(equal);
757  testReturnsLessThanZeroForAll(negative);
758  testReturnsMoreThanZeroForAll(positive);
759 }
760 
762 {
763  const CompareWordsArray equal{
764  {"0", "0"},
765  {"0001", "0001"},
766  {"42", "42"},
767  {"0042", "0042"},
768  };
769  const CompareWordsArray negative{
770  /* If numeric values are equal, number of leading zeros is used as tiebreaker. */
771  {"1", "0001"},
772  {"01", "001"},
773  {"0042", "0043"},
774  {"0042", "43"},
775  };
776  const CompareWordsArray positive = copyWithSwappedWords(negative);
777 
778  testReturnsZeroForAll(equal);
779  testReturnsLessThanZeroForAll(negative);
780  testReturnsMoreThanZeroForAll(positive);
781 }
782 
783 TEST_F(StringCasecmpNatural, TextAndNumbers)
784 {
785  const CompareWordsArray equal{
786  {"00je møder1", "00je møder1"},
787  {".0 ", ".0 "},
788  {" 1.", " 1."},
789  {" .0 ", " .0 "},
790  };
791  const CompareWordsArray negative{
792  {"00je møder0", "00je møder1"},
793  {"05je møder0", "06je møder1"},
794  {"Cube", "Cube.001"},
795  {"Cube.001", "Cube.002"},
796  {"CUbe.001", "Cube.002"},
797  {"CUbe.002", "Cube.002"},
798  };
799  const CompareWordsArray positive = copyWithSwappedWords(negative);
800 
801  testReturnsZeroForAll(equal);
802  testReturnsLessThanZeroForAll(negative);
803  testReturnsMoreThanZeroForAll(positive);
804 }
805 
806 /* BLI_str_escape, BLI_str_unescape */
807 
808 class StringEscape : public testing::Test {
809  protected:
811  {
812  }
813 
815 
817  {
818  size_t dst_test_len;
819  char dst_test[64];
820  for (const auto &item : items) {
821  /* Escape the string. */
822  dst_test_len = BLI_str_escape(dst_test, item[0], SIZE_MAX);
823  EXPECT_STREQ(dst_test, item[1]);
824  EXPECT_EQ(dst_test_len, strlen(dst_test));
825  /* Escape back. */
826  dst_test_len = BLI_str_unescape(dst_test, item[1], strlen(item[1]));
827  EXPECT_STREQ(dst_test, item[0]);
828  EXPECT_EQ(dst_test_len, strlen(dst_test));
829  }
830  }
831 };
832 
834 {
835  const CompareWordsArray equal{
836  {"", ""},
837  {"/", "/"},
838  {"'", "'"},
839  {"?", "?"},
840  };
841 
842  const CompareWordsArray escaped{
843  {"\\", "\\\\"},
844  {"A\\", "A\\\\"},
845  {"\\A", "\\\\A"},
846  {"A\\B", "A\\\\B"},
847  {"?", "?"},
848  {"\"\\", "\\\"\\\\"},
849  {"\\\"", "\\\\\\\""},
850  {"\"\\\"", "\\\"\\\\\\\""},
851 
852  {"\"\"\"", "\\\"\\\"\\\""},
853  {"\\\\\\", "\\\\\\\\\\\\"},
854  };
855 
856  testEscapeWords(equal);
857  testEscapeWords(escaped);
858 }
859 
861 {
862  const CompareWordsArray escaped{
863  {"\n", "\\n"},
864  {"\r", "\\r"},
865  {"\t", "\\t"},
866  {"\a", "\\a"},
867  {"\b", "\\b"},
868  {"\f", "\\f"},
869  {"A\n", "A\\n"},
870  {"\nA", "\\nA"},
871  {"\n\r\t\a\b\f", "\\n\\r\\t\\a\\b\\f"},
872  {"\n_\r_\t_\a_\b_\f", "\\n_\\r_\\t_\\a_\\b_\\f"},
873  {"\n\\\r\\\t\\\a\\\b\\\f", "\\n\\\\\\r\\\\\\t\\\\\\a\\\\\\b\\\\\\f"},
874  };
875 
876  testEscapeWords(escaped);
877 }
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
size_t BLI_str_partition_ex(const char *str, const char *end, const char delim[], const char **sep, const char **suf, const bool from_right) ATTR_NONNULL(1
void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10) ATTR_NONNULL()
Definition: string.c:1206
char * BLI_strncasestr(const char *s, const char *find, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:635
size_t int BLI_string_max_possible_word_count(const int str_len)
Definition: string.c:599
int BLI_string_find_split_words(const char *str, const size_t len, const char delim, int r_words[][2], int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:1242
int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:766
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:333
size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL()
Definition: string.c:1056
size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, const size_t src_maxncpy) ATTR_NONNULL()
Definition: string.c:375
size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL()
Definition: string.c:1170
size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL()
Definition: string.c:1071
TEST(string, StrPartition)
TEST_F(StringFindSplitWords, Simple)
static std::ostream & operator<<(std::ostream &os, const WordInfo &word_info)
size_t BLI_str_rpartition_utf8(const char *str, const unsigned int delim[], const char **sep, const char **suf) ATTR_NONNULL()
Definition: string_utf8.c:857
size_t BLI_str_partition_ex_utf8(const char *str, const char *end, const unsigned int delim[], const char **sep, const char **suf, const bool from_right) ATTR_NONNULL(1
size_t BLI_str_partition_utf8(const char *str, const unsigned int delim[], const char **sep, const char **suf) ATTR_NONNULL()
Definition: string_utf8.c:849
bool BLI_string_is_decimal(const char *string) ATTR_NONNULL()
Definition: string_utils.c:85
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
void testReturnsMoreThanZeroForAll(const CompareWordsArray &items)
void testReturnsZeroForAll(const CompareWordsArray &items)
void testReturnsLessThanZeroForAll(const CompareWordsArray &items)
StringCasecmpNatural()=default
CompareWordsArray copyWithSwappedWords(const CompareWordsArray &items)
void testEscapeWords(const CompareWordsArray &items)
void testStringFindSplitWords(const string &str, initializer_list< WordInfo > expected_words_info_init)
void testStringFindSplitWords(const string &str, const size_t max_length, initializer_list< WordInfo > expected_words_info_init, int max_words=-1)
#define str(s)
std::vector< ElementType, Eigen::aligned_allocator< ElementType > > vector
Definition: vector.h:39
#define SIZE_MAX
Definition: stdint.h:209
bool operator==(const WordInfo &other) const
WordInfo(int start, int end)