Blender  V3.3
BLI_string_test.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-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 number_str[16];
328  int number;
329 
330  BLI_str_format_int_grouped(number_str, number = 0);
331  EXPECT_STREQ("0", number_str);
332 
333  BLI_str_format_int_grouped(number_str, number = 1);
334  EXPECT_STREQ("1", number_str);
335 
336  BLI_str_format_int_grouped(number_str, number = -1);
337  EXPECT_STREQ("-1", number_str);
338 
339  BLI_str_format_int_grouped(number_str, number = -2147483648);
340  EXPECT_STREQ("-2,147,483,648", number_str);
341 
342  BLI_str_format_int_grouped(number_str, number = 2147483647);
343  EXPECT_STREQ("2,147,483,647", number_str);
344 
345  BLI_str_format_int_grouped(number_str, number = 1000);
346  EXPECT_STREQ("1,000", number_str);
347 
348  BLI_str_format_int_grouped(number_str, number = -1000);
349  EXPECT_STREQ("-1,000", number_str);
350 
351  BLI_str_format_int_grouped(number_str, number = 999);
352  EXPECT_STREQ("999", number_str);
353 
354  BLI_str_format_int_grouped(number_str, number = -999);
355  EXPECT_STREQ("-999", number_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 /* BLI_str_format_decimal_unit */
424 TEST(string, StrFormatDecimalUnits)
425 {
426  char size_str[7];
427  int size;
428 
429  BLI_str_format_decimal_unit(size_str, size = 0);
430  EXPECT_STREQ("0", size_str);
431  BLI_str_format_decimal_unit(size_str, size = 1);
432  EXPECT_STREQ("1", size_str);
433  BLI_str_format_decimal_unit(size_str, size = 10);
434  EXPECT_STREQ("10", size_str);
435  BLI_str_format_decimal_unit(size_str, size = 15);
436  EXPECT_STREQ("15", size_str);
437  BLI_str_format_decimal_unit(size_str, size = 100);
438  EXPECT_STREQ("100", size_str);
439  BLI_str_format_decimal_unit(size_str, size = 155);
440  EXPECT_STREQ("155", size_str);
441  BLI_str_format_decimal_unit(size_str, size = 1000);
442  EXPECT_STREQ("1.0K", size_str);
443  BLI_str_format_decimal_unit(size_str, size = 1555);
444  EXPECT_STREQ("1.6K", size_str);
445  BLI_str_format_decimal_unit(size_str, size = 10000);
446  EXPECT_STREQ("10.0K", size_str);
447  BLI_str_format_decimal_unit(size_str, size = 15555);
448  EXPECT_STREQ("15.6K", size_str);
449  BLI_str_format_decimal_unit(size_str, size = 100000);
450  EXPECT_STREQ("100K", size_str);
451  BLI_str_format_decimal_unit(size_str, size = 100000);
452  EXPECT_STREQ("100K", size_str);
453  BLI_str_format_decimal_unit(size_str, size = 155555);
454  EXPECT_STREQ("156K", size_str);
455  BLI_str_format_decimal_unit(size_str, size = 1000000);
456  EXPECT_STREQ("1.0M", size_str);
457  BLI_str_format_decimal_unit(size_str, size = 1555555);
458  EXPECT_STREQ("1.6M", size_str);
459  BLI_str_format_decimal_unit(size_str, size = 10000000);
460  EXPECT_STREQ("10.0M", size_str);
461  BLI_str_format_decimal_unit(size_str, size = 15555555);
462  EXPECT_STREQ("15.6M", size_str);
463  BLI_str_format_decimal_unit(size_str, size = 100000000);
464  EXPECT_STREQ("100M", size_str);
465  BLI_str_format_decimal_unit(size_str, size = 155555555);
466  EXPECT_STREQ("156M", size_str);
467  BLI_str_format_decimal_unit(size_str, size = 1000000000);
468  EXPECT_STREQ("1.0B", size_str);
469 
470  /* Largest possible value. */
472  EXPECT_STREQ("2.1B", size_str);
473 
474  BLI_str_format_decimal_unit(size_str, size = -0);
475  EXPECT_STREQ("0", size_str);
476  BLI_str_format_decimal_unit(size_str, size = -1);
477  EXPECT_STREQ("-1", size_str);
478  BLI_str_format_decimal_unit(size_str, size = -10);
479  EXPECT_STREQ("-10", size_str);
480  BLI_str_format_decimal_unit(size_str, size = -15);
481  EXPECT_STREQ("-15", size_str);
482  BLI_str_format_decimal_unit(size_str, size = -100);
483  EXPECT_STREQ("-100", size_str);
484  BLI_str_format_decimal_unit(size_str, size = -155);
485  EXPECT_STREQ("-155", size_str);
486  BLI_str_format_decimal_unit(size_str, size = -1000);
487  EXPECT_STREQ("-1.0K", size_str);
488  BLI_str_format_decimal_unit(size_str, size = -1555);
489  EXPECT_STREQ("-1.6K", size_str);
490  BLI_str_format_decimal_unit(size_str, size = -10000);
491  EXPECT_STREQ("-10.0K", size_str);
492  BLI_str_format_decimal_unit(size_str, size = -15555);
493  EXPECT_STREQ("-15.6K", size_str);
494  BLI_str_format_decimal_unit(size_str, size = -100000);
495  EXPECT_STREQ("-100K", size_str);
496  BLI_str_format_decimal_unit(size_str, size = -155555);
497  EXPECT_STREQ("-156K", size_str);
498  BLI_str_format_decimal_unit(size_str, size = -1000000);
499  EXPECT_STREQ("-1.0M", size_str);
500  BLI_str_format_decimal_unit(size_str, size = -1555555);
501  EXPECT_STREQ("-1.6M", size_str);
502  BLI_str_format_decimal_unit(size_str, size = -10000000);
503  EXPECT_STREQ("-10.0M", size_str);
504  BLI_str_format_decimal_unit(size_str, size = -15555555);
505  EXPECT_STREQ("-15.6M", size_str);
506  BLI_str_format_decimal_unit(size_str, size = -100000000);
507  EXPECT_STREQ("-100M", size_str);
508  BLI_str_format_decimal_unit(size_str, size = -155555555);
509  EXPECT_STREQ("-156M", size_str);
510  BLI_str_format_decimal_unit(size_str, size = -1000000000);
511  EXPECT_STREQ("-1.0B", size_str);
512 
513  /* Smallest possible value. */
515  EXPECT_STREQ("-2.1B", size_str);
516 }
517 
518 struct WordInfo {
519  WordInfo() = default;
520  WordInfo(int start, int end) : start(start), end(end)
521  {
522  }
523  bool operator==(const WordInfo &other) const
524  {
525  return start == other.start && end == other.end;
526  }
527  int start, end;
528 };
529 static std::ostream &operator<<(std::ostream &os, const WordInfo &word_info)
530 {
531  os << "start: " << word_info.start << ", end: " << word_info.end;
532  return os;
533 }
534 
535 class StringFindSplitWords : public testing::Test {
536  protected:
537  StringFindSplitWords() = default;
538 
539  /* If max_words is -1 it will be initialized from the number of expected
540  * words +1. This way there is no need to pass an explicit number of words,
541  * but is also making it possible to catch situation when too many words
542  * are being returned. */
543  void testStringFindSplitWords(const string &str,
544  const size_t max_length,
545  initializer_list<WordInfo> expected_words_info_init,
546  int max_words = -1)
547  {
548  const vector<WordInfo> expected_words_info = expected_words_info_init;
549  if (max_words != -1) {
550  CHECK_LE(max_words, expected_words_info.size() - 1);
551  }
552  /* Since number of word info is used here, this makes it so we allow one
553  * extra word to be collected from the input. This allows to catch possible
554  * issues with word splitting not doing a correct thing. */
555  const int effective_max_words = (max_words == -1) ? expected_words_info.size() : max_words;
556  /* One extra element for the {-1, -1}. */
557  vector<WordInfo> actual_word_info(effective_max_words + 1, WordInfo(-1, -1));
558  const int actual_word_num = BLI_string_find_split_words(
559  str.c_str(),
560  max_length,
561  ' ',
562  reinterpret_cast<int(*)[2]>(actual_word_info.data()),
563  effective_max_words);
564  /* Schrink actual array to an actual number of words, so we can compare
565  * vectors as-is. */
566  EXPECT_LE(actual_word_num, actual_word_info.size() - 1);
567  actual_word_info.resize(actual_word_num + 1);
568  /* Perform actual comparison. */
569  EXPECT_EQ_VECTOR(actual_word_info, expected_words_info);
570  }
571 
572  void testStringFindSplitWords(const string &str,
573  initializer_list<WordInfo> expected_words_info_init)
574  {
575  testStringFindSplitWords(str, str.length(), expected_words_info_init);
576  }
577 };
578 
579 /* BLI_string_find_split_words */
581 {
582  testStringFindSplitWords("t", {{0, 1}, {-1, -1}});
583  testStringFindSplitWords("test", {{0, 4}, {-1, -1}});
584 }
586 {
587  testStringFindSplitWords("f t w", {{0, 1}, {2, 1}, {4, 1}, {-1, -1}});
588  testStringFindSplitWords("find three words", {{0, 4}, {5, 5}, {11, 5}, {-1, -1}});
589 }
591 {
592  testStringFindSplitWords("# ## ### ####", {{0, 1}, {2, 2}, {5, 3}, {9, 4}, {-1, -1}});
593  testStringFindSplitWords("# # # #", {{0, 1}, {3, 1}, {7, 1}, {12, 1}, {-1, -1}});
594 }
596 {
597  testStringFindSplitWords(" t", {{3, 1}, {-1, -1}});
598  testStringFindSplitWords(" test", {{3, 4}, {-1, -1}});
599 }
600 TEST_F(StringFindSplitWords, Trailing_Right)
601 {
602  testStringFindSplitWords("t ", {{0, 1}, {-1, -1}});
603  testStringFindSplitWords("test ", {{0, 4}, {-1, -1}});
604 }
605 TEST_F(StringFindSplitWords, Trailing_LeftRight)
606 {
607  testStringFindSplitWords(" surrounding space test 123 ",
608  {{3, 11}, {15, 5}, {21, 4}, {28, 3}, {-1, -1}});
609 }
611 {
612  testStringFindSplitWords("", {{-1, -1}});
613 }
615 {
616  testStringFindSplitWords(" ", {{-1, -1}});
617  testStringFindSplitWords(" ", {{-1, -1}});
618 }
620 {
621  const string words = "too many chars";
622  const int words_len = words.length();
623  testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}}, 3);
624  testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {-1, -1}}, 2);
625  testStringFindSplitWords(words, words_len, {{0, 3}, {-1, -1}}, 1);
626  testStringFindSplitWords(words, words_len, {{-1, -1}}, 0);
627 }
629 {
630  const string words = "too many chars";
631  const int words_len = words.length();
632  testStringFindSplitWords(words, words_len, {{0, 3}, {4, 4}, {9, 5}, {-1, -1}});
633  testStringFindSplitWords(words, words_len - 1, {{0, 3}, {4, 4}, {9, 4}, {-1, -1}});
634  testStringFindSplitWords(words, words_len - 5, {{0, 3}, {4, 4}, {-1, -1}});
635  testStringFindSplitWords(words, 1, {{0, 1}, {-1, -1}});
636  testStringFindSplitWords(words, 0, {{-1, -1}});
637 }
638 
639 /* BLI_strncasestr */
640 TEST(string, StringStrncasestr)
641 {
642  const char *str_test0 = "search here";
643  const char *res;
644 
645  res = BLI_strncasestr(str_test0, "", 0);
646  EXPECT_EQ(res, str_test0);
647 
648  res = BLI_strncasestr(str_test0, " ", 1);
649  EXPECT_EQ(res, str_test0 + 6);
650 
651  res = BLI_strncasestr(str_test0, "her", 3);
652  EXPECT_EQ(res, str_test0 + 7);
653 
654  res = BLI_strncasestr(str_test0, "ARCh", 4);
655  EXPECT_EQ(res, str_test0 + 2);
656 
657  res = BLI_strncasestr(str_test0, "earcq", 4);
658  EXPECT_EQ(res, str_test0 + 1);
659 
660  res = BLI_strncasestr(str_test0, "not there", 9);
661  EXPECT_EQ(res, (void *)nullptr);
662 }
663 
664 /* BLI_string_max_possible_word_count */
665 TEST(string, StringMaxPossibleWordCount)
666 {
672 }
673 
674 /* BLI_string_is_decimal */
675 TEST(string, StrIsDecimal)
676 {
677  EXPECT_FALSE(BLI_string_is_decimal(""));
678  EXPECT_FALSE(BLI_string_is_decimal("je moeder"));
679  EXPECT_FALSE(BLI_string_is_decimal("je møder"));
680  EXPECT_FALSE(BLI_string_is_decimal("Agent 327"));
681  EXPECT_FALSE(BLI_string_is_decimal("Agent\000327"));
682  EXPECT_FALSE(BLI_string_is_decimal("\000327"));
683  EXPECT_FALSE(BLI_string_is_decimal("0x16"));
684  EXPECT_FALSE(BLI_string_is_decimal("16.4"));
685  EXPECT_FALSE(BLI_string_is_decimal("-1"));
686 
687  EXPECT_TRUE(BLI_string_is_decimal("0"));
688  EXPECT_TRUE(BLI_string_is_decimal("1"));
689  EXPECT_TRUE(BLI_string_is_decimal("001"));
690  EXPECT_TRUE(BLI_string_is_decimal("11342908713948713498745980171334059871345098713405981734"));
691 }
692 
693 /* BLI_strcasecmp_natural */
694 class StringCasecmpNatural : public testing::Test {
695  protected:
696  StringCasecmpNatural() = default;
697 
699 
701  {
702  for (const auto &item : items) {
703  int res = BLI_strcasecmp_natural(item[0], item[1]);
704  EXPECT_EQ(res, 0);
705  }
706  }
708  {
709  for (const auto &item : items) {
710  int res = BLI_strcasecmp_natural(item[0], item[1]);
711  EXPECT_LT(res, 0);
712  }
713  }
715  {
716  for (const auto &item : items) {
717  int res = BLI_strcasecmp_natural(item[0], item[1]);
718  EXPECT_GT(res, 0);
719  }
720  }
721 
723  {
724  CompareWordsArray ret_array;
725 
726  /* E.g. {{"a", "b"}, {"ab", "cd"}} becomes {{"b", "a"}, {"cd", "ab"}} */
727 
728  ret_array.reserve(items.size());
729  for (const auto &item : items) {
730  ret_array.push_back({item[1], item[0]});
731  }
732 
733  return ret_array;
734  }
735 };
736 
738 {
739  const CompareWordsArray equal{
740  {"", ""},
741  };
742  const CompareWordsArray negative{
743  {"", "a"},
744  {"", "A"},
745  };
746  CompareWordsArray positive = copyWithSwappedWords(negative);
747 
748  testReturnsZeroForAll(equal);
749  testReturnsLessThanZeroForAll(negative);
750  testReturnsMoreThanZeroForAll(positive);
751 }
752 
754 {
755  const CompareWordsArray equal{
756  {" ", " "},
757  {" a", " a"},
758  {" a ", " a "},
759  };
760  const CompareWordsArray negative{
761  {"", " "},
762  {"", " a"},
763  {"", " a "},
764  {" ", " a"},
765  };
766  CompareWordsArray positive = copyWithSwappedWords(negative);
767 
768  testReturnsZeroForAll(equal);
769  testReturnsLessThanZeroForAll(negative);
770  testReturnsMoreThanZeroForAll(positive);
771 }
772 
773 TEST_F(StringCasecmpNatural, TextOnlyLowerCase)
774 {
775  const CompareWordsArray equal{
776  {"a", "a"},
777  {"aa", "aa"},
778  {"ab", "ab"},
779  {"ba", "ba"},
780  {"je møder", "je møder"},
781  };
782  const CompareWordsArray negative{
783  {"a", "b"},
784  {"a", "aa"},
785  {"a", "ab"},
786  {"aa", "b"},
787  {"je møda", "je møder"},
788  };
789  CompareWordsArray positive = copyWithSwappedWords(negative);
790 
791  testReturnsZeroForAll(equal);
792  testReturnsLessThanZeroForAll(negative);
793  testReturnsMoreThanZeroForAll(positive);
794 }
795 
797 {
798  const CompareWordsArray equal{
799  {"A", "A"},
800  {"AA", "AA"},
801  {"AB", "AB"},
802  {"Ab", "Ab"},
803  {"aB", "aB"},
804  };
805  const CompareWordsArray negative{
806  {"A", "a"},
807  {"A", "B"},
808  {"A", "b"},
809  {"a", "B"},
810  {"AA", "aA"},
811  {"AA", "aA"},
812  {"Ab", "ab"},
813  {"AB", "Ab"},
814  /* Different lengths */
815  {"A", "ab"},
816  {"Aa", "b"},
817  {"aA", "b"},
818  {"AA", "b"},
819  {"A", "Ab"},
820  {"A", "aB"},
821  {"Aa", "B"},
822  {"aA", "B"},
823  {"AA", "B"},
824  };
825  CompareWordsArray positive = copyWithSwappedWords(negative);
826 
827  testReturnsZeroForAll(equal);
828  testReturnsLessThanZeroForAll(negative);
829  testReturnsMoreThanZeroForAll(positive);
830 }
831 
833 {
834  const CompareWordsArray equal{
835  {".", "."},
836  {". ", ". "},
837  {" .", " ."},
838  {" . ", " . "},
839  };
840  const CompareWordsArray negative{
841  {".", ". "},
842  {" .", " . "},
843  {"foo.bar", "foo 1.bar"},
844  };
845  CompareWordsArray positive = copyWithSwappedWords(negative);
846 
847  testReturnsZeroForAll(equal);
848  testReturnsLessThanZeroForAll(negative);
849  testReturnsMoreThanZeroForAll(positive);
850 }
851 
853 {
854  const CompareWordsArray equal{
855  {"0", "0"},
856  {"0001", "0001"},
857  {"42", "42"},
858  {"0042", "0042"},
859  };
860  const CompareWordsArray negative{
861  /* If numeric values are equal, number of leading zeros is used as tiebreaker. */
862  {"1", "0001"},
863  {"01", "001"},
864  {"0042", "0043"},
865  {"0042", "43"},
866  };
867  const CompareWordsArray positive = copyWithSwappedWords(negative);
868 
869  testReturnsZeroForAll(equal);
870  testReturnsLessThanZeroForAll(negative);
871  testReturnsMoreThanZeroForAll(positive);
872 }
873 
874 TEST_F(StringCasecmpNatural, TextAndNumbers)
875 {
876  const CompareWordsArray equal{
877  {"00je møder1", "00je møder1"},
878  {".0 ", ".0 "},
879  {" 1.", " 1."},
880  {" .0 ", " .0 "},
881  };
882  const CompareWordsArray negative{
883  {"00je møder0", "00je møder1"},
884  {"05je møder0", "06je møder1"},
885  {"Cube", "Cube.001"},
886  {"Cube.001", "Cube.002"},
887  {"CUbe.001", "Cube.002"},
888  {"CUbe.002", "Cube.002"},
889  };
890  const CompareWordsArray positive = copyWithSwappedWords(negative);
891 
892  testReturnsZeroForAll(equal);
893  testReturnsLessThanZeroForAll(negative);
894  testReturnsMoreThanZeroForAll(positive);
895 }
896 
897 /* BLI_str_escape, BLI_str_unescape */
898 
899 class StringEscape : public testing::Test {
900  protected:
901  StringEscape() = default;
902 
904 
906  {
907  size_t dst_test_len;
908  char dst_test[64];
909  for (const auto &item : items) {
910  /* Escape the string. */
911  dst_test_len = BLI_str_escape(dst_test, item[0], SIZE_MAX);
912  EXPECT_STREQ(dst_test, item[1]);
913  EXPECT_EQ(dst_test_len, strlen(dst_test));
914  /* Escape back. */
915  dst_test_len = BLI_str_unescape(dst_test, item[1], strlen(item[1]));
916  EXPECT_STREQ(dst_test, item[0]);
917  EXPECT_EQ(dst_test_len, strlen(dst_test));
918  }
919  }
920 };
921 
923 {
924  /* NOTE: clang-tidy `modernize-raw-string-literal` is disabled as it causes errors with MSVC.
925  * TODO: investigate resolving with `/Zc:preprocessor` flag. */
926 
927  const CompareWordsArray equal{
928  {"", ""},
929  {"/", "/"},
930  {"'", "'"},
931  {"?", "?"},
932  };
933 
934  const CompareWordsArray escaped{
935  {"\\", "\\\\"},
936  {"A\\", "A\\\\"},
937  {"\\A", "\\\\A"},
938  {"A\\B", "A\\\\B"},
939  {"?", "?"},
940  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
941  {"\"\\", "\\\"\\\\"},
942  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
943  {"\\\"", "\\\\\\\""},
944  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
945  {"\"\\\"", "\\\"\\\\\\\""},
946 
947  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
948  {"\"\"\"", "\\\"\\\"\\\""},
949  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
950  {"\\\\\\", "\\\\\\\\\\\\"},
951  };
952 
953  testEscapeWords(equal);
954  testEscapeWords(escaped);
955 }
956 
958 {
959  const CompareWordsArray escaped{
960  {"\n", "\\n"},
961  {"\r", "\\r"},
962  {"\t", "\\t"},
963  {"\a", "\\a"},
964  {"\b", "\\b"},
965  {"\f", "\\f"},
966  {"A\n", "A\\n"},
967  {"\nA", "\\nA"},
968  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
969  {"\n\r\t\a\b\f", "\\n\\r\\t\\a\\b\\f"},
970  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
971  {"\n_\r_\t_\a_\b_\f", "\\n_\\r_\\t_\\a_\\b_\\f"},
972  /* NOLINTNEXTLINE: modernize-raw-string-literal. */
973  {"\n\\\r\\\t\\\a\\\b\\\f", "\\n\\\\\\r\\\\\\t\\\\\\a\\\\\\b\\\\\\f"},
974  };
975 
976  testEscapeWords(escaped);
977 }
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
size_t int BLI_string_max_possible_word_count(int str_len)
Definition: string.c:559
size_t BLI_str_unescape(char *__restrict dst, const char *__restrict src, size_t src_maxncpy) ATTR_NONNULL()
Definition: string.c:327
char * BLI_strncasestr(const char *s, const char *find, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:592
int BLI_strcasecmp_natural(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:719
int BLI_string_find_split_words(const char *str, size_t len, char delim, int r_words[][2], int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:1049
void BLI_str_format_decimal_unit(char dst[7], int number_to_format) ATTR_NONNULL()
Definition: string.c:1158
size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL()
Definition: string.c:989
size_t BLI_str_partition_ex(const char *str, const char *end, const char delim[], const char **sep, const char **suf, bool from_right) ATTR_NONNULL(1
size_t BLI_str_format_int_grouped(char dst[16], int num) ATTR_NONNULL()
Definition: string.c:1114
size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf) ATTR_NONNULL()
Definition: string.c:994
void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) ATTR_NONNULL()
Definition: string.c:1132
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:250
TEST(string, StrPartition)
TEST_F(StringFindSplitWords, Simple)
static std::ostream & operator<<(std::ostream &os, const WordInfo &word_info)
size_t BLI_str_partition_utf8(const char *str, const unsigned int delim[], const char **sep, const char **suf) ATTR_NONNULL(1
size_t size_t BLI_str_rpartition_utf8(const char *str, const unsigned int delim[], const char **sep, const char **suf) ATTR_NONNULL(1
size_t size_t size_t BLI_str_partition_ex_utf8(const char *str, const char *end, const unsigned int delim[], const char **sep, const char **suf, bool from_right) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
bool BLI_string_is_decimal(const char *string) ATTR_NONNULL()
Definition: string_utils.c:55
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a vector
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)
StringEscape()=default
void testEscapeWords(const CompareWordsArray &items)
void testStringFindSplitWords(const string &str, initializer_list< WordInfo > expected_words_info_init)
StringFindSplitWords()=default
void testStringFindSplitWords(const string &str, const size_t max_length, initializer_list< WordInfo > expected_words_info_init, int max_words=-1)
#define str(s)
#define CHECK_LE(a, b)
Definition: log.h:53
#define INT32_MAX
Definition: stdint.h:137
#define SIZE_MAX
Definition: stdint.h:206
WordInfo()=default
bool operator==(const WordInfo &other) const
WordInfo(int start, int end)