Blender V5.0
BLI_string_ref_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "BLI_string_ref.hh"
7#include "BLI_vector.hh"
8
9#include "testing/testing.h"
10
11#include "BLI_strict_flags.h" /* IWYU pragma: keep. Keep last. */
12
13namespace blender::tests {
14
15TEST(string_ref_null, DefaultConstructor)
16{
17 StringRefNull ref;
18 EXPECT_EQ(ref.size(), 0);
19 EXPECT_EQ(ref[0], '\0');
20}
21
22TEST(string_ref_null, CStringConstructor)
23{
24 const char *str = "Hello";
25 StringRefNull ref(str);
26 EXPECT_EQ(ref.size(), 5);
27 EXPECT_EQ(ref.data(), str);
28}
29
30TEST(string_ref_null, CStringLengthConstructor)
31{
32 const char *str = "Hello";
33 StringRefNull ref(str, 5);
34 EXPECT_EQ(ref.size(), 5);
35 EXPECT_EQ(ref.data(), str);
36}
37
38TEST(string_ref_null, CompareEqual)
39{
40 StringRefNull ref1("test");
41 StringRefNull ref2("test");
42 StringRefNull ref3("other");
43 EXPECT_TRUE(ref1 == ref2);
44 EXPECT_FALSE(ref1 == ref3);
45 EXPECT_TRUE(ref1 != ref3);
46 EXPECT_FALSE(ref1 != ref2);
47}
48
49TEST(string_ref_null, CompareEqualCharPtr1)
50{
51 StringRefNull ref("test");
52 EXPECT_TRUE(ref == "test");
53 EXPECT_FALSE(ref == "other");
54 EXPECT_TRUE(ref != "other");
55 EXPECT_FALSE(ref != "test");
56}
57
58TEST(string_ref_null, CompareEqualCharPtr2)
59{
60 StringRefNull ref("test");
61 EXPECT_TRUE("test" == ref);
62 EXPECT_FALSE("other" == ref);
63 EXPECT_TRUE(ref != "other");
64 EXPECT_FALSE(ref != "test");
65}
66
67TEST(string_ref_null, CompareEqualString1)
68{
69 StringRefNull ref("test");
70 EXPECT_TRUE(ref == std::string("test"));
71 EXPECT_FALSE(ref == std::string("other"));
72 EXPECT_TRUE(ref != std::string("other"));
73 EXPECT_FALSE(ref != std::string("test"));
74}
75
76TEST(string_ref_null, CompareEqualString2)
77{
78 StringRefNull ref("test");
79 EXPECT_TRUE(std::string("test") == ref);
80 EXPECT_FALSE(std::string("other") == ref);
81 EXPECT_TRUE(std::string("other") != ref);
82 EXPECT_FALSE(std::string("test") != ref);
83}
84
85TEST(string_ref_null, CompareEqualStringRef1)
86{
87 StringRefNull ref("test");
88 EXPECT_TRUE(ref == StringRef("test"));
89 EXPECT_FALSE(ref == StringRef("other"));
90 EXPECT_TRUE(ref != StringRef("other"));
91 EXPECT_FALSE(ref != StringRef("test"));
92}
93
94TEST(string_ref_null, CompareEqualStringRef2)
95{
96 StringRefNull ref("test");
97 EXPECT_TRUE(StringRef("test") == ref);
98 EXPECT_FALSE(StringRef("other") == ref);
99 EXPECT_TRUE(StringRef("other") != ref);
100 EXPECT_FALSE(StringRef("test") != ref);
101}
102
103TEST(string_ref_null, Constexpr)
104{
105 constexpr StringRefNull sref("World", 5);
106 BLI_STATIC_ASSERT(sref[2] == 'r', "");
107 BLI_STATIC_ASSERT(sref.size() == 5, "");
108 std::array<int, std::size_t(sref.find_first_of('o'))> compiles = {1};
109 EXPECT_EQ(compiles[0], 1);
110}
111
112TEST(string_ref, DefaultConstructor)
113{
114 StringRef ref;
115 EXPECT_EQ(ref.size(), 0);
116}
117
118TEST(string_ref, StartEndConstructor)
119{
120 const char *text = "hello world";
121 StringRef ref(text, text + 5);
122 EXPECT_EQ(ref.size(), 5);
123 EXPECT_TRUE(ref == "hello");
124 EXPECT_FALSE(ref == "hello ");
125}
126
127TEST(string_ref, StartEndConstructorNullptr)
128{
129 StringRef ref(nullptr, nullptr);
130 EXPECT_EQ(ref.size(), 0);
131 EXPECT_TRUE(ref == "");
132}
133
134TEST(string_ref, StartEndConstructorSame)
135{
136 const char *text = "hello world";
137 StringRef ref(text, text);
138 EXPECT_EQ(ref.size(), 0);
139 EXPECT_TRUE(ref == "");
140}
141
142TEST(string_ref, CStringConstructor)
143{
144 const char *str = "Test";
145 StringRef ref(str);
146 EXPECT_EQ(ref.size(), 4);
147 EXPECT_EQ(ref.data(), str);
148}
149
150TEST(string_ref, PointerWithLengthConstructor)
151{
152 const char *str = "Test";
153 StringRef ref(str, 2);
154 EXPECT_EQ(ref.size(), 2);
155 EXPECT_EQ(ref.data(), str);
156}
157
158TEST(string_ref, StdStringConstructor)
159{
160 std::string str = "Test";
161 StringRef ref(str);
162 EXPECT_EQ(ref.size(), 4);
163 EXPECT_EQ(ref.data(), str.data());
164}
165
166TEST(string_ref, SpanConstructor)
167{
168 EXPECT_EQ(StringRef(Span<char>("hello", 5)), "hello");
169 EXPECT_EQ(StringRef(Span<char>("hello", 2)), "he");
170}
171
172TEST(string_ref, SubscriptOperator)
173{
174 StringRef ref("hello");
175 EXPECT_EQ(ref.size(), 5);
176 EXPECT_EQ(ref[0], 'h');
177 EXPECT_EQ(ref[1], 'e');
178 EXPECT_EQ(ref[2], 'l');
179 EXPECT_EQ(ref[3], 'l');
180 EXPECT_EQ(ref[4], 'o');
181}
182
183TEST(string_ref, ToStdString)
184{
185 StringRef ref("test");
186 std::string str = ref;
187 EXPECT_EQ(str.size(), 4);
188 EXPECT_EQ(str, "test");
189}
190
191TEST(string_ref, Print)
192{
193 StringRef ref("test");
194 std::stringstream ss;
195 ss << ref;
196 ss << ref;
197 std::string str = ss.str();
198 EXPECT_EQ(str.size(), 8);
199 EXPECT_EQ(str, "testtest");
200}
201
202TEST(string_ref, Add)
203{
204 StringRef a("qwe");
205 StringRef b("asd");
206 std::string result = a + b;
207 EXPECT_EQ(result, "qweasd");
208}
209
210TEST(string_ref, AddCharPtr1)
211{
212 StringRef ref("test");
213 std::string result = ref + "qwe";
214 EXPECT_EQ(result, "testqwe");
215}
216
217TEST(string_ref, AddCharPtr2)
218{
219 StringRef ref("test");
220 std::string result = "qwe" + ref;
221 EXPECT_EQ(result, "qwetest");
222}
223
224TEST(string_ref, AddString1)
225{
226 StringRef ref("test");
227 std::string result = ref + std::string("asd");
228 EXPECT_EQ(result, "testasd");
229}
230
231TEST(string_ref, AddString2)
232{
233 StringRef ref("test");
234 std::string result = std::string("asd") + ref;
235 EXPECT_EQ(result, "asdtest");
236}
237
238TEST(string_ref, CompareEqual)
239{
240 StringRef ref1("test");
241 StringRef ref2("test");
242 StringRef ref3("other");
243 EXPECT_TRUE(ref1 == ref2);
244 EXPECT_FALSE(ref1 == ref3);
245 EXPECT_TRUE(ref1 != ref3);
246 EXPECT_FALSE(ref1 != ref2);
247}
248
249TEST(string_ref, CompareEqualCharPtr1)
250{
251 StringRef ref("test");
252 EXPECT_TRUE(ref == "test");
253 EXPECT_FALSE(ref == "other");
254 EXPECT_TRUE(ref != "other");
255 EXPECT_FALSE(ref != "test");
256}
257
258TEST(string_ref, CompareEqualCharPtr2)
259{
260 StringRef ref("test");
261 EXPECT_TRUE("test" == ref);
262 EXPECT_FALSE("other" == ref);
263 EXPECT_TRUE(ref != "other");
264 EXPECT_FALSE(ref != "test");
265}
266
267TEST(string_ref, CompareEqualString1)
268{
269 StringRef ref("test");
270 EXPECT_TRUE(ref == std::string("test"));
271 EXPECT_FALSE(ref == std::string("other"));
272 EXPECT_TRUE(ref != std::string("other"));
273 EXPECT_FALSE(ref != std::string("test"));
274}
275
276TEST(string_ref, CompareEqualString2)
277{
278 StringRef ref("test");
279 EXPECT_TRUE(std::string("test") == ref);
280 EXPECT_FALSE(std::string("other") == ref);
281 EXPECT_TRUE(std::string("other") != ref);
282 EXPECT_FALSE(std::string("test") != ref);
283}
284
285TEST(string_ref, Iterate)
286{
287 StringRef ref("test");
288 Vector<char> chars;
289 for (char c : ref) {
290 chars.append(c);
291 }
292 EXPECT_EQ(chars.size(), 4);
293 EXPECT_EQ(chars[0], 't');
294 EXPECT_EQ(chars[1], 'e');
295 EXPECT_EQ(chars[2], 's');
296 EXPECT_EQ(chars[3], 't');
297}
298
299TEST(string_ref, StartsWith)
300{
301 StringRef ref("test");
302 EXPECT_TRUE(ref.startswith(""));
303 EXPECT_TRUE(ref.startswith("t"));
304 EXPECT_TRUE(ref.startswith("te"));
305 EXPECT_TRUE(ref.startswith("tes"));
306 EXPECT_TRUE(ref.startswith("test"));
307 EXPECT_FALSE(ref.startswith("test "));
308 EXPECT_FALSE(ref.startswith("a"));
309}
310
311TEST(string_ref, EndsWith)
312{
313 StringRef ref("test");
314 EXPECT_TRUE(ref.endswith(""));
315 EXPECT_TRUE(ref.endswith("t"));
316 EXPECT_TRUE(ref.endswith("st"));
317 EXPECT_TRUE(ref.endswith("est"));
318 EXPECT_TRUE(ref.endswith("test"));
319 EXPECT_FALSE(ref.endswith(" test"));
320 EXPECT_FALSE(ref.endswith("a"));
321}
322
323TEST(string_ref, DropPrefixN)
324{
325 StringRef ref("test");
326 StringRef ref2 = ref.drop_prefix(2);
327 StringRef ref3 = ref2.drop_prefix(2);
328 EXPECT_EQ(ref2.size(), 2);
329 EXPECT_EQ(ref3.size(), 0);
330 EXPECT_EQ(ref2, "st");
331 EXPECT_EQ(ref3, "");
332}
333
334TEST(string_ref, DropPrefixLargeN)
335{
336 StringRef ref("test");
337 StringRef ref2 = ref.drop_prefix(100);
338 EXPECT_EQ(ref2.size(), 0);
339 EXPECT_EQ(ref2, "");
340}
341
342TEST(string_ref, DropKnownPrefix)
343{
344 StringRef ref("test");
345 StringRef ref2 = ref.drop_known_prefix("tes");
346 EXPECT_EQ(ref2.size(), 1);
347 EXPECT_EQ(ref2, "t");
348}
349
350TEST(string_ref, DropSuffix)
351{
352 StringRef ref("test");
353 StringRef ref2 = ref.drop_suffix(1);
354 EXPECT_EQ(ref2.size(), 3);
355 EXPECT_EQ(ref2, "tes");
356}
357
358TEST(string_ref, DropSuffixLargeN)
359{
360 StringRef ref("test");
361 StringRef ref2 = ref.drop_suffix(100);
362 EXPECT_EQ(ref2.size(), 0);
363 EXPECT_EQ(ref2, "");
364}
365
366TEST(string_ref, TrimArbitrary)
367{
368 StringRef ref1("test");
369 StringRef ref2(" test ");
370 StringRef ref3(" \t Urož with spaces ");
371 StringRef ref4("žžžžleepyžžž");
372 EXPECT_EQ(ref1.trim("t"), "es");
373 EXPECT_EQ(ref1.trim("te"), "s");
374 EXPECT_EQ(ref1.trim("test"), "");
375 EXPECT_EQ(ref2.trim("t"), " test ");
376 EXPECT_EQ(ref2.trim(""), " test ");
377 EXPECT_EQ(ref3.trim(" "), "\t Urož with spaces"); /* TAB should be kept. */
378 EXPECT_EQ(ref4.trim("ž"), "leepy");
379}
380
381TEST(string_ref, TrimWhitespace)
382{
383 StringRef ref1("test");
384 StringRef ref2(" test ");
385 StringRef ref3(" \t Urož with spaces ");
386 StringRef ref4(" \t \n\r \t ");
387 EXPECT_EQ(ref1.trim(), "test");
388 EXPECT_EQ(ref2.trim(), "test");
389 EXPECT_EQ(ref3.trim(), "Urož with spaces");
390 EXPECT_EQ(ref4.trim(), "");
391}
392
393TEST(string_ref, TrimCharacter)
394{
395 StringRef ref1("test");
396 StringRef ref2(" test ");
397 StringRef ref3("does this work?");
398 EXPECT_EQ(ref1.trim('t'), "es");
399 EXPECT_EQ(ref1.trim('p'), "test");
400 EXPECT_EQ(ref2.trim(' '), "test");
401 EXPECT_EQ(ref3.trim('\000'), "does this work?");
402}
403
404TEST(string_ref, Substr)
405{
406 StringRef ref("hello world");
407 EXPECT_EQ(ref.substr(0, 5), "hello");
408 EXPECT_EQ(ref.substr(4, 0), "");
409 EXPECT_EQ(ref.substr(3, 4), "lo w");
410 EXPECT_EQ(ref.substr(6, 5), "world");
411 EXPECT_EQ(ref.substr(8), "rld");
412 EXPECT_EQ(ref.substr(8, 100), "rld");
413}
414
415TEST(string_ref, CopyUtf8Truncated)
416{
417 {
418 StringRef ref("hello");
419 char dst[10];
420 memset(dst, 0xFF, 10);
421 ref.copy_utf8_truncated(dst);
422 EXPECT_EQ(dst[5], '\0');
423 EXPECT_EQ(dst[6], 0xFF);
424 EXPECT_EQ(ref, dst);
425 }
426 {
427 StringRef ref("0123456789");
428 char dst[4];
429 memset(dst, 0xFF, 4);
430 ref.copy_utf8_truncated(dst);
431 EXPECT_EQ(dst[0], '0');
432 EXPECT_EQ(dst[1], '1');
433 EXPECT_EQ(dst[2], '2');
434 EXPECT_EQ(dst[3], '\0');
435 }
436 {
437 /* #BLI_STR_UTF8_SUPERSCRIPT_2 is a two-byte code point. */
439 {
440 char dst[1];
441 ref.copy_utf8_truncated(dst);
442 EXPECT_EQ(dst[0], '\0');
443 }
444 {
445 char dst[2];
446 ref.copy_utf8_truncated(dst);
447 EXPECT_EQ(dst[0], '\0');
448 }
449 {
450 char dst[3];
451 ref.copy_utf8_truncated(dst);
453 }
454 {
455 char dst[4];
456 ref.copy_utf8_truncated(dst);
458 }
459 {
460 char dst[5];
461 ref.copy_utf8_truncated(dst);
463 }
464 }
465}
466
467TEST(string_ref, CopyBytesTruncated)
468{
469 {
470 StringRef ref("hello");
471 char dst[10];
472 memset(dst, 0xFF, 10);
473 ref.copy_bytes_truncated(dst);
474 EXPECT_EQ(dst[5], '\0');
475 EXPECT_EQ(dst[6], 0xFF);
476 EXPECT_EQ(ref, dst);
477 }
478 {
479 StringRef ref("0123456789");
480 char dst[4];
481 memset(dst, 0xFF, 4);
482 ref.copy_bytes_truncated(dst);
483 EXPECT_EQ(dst[0], '0');
484 EXPECT_EQ(dst[1], '1');
485 EXPECT_EQ(dst[2], '2');
486 EXPECT_EQ(dst[3], '\0');
487 }
488 {
489 /* Simple 4 byte string. */
490 StringRef ref("01234");
491 {
492 char dst[1];
493 ref.copy_bytes_truncated(dst);
494 EXPECT_EQ(dst[0], '\0');
495 }
496 {
497 char dst[2];
498 ref.copy_bytes_truncated(dst);
499 EXPECT_EQ(dst[0], '0');
500 }
501 {
502 char dst[3];
503 ref.copy_bytes_truncated(dst);
504 EXPECT_EQ(StringRef(dst), "01");
505 }
506 {
507 char dst[4];
508 ref.copy_bytes_truncated(dst);
509 EXPECT_EQ(StringRef(dst), "012");
510 }
511 {
512 char dst[5];
513 ref.copy_bytes_truncated(dst);
514 EXPECT_EQ(StringRef(dst), "0123");
515 }
516 }
517}
518
519TEST(string_ref, FromStringView)
520{
521 std::string_view view = "hello";
522 StringRef ref = view;
523 EXPECT_EQ(ref, "hello");
524}
525
526TEST(string_ref, ToStringView)
527{
528 StringRef ref = "hello";
529 std::string_view view = ref;
530 EXPECT_EQ(view, "hello");
531}
532
533TEST(string_ref, Constexpr)
534{
535 constexpr StringRef sref("World");
536 BLI_STATIC_ASSERT(sref[2] == 'r', "");
537 BLI_STATIC_ASSERT(sref.size() == 5, "");
538 std::array<int, std::size_t(sref.find_first_of('o'))> compiles = {1};
539 EXPECT_EQ(compiles[0], 1);
540}
541} // namespace blender::tests
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:83
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define BLI_STR_UTF8_SUPERSCRIPT_2
static AppView * view
static btMatrix3x3 Add(const btMatrix3x3 &a, const btMatrix3x3 &b)
constexpr StringRef substr(int64_t start, int64_t size) const
void copy_bytes_truncated(char *dst, int64_t dst_size) const
Definition string_ref.cc:47
constexpr bool startswith(StringRef prefix) const
constexpr bool endswith(StringRef suffix) const
constexpr int64_t find_first_of(StringRef chars, int64_t pos=0) const
constexpr int64_t size() const
void copy_utf8_truncated(char *dst, int64_t dst_size) const
Definition string_ref.cc:28
constexpr StringRef trim() const
constexpr const char * data() const
constexpr StringRef drop_prefix(int64_t n) const
constexpr StringRef drop_suffix(int64_t n) const
constexpr StringRef drop_known_prefix(StringRef prefix) const
int64_t size() const
void append(const T &value)
#define str(s)
TEST(blf_load, load)
Definition BLF_tests.cc:34