Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/common-tests/small_string_tests.cpp
7197 views
1
// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
#include "common/small_string.h"
5
6
#include <fmt/format.h>
7
#include <gtest/gtest.h>
8
#include <string>
9
#include <string_view>
10
11
using namespace std::string_view_literals;
12
13
//////////////////////////////////////////////////////////////////////////
14
// SmallStringBase Test Suite
15
//////////////////////////////////////////////////////////////////////////
16
17
// Constructor Tests
18
TEST(SmallStringBase, DefaultConstructor)
19
{
20
SmallString s;
21
EXPECT_TRUE(s.empty());
22
EXPECT_EQ(s.length(), 0u);
23
EXPECT_STREQ(s.c_str(), "");
24
}
25
26
TEST(SmallStringBase, ConstCharConstructor)
27
{
28
SmallString s("Hello");
29
EXPECT_FALSE(s.empty());
30
EXPECT_EQ(s.length(), 5u);
31
EXPECT_STREQ(s.c_str(), "Hello");
32
}
33
34
TEST(SmallStringBase, ConstCharWithLengthConstructor)
35
{
36
SmallString s("Hello World", 5);
37
EXPECT_EQ(s.length(), 5u);
38
EXPECT_STREQ(s.c_str(), "Hello");
39
}
40
41
TEST(SmallStringBase, CopyConstructor)
42
{
43
SmallString original("Test String");
44
SmallString copy(original);
45
EXPECT_EQ(copy.length(), original.length());
46
EXPECT_STREQ(copy.c_str(), original.c_str());
47
}
48
49
TEST(SmallStringBase, MoveConstructor)
50
{
51
SmallString original("Test String");
52
SmallString moved(std::move(original));
53
EXPECT_EQ(moved.length(), 11u);
54
EXPECT_STREQ(moved.c_str(), "Test String");
55
}
56
57
TEST(SmallStringBase, StdStringConstructor)
58
{
59
std::string stdStr = "Hello from std::string";
60
SmallString s(stdStr);
61
EXPECT_EQ(s.length(), stdStr.length());
62
EXPECT_STREQ(s.c_str(), stdStr.c_str());
63
}
64
65
TEST(SmallStringBase, StringViewConstructor)
66
{
67
std::string_view sv = "Hello from string_view";
68
SmallString s(sv);
69
EXPECT_EQ(s.length(), sv.length());
70
EXPECT_EQ(s.view(), sv);
71
}
72
73
// Assignment Tests
74
TEST(SmallStringBase, AssignConstChar)
75
{
76
SmallString str;
77
str.assign("New Value");
78
EXPECT_EQ(str.length(), 9u);
79
EXPECT_STREQ(str.c_str(), "New Value");
80
}
81
82
TEST(SmallStringBase, AssignConstCharWithLength)
83
{
84
SmallString str;
85
str.assign("New Value Extended", 9);
86
EXPECT_EQ(str.length(), 9u);
87
EXPECT_STREQ(str.c_str(), "New Value");
88
}
89
90
TEST(SmallStringBase, AssignStdString)
91
{
92
SmallString str;
93
std::string stdStr = "std::string value";
94
str.assign(stdStr);
95
EXPECT_STREQ(str.c_str(), stdStr.c_str());
96
}
97
98
TEST(SmallStringBase, AssignStringView)
99
{
100
SmallString str;
101
std::string_view sv = "string_view value"sv;
102
str.assign(sv);
103
EXPECT_EQ(str.view(), sv);
104
}
105
106
TEST(SmallStringBase, AssignSmallStringBase)
107
{
108
SmallString str;
109
SmallString other("Other string");
110
str.assign(other);
111
EXPECT_STREQ(str.c_str(), other.c_str());
112
}
113
114
TEST(SmallStringBase, AssignMove)
115
{
116
SmallString str;
117
SmallString other("Move this");
118
str.assign(std::move(other));
119
EXPECT_STREQ(str.c_str(), "Move this");
120
}
121
122
// Clear Tests
123
TEST(SmallStringBase, Clear)
124
{
125
SmallString str("Some content");
126
EXPECT_FALSE(str.empty());
127
str.clear();
128
EXPECT_TRUE(str.empty());
129
EXPECT_EQ(str.length(), 0u);
130
}
131
132
// Append Tests
133
TEST(SmallStringBase, AppendChar)
134
{
135
SmallString str("Hello");
136
str.append('!');
137
EXPECT_STREQ(str.c_str(), "Hello!");
138
}
139
140
TEST(SmallStringBase, AppendConstChar)
141
{
142
SmallString str("Hello");
143
str.append(" World");
144
EXPECT_STREQ(str.c_str(), "Hello World");
145
}
146
147
TEST(SmallStringBase, AppendConstCharWithLength)
148
{
149
SmallString str("Hello");
150
str.append(" World!!!", 6);
151
EXPECT_STREQ(str.c_str(), "Hello World");
152
}
153
154
TEST(SmallStringBase, AppendStdString)
155
{
156
SmallString str("Hello");
157
std::string suffix = " World";
158
str.append(suffix);
159
EXPECT_STREQ(str.c_str(), "Hello World");
160
}
161
162
TEST(SmallStringBase, AppendStringView)
163
{
164
SmallString str("Hello");
165
str.append(" World"sv);
166
EXPECT_STREQ(str.c_str(), "Hello World");
167
}
168
169
TEST(SmallStringBase, AppendSmallStringBase)
170
{
171
SmallString str("Hello");
172
SmallString suffix(" World");
173
str.append(suffix);
174
EXPECT_STREQ(str.c_str(), "Hello World");
175
}
176
177
TEST(SmallStringBase, AppendSprintf)
178
{
179
SmallString str("Value: ");
180
str.append_sprintf("%d", 42);
181
EXPECT_STREQ(str.c_str(), "Value: 42");
182
}
183
184
TEST(SmallStringBase, AppendFormat)
185
{
186
SmallString str("Value: ");
187
str.append_format("{}", 42);
188
EXPECT_STREQ(str.c_str(), "Value: 42");
189
}
190
191
TEST(SmallStringBase, AppendHex)
192
{
193
SmallString str;
194
const u8 data[] = {0xDE, 0xAD, 0xBE, 0xEF};
195
str.append_hex(data, sizeof(data));
196
EXPECT_STREQ(str.c_str(), "deadbeef");
197
}
198
199
TEST(SmallStringBase, AppendHexCommaSeparated)
200
{
201
SmallString str;
202
const u8 data[] = {0xDE, 0xAD};
203
str.append_hex(data, sizeof(data), true);
204
EXPECT_STREQ(str.c_str(), "0xde, 0xad");
205
}
206
207
// Prepend Tests
208
TEST(SmallStringBase, PrependChar)
209
{
210
SmallString str("ello");
211
str.prepend('H');
212
EXPECT_STREQ(str.c_str(), "Hello");
213
}
214
215
TEST(SmallStringBase, PrependConstChar)
216
{
217
SmallString str("World");
218
str.prepend("Hello ");
219
EXPECT_STREQ(str.c_str(), "Hello World");
220
}
221
222
TEST(SmallStringBase, PrependConstCharWithLength)
223
{
224
SmallString str("World");
225
str.prepend("Hello XXX", 6);
226
EXPECT_STREQ(str.c_str(), "Hello World");
227
}
228
229
TEST(SmallStringBase, PrependStdString)
230
{
231
SmallString str("World");
232
std::string prefix = "Hello ";
233
str.prepend(prefix);
234
EXPECT_STREQ(str.c_str(), "Hello World");
235
}
236
237
TEST(SmallStringBase, PrependStringView)
238
{
239
SmallString str("World");
240
str.prepend("Hello "sv);
241
EXPECT_STREQ(str.c_str(), "Hello World");
242
}
243
244
TEST(SmallStringBase, PrependSmallStringBase)
245
{
246
SmallString str("World");
247
SmallString prefix("Hello ");
248
str.prepend(prefix);
249
EXPECT_STREQ(str.c_str(), "Hello World");
250
}
251
252
TEST(SmallStringBase, PrependSprintf)
253
{
254
SmallString str(" items");
255
str.prepend_sprintf("%d", 5);
256
EXPECT_STREQ(str.c_str(), "5 items");
257
}
258
259
TEST(SmallStringBase, PrependFormat)
260
{
261
SmallString str(" items");
262
str.prepend_format("{}", 5);
263
EXPECT_STREQ(str.c_str(), "5 items");
264
}
265
266
// Insert Tests
267
TEST(SmallStringBase, InsertConstChar)
268
{
269
SmallString str("Hello World");
270
str.insert(5, " Beautiful");
271
EXPECT_STREQ(str.c_str(), "Hello Beautiful World");
272
}
273
274
TEST(SmallStringBase, InsertConstCharWithLength)
275
{
276
SmallString str("Hello World");
277
str.insert(5, " BeautifulXXX", 10);
278
EXPECT_STREQ(str.c_str(), "Hello Beautiful World");
279
}
280
281
TEST(SmallStringBase, InsertStdString)
282
{
283
SmallString str("Hello World");
284
std::string insert = " Beautiful";
285
str.insert(5, insert);
286
EXPECT_STREQ(str.c_str(), "Hello Beautiful World");
287
}
288
289
TEST(SmallStringBase, InsertStringView)
290
{
291
SmallString str("Hello World");
292
str.insert(5, " Beautiful"sv);
293
EXPECT_STREQ(str.c_str(), "Hello Beautiful World");
294
}
295
296
TEST(SmallStringBase, InsertSmallStringBase)
297
{
298
SmallString str("Hello World");
299
SmallString insert(" Beautiful");
300
str.insert(5, insert);
301
EXPECT_STREQ(str.c_str(), "Hello Beautiful World");
302
}
303
304
TEST(SmallStringBase, InsertNegativeOffset)
305
{
306
SmallString str("Hello World");
307
str.insert(-6, "Beautiful ");
308
EXPECT_STREQ(str.c_str(), "HelloBeautiful World");
309
}
310
311
// Format Tests
312
TEST(SmallStringBase, Sprintf)
313
{
314
SmallString str;
315
str.sprintf("Value: %d, String: %s", 42, "test");
316
EXPECT_STREQ(str.c_str(), "Value: 42, String: test");
317
}
318
319
TEST(SmallStringBase, Format)
320
{
321
SmallString str;
322
str.format("Value: {}, String: {}", 42, "test");
323
EXPECT_STREQ(str.c_str(), "Value: 42, String: test");
324
}
325
326
// Comparison Tests - equals
327
TEST(SmallStringBase, EqualsConstChar)
328
{
329
SmallString str("Hello");
330
EXPECT_TRUE(str.equals("Hello"));
331
EXPECT_FALSE(str.equals("hello"));
332
EXPECT_FALSE(str.equals("Hello World"));
333
}
334
335
TEST(SmallStringBase, EqualsSmallStringBase)
336
{
337
SmallString str("Hello");
338
SmallString other("Hello");
339
SmallString different("World");
340
EXPECT_TRUE(str.equals(other));
341
EXPECT_FALSE(str.equals(different));
342
}
343
344
TEST(SmallStringBase, EqualsStringView)
345
{
346
SmallString str("Hello");
347
EXPECT_TRUE(str.equals("Hello"sv));
348
EXPECT_FALSE(str.equals("hello"sv));
349
}
350
351
TEST(SmallStringBase, EqualsStdString)
352
{
353
SmallString str("Hello");
354
std::string same = "Hello";
355
std::string different = "World";
356
EXPECT_TRUE(str.equals(same));
357
EXPECT_FALSE(str.equals(different));
358
}
359
360
TEST(SmallStringBase, EqualsEmptyString)
361
{
362
SmallString str;
363
EXPECT_TRUE(str.equals(""));
364
EXPECT_FALSE(str.equals("x"));
365
}
366
367
// Comparison Tests - iequals (case insensitive)
368
TEST(SmallStringBase, IEqualsConstChar)
369
{
370
SmallString str("Hello");
371
EXPECT_TRUE(str.iequals("hello"));
372
EXPECT_TRUE(str.iequals("HELLO"));
373
EXPECT_TRUE(str.iequals("HeLLo"));
374
EXPECT_FALSE(str.iequals("World"));
375
}
376
377
TEST(SmallStringBase, IEqualsStringView)
378
{
379
SmallString str("Hello");
380
EXPECT_TRUE(str.iequals("hello"sv));
381
EXPECT_TRUE(str.iequals("HELLO"sv));
382
}
383
384
TEST(SmallStringBase, IEqualsStdString)
385
{
386
SmallString str("Hello");
387
std::string same = "hello";
388
EXPECT_TRUE(str.iequals(same));
389
}
390
391
// Comparison Tests - compare
392
TEST(SmallStringBase, CompareConstChar)
393
{
394
SmallString str("banana");
395
EXPECT_LT(str.compare("cherry"), 0);
396
EXPECT_GT(str.compare("apple"), 0);
397
EXPECT_EQ(str.compare("banana"), 0);
398
}
399
400
TEST(SmallStringBase, CompareSmallStringBase)
401
{
402
SmallString str("banana");
403
SmallString less("apple");
404
SmallString greater("cherry");
405
SmallString equal("banana");
406
EXPECT_GT(str.compare(less), 0);
407
EXPECT_LT(str.compare(greater), 0);
408
EXPECT_EQ(str.compare(equal), 0);
409
}
410
411
TEST(SmallStringBase, CompareStringView)
412
{
413
SmallString str("banana");
414
EXPECT_LT(str.compare("cherry"sv), 0);
415
EXPECT_GT(str.compare("apple"sv), 0);
416
EXPECT_EQ(str.compare("banana"sv), 0);
417
}
418
419
TEST(SmallStringBase, CompareStdString)
420
{
421
SmallString str("banana");
422
std::string less = "apple";
423
std::string greater = "cherry";
424
std::string equal = "banana";
425
EXPECT_GT(str.compare(less), 0);
426
EXPECT_LT(str.compare(greater), 0);
427
EXPECT_EQ(str.compare(equal), 0);
428
}
429
430
TEST(SmallStringBase, CompareEmptyStrings)
431
{
432
SmallString str;
433
EXPECT_EQ(str.compare(""), 0);
434
EXPECT_LT(str.compare("a"), 0);
435
436
str.assign("a");
437
SmallString empty;
438
EXPECT_GT(str.compare(empty), 0);
439
}
440
441
TEST(SmallStringBase, CompareDifferentLengths)
442
{
443
SmallString str("abc");
444
EXPECT_LT(str.compare("abcd"), 0);
445
EXPECT_GT(str.compare("ab"), 0);
446
}
447
448
// Comparison Tests - icompare (case insensitive)
449
TEST(SmallStringBase, ICompareConstChar)
450
{
451
SmallString str("Banana");
452
EXPECT_LT(str.icompare("CHERRY"), 0);
453
EXPECT_GT(str.icompare("APPLE"), 0);
454
EXPECT_EQ(str.icompare("BANANA"), 0);
455
}
456
457
TEST(SmallStringBase, ICompareSmallStringBase)
458
{
459
SmallString str("Banana");
460
SmallString equal("BANANA");
461
EXPECT_EQ(str.icompare(equal), 0);
462
}
463
464
TEST(SmallStringBase, ICompareStringView)
465
{
466
SmallString str("Banana");
467
EXPECT_EQ(str.icompare("BANANA"sv), 0);
468
}
469
470
TEST(SmallStringBase, ICompareStdString)
471
{
472
SmallString str("Banana");
473
std::string equal = "BANANA";
474
EXPECT_EQ(str.icompare(equal), 0);
475
}
476
477
// StartsWith Tests
478
TEST(SmallStringBase, StartsWithConstChar)
479
{
480
SmallString str("Hello World");
481
EXPECT_TRUE(str.starts_with("Hello"));
482
EXPECT_TRUE(str.starts_with("H"));
483
EXPECT_TRUE(str.starts_with(""));
484
EXPECT_FALSE(str.starts_with("World"));
485
EXPECT_FALSE(str.starts_with("hello"));
486
}
487
488
TEST(SmallStringBase, StartsWithCaseInsensitive)
489
{
490
SmallString str("Hello World");
491
EXPECT_TRUE(str.starts_with("HELLO", false));
492
EXPECT_TRUE(str.starts_with("hello", false));
493
EXPECT_FALSE(str.starts_with("hello", true));
494
}
495
496
TEST(SmallStringBase, StartsWithSmallStringBase)
497
{
498
SmallString str("Hello World");
499
SmallString prefix("Hello");
500
EXPECT_TRUE(str.starts_with(prefix));
501
}
502
503
TEST(SmallStringBase, StartsWithStringView)
504
{
505
SmallString str("Hello World");
506
EXPECT_TRUE(str.starts_with("Hello"sv));
507
}
508
509
TEST(SmallStringBase, StartsWithStdString)
510
{
511
SmallString str("Hello World");
512
std::string prefix = "Hello";
513
EXPECT_TRUE(str.starts_with(prefix));
514
}
515
516
TEST(SmallStringBase, StartsWithLongerPrefix)
517
{
518
SmallString str("Hi");
519
EXPECT_FALSE(str.starts_with("Hello"));
520
}
521
522
// EndsWith Tests
523
TEST(SmallStringBase, EndsWithConstChar)
524
{
525
SmallString str("Hello World");
526
EXPECT_TRUE(str.ends_with("World"));
527
EXPECT_TRUE(str.ends_with("d"));
528
EXPECT_TRUE(str.ends_with(""));
529
EXPECT_FALSE(str.ends_with("Hello"));
530
EXPECT_FALSE(str.ends_with("world"));
531
}
532
533
TEST(SmallStringBase, EndsWithCaseInsensitive)
534
{
535
SmallString str("Hello World");
536
EXPECT_TRUE(str.ends_with("WORLD", false));
537
EXPECT_TRUE(str.ends_with("world", false));
538
EXPECT_FALSE(str.ends_with("world", true));
539
}
540
541
TEST(SmallStringBase, EndsWithSmallStringBase)
542
{
543
SmallString str("Hello World");
544
SmallString suffix("World");
545
EXPECT_TRUE(str.ends_with(suffix));
546
}
547
548
TEST(SmallStringBase, EndsWithStringView)
549
{
550
SmallString str("Hello World");
551
EXPECT_TRUE(str.ends_with("World"sv));
552
}
553
554
TEST(SmallStringBase, EndsWithStdString)
555
{
556
SmallString str("Hello World");
557
std::string suffix = "World";
558
EXPECT_TRUE(str.ends_with(suffix));
559
}
560
561
TEST(SmallStringBase, EndsWithLongerSuffix)
562
{
563
SmallString str("Hi");
564
EXPECT_FALSE(str.ends_with("Hello"));
565
}
566
567
// Find Tests
568
TEST(SmallStringBase, FindChar)
569
{
570
SmallString str("Hello World");
571
EXPECT_EQ(str.find('o'), 4);
572
EXPECT_EQ(str.find('W'), 6);
573
EXPECT_EQ(str.find('z'), -1);
574
}
575
576
TEST(SmallStringBase, FindCharWithOffset)
577
{
578
SmallString str("Hello World");
579
EXPECT_EQ(str.find('o', 5), 7);
580
EXPECT_EQ(str.find('o', 8), -1);
581
}
582
583
TEST(SmallStringBase, RFindChar)
584
{
585
SmallString str("Hello World");
586
EXPECT_EQ(str.rfind('o'), 7);
587
EXPECT_EQ(str.rfind('l'), 9);
588
}
589
590
TEST(SmallStringBase, FindCharEmptyString)
591
{
592
SmallString str;
593
EXPECT_EQ(str.find('a'), -1);
594
EXPECT_EQ(str.rfind('a'), -1);
595
}
596
597
TEST(SmallStringBase, FindString)
598
{
599
SmallString str("Hello World Hello");
600
EXPECT_EQ(str.find("Hello"), 0);
601
EXPECT_EQ(str.find("World"), 6);
602
EXPECT_EQ(str.find("Goodbye"), -1);
603
}
604
605
TEST(SmallStringBase, FindStringWithOffset)
606
{
607
SmallString str("Hello World Hello");
608
EXPECT_EQ(str.find("Hello", 1), 12);
609
EXPECT_EQ(str.find("Hello", 13), -1);
610
}
611
612
// Count Tests
613
TEST(SmallStringBase, Count)
614
{
615
SmallString str("Hello World");
616
EXPECT_EQ(str.count('l'), 3u);
617
EXPECT_EQ(str.count('o'), 2u);
618
EXPECT_EQ(str.count('z'), 0u);
619
}
620
621
// Replace Tests
622
TEST(SmallStringBase, Replace)
623
{
624
SmallString str("Hello World");
625
u32 count = str.replace("World", "Universe");
626
EXPECT_EQ(count, 1u);
627
EXPECT_STREQ(str.c_str(), "Hello Universe");
628
}
629
630
TEST(SmallStringBase, ReplaceMultiple)
631
{
632
SmallString str("Hello Hello Hello");
633
u32 count = str.replace("Hello", "Hi");
634
EXPECT_EQ(count, 3u);
635
EXPECT_STREQ(str.c_str(), "Hi Hi Hi");
636
}
637
638
TEST(SmallStringBase, ReplaceNoMatch)
639
{
640
SmallString str("Hello World");
641
u32 count = str.replace("Goodbye", "Hi");
642
EXPECT_EQ(count, 0u);
643
EXPECT_STREQ(str.c_str(), "Hello World");
644
}
645
646
TEST(SmallStringBase, ReplaceWithLonger)
647
{
648
SmallString str("Hi");
649
str.replace("Hi", "Hello World");
650
EXPECT_STREQ(str.c_str(), "Hello World");
651
}
652
653
TEST(SmallStringBase, ReplaceWithShorter)
654
{
655
SmallString str("Hello World");
656
str.replace("Hello World", "Hi");
657
EXPECT_STREQ(str.c_str(), "Hi");
658
}
659
660
// Erase Tests
661
TEST(SmallStringBase, EraseFromOffset)
662
{
663
SmallString str("Hello World");
664
str.erase(5);
665
EXPECT_STREQ(str.c_str(), "Hello");
666
}
667
668
TEST(SmallStringBase, EraseWithCount)
669
{
670
SmallString str("Hello World");
671
str.erase(5, 1);
672
EXPECT_STREQ(str.c_str(), "HelloWorld");
673
}
674
675
TEST(SmallStringBase, EraseNegativeOffset)
676
{
677
SmallString str("Hello World");
678
str.erase(-5);
679
EXPECT_STREQ(str.c_str(), "Hello ");
680
}
681
682
TEST(SmallStringBase, EraseAll)
683
{
684
SmallString str("Hello World");
685
str.erase(0);
686
EXPECT_TRUE(str.empty());
687
}
688
689
// Reserve/Resize Tests
690
TEST(SmallStringBase, Reserve)
691
{
692
SmallString str;
693
str.reserve(100);
694
EXPECT_GE(str.buffer_size(), 100u);
695
EXPECT_TRUE(str.empty());
696
}
697
698
TEST(SmallStringBase, ResizeGrow)
699
{
700
SmallString str("Hello");
701
str.resize(10, 'X');
702
EXPECT_EQ(str.length(), 10u);
703
EXPECT_STREQ(str.c_str(), "HelloXXXXX");
704
}
705
706
TEST(SmallStringBase, ResizeShrink)
707
{
708
SmallString str("Hello World");
709
str.resize(5);
710
EXPECT_EQ(str.length(), 5u);
711
EXPECT_STREQ(str.c_str(), "Hello");
712
}
713
714
TEST(SmallStringBase, SetSize)
715
{
716
SmallString str("Hello World");
717
str.set_size(5);
718
EXPECT_EQ(str.length(), 5u);
719
EXPECT_STREQ(str.c_str(), "Hello");
720
}
721
722
TEST(SmallStringBase, UpdateSize)
723
{
724
SmallString str;
725
str.reserve(20);
726
std::strcpy(str.data(), "Manual");
727
str.update_size();
728
EXPECT_EQ(str.length(), 6u);
729
EXPECT_STREQ(str.c_str(), "Manual");
730
}
731
732
TEST(SmallStringBase, MakeRoomFor)
733
{
734
SmallString str("Hello");
735
str.make_room_for(1000);
736
EXPECT_GE(str.buffer_size(), str.length() + 1000u);
737
}
738
739
// Case Conversion Tests
740
TEST(SmallStringBase, ConvertToLowerCase)
741
{
742
SmallString str("HELLO WORLD");
743
str.convert_to_lower_case();
744
EXPECT_STREQ(str.c_str(), "hello world");
745
}
746
747
TEST(SmallStringBase, ConvertToUpperCase)
748
{
749
SmallString str("hello world");
750
str.convert_to_upper_case();
751
EXPECT_STREQ(str.c_str(), "HELLO WORLD");
752
}
753
754
// View/Substr Tests
755
TEST(SmallStringBase, View)
756
{
757
SmallString str("Hello World");
758
std::string_view sv = str.view();
759
EXPECT_EQ(sv, "Hello World");
760
}
761
762
TEST(SmallStringBase, ViewEmpty)
763
{
764
SmallString str;
765
std::string_view sv = str.view();
766
EXPECT_TRUE(sv.empty());
767
}
768
769
TEST(SmallStringBase, Substr)
770
{
771
SmallString str("Hello World");
772
std::string_view sv = str.substr(0, 5);
773
EXPECT_EQ(sv, "Hello");
774
}
775
776
TEST(SmallStringBase, SubstrNegativeOffset)
777
{
778
SmallString str("Hello World");
779
std::string_view sv = str.substr(-5, 5);
780
EXPECT_EQ(sv, "World");
781
}
782
783
TEST(SmallStringBase, SubstrNegativeCount)
784
{
785
SmallString str("Hello World");
786
std::string_view sv = str.substr(0, -6);
787
EXPECT_EQ(sv, "Hello");
788
}
789
790
// Span Tests
791
TEST(SmallStringBase, CSpan)
792
{
793
SmallString str("Hello");
794
std::span<const char> sp = str.cspan();
795
EXPECT_EQ(sp.size(), 5u);
796
EXPECT_EQ(sp[0], 'H');
797
}
798
799
TEST(SmallStringBase, Span)
800
{
801
SmallString str("Hello");
802
std::span<char> sp = str.span();
803
sp[0] = 'J';
804
EXPECT_STREQ(str.c_str(), "Jello");
805
}
806
807
TEST(SmallStringBase, CBSpan)
808
{
809
SmallString str("AB");
810
std::span<const u8> sp = str.cbspan();
811
EXPECT_EQ(sp.size(), 2u);
812
EXPECT_EQ(sp[0], static_cast<u8>('A'));
813
}
814
815
TEST(SmallStringBase, BSpan)
816
{
817
SmallString str("AB");
818
std::span<u8> sp = str.bspan();
819
sp[0] = static_cast<u8>('X');
820
EXPECT_STREQ(str.c_str(), "XB");
821
}
822
823
// STL Adapter Tests
824
TEST(SmallStringBase, Front)
825
{
826
SmallString str("Hello");
827
EXPECT_EQ(str.front(), 'H');
828
}
829
830
TEST(SmallStringBase, Back)
831
{
832
SmallString str("Hello");
833
EXPECT_EQ(str.back(), 'o');
834
}
835
836
TEST(SmallStringBase, PushBack)
837
{
838
SmallString str("Hello");
839
str.push_back('!');
840
EXPECT_STREQ(str.c_str(), "Hello!");
841
}
842
843
TEST(SmallStringBase, PopBack)
844
{
845
SmallString str("Hello!");
846
str.pop_back();
847
EXPECT_STREQ(str.c_str(), "Hello");
848
}
849
850
// Accessor Tests
851
TEST(SmallStringBase, Length)
852
{
853
SmallString str("Hello");
854
EXPECT_EQ(str.length(), 5u);
855
}
856
857
TEST(SmallStringBase, Empty)
858
{
859
SmallString str;
860
EXPECT_TRUE(str.empty());
861
str.assign("x");
862
EXPECT_FALSE(str.empty());
863
}
864
865
TEST(SmallStringBase, BufferSize)
866
{
867
SmallString str;
868
EXPECT_GT(str.buffer_size(), 0u);
869
}
870
871
TEST(SmallStringBase, CStr)
872
{
873
SmallString str("Hello");
874
EXPECT_STREQ(str.c_str(), "Hello");
875
}
876
877
TEST(SmallStringBase, Data)
878
{
879
SmallString str("Hello");
880
str.data()[0] = 'J';
881
EXPECT_STREQ(str.c_str(), "Jello");
882
}
883
884
TEST(SmallStringBase, EndPtr)
885
{
886
SmallString str("Hello");
887
const char* end = str.end_ptr();
888
EXPECT_EQ(end - str.c_str(), 5);
889
}
890
891
// Operator Tests
892
TEST(SmallStringBase, OperatorConstCharStar)
893
{
894
SmallString str("Hello");
895
const char* ptr = str;
896
EXPECT_STREQ(ptr, "Hello");
897
}
898
899
TEST(SmallStringBase, OperatorCharStar)
900
{
901
SmallString str("Hello");
902
char* ptr = str;
903
ptr[0] = 'J';
904
EXPECT_STREQ(str.c_str(), "Jello");
905
}
906
907
TEST(SmallStringBase, OperatorStringView)
908
{
909
SmallString str("Hello");
910
std::string_view sv = str;
911
EXPECT_EQ(sv, "Hello");
912
}
913
914
TEST(SmallStringBase, OperatorEqualityConstChar)
915
{
916
SmallString str("Hello");
917
EXPECT_TRUE(str == "Hello");
918
EXPECT_FALSE(str == "World");
919
}
920
921
TEST(SmallStringBase, OperatorEqualitySmallStringBase)
922
{
923
SmallString str("Hello");
924
SmallString other("Hello");
925
SmallString different("World");
926
EXPECT_TRUE(str == other);
927
EXPECT_FALSE(str == different);
928
}
929
930
TEST(SmallStringBase, OperatorEqualityStringView)
931
{
932
SmallString str("Hello");
933
EXPECT_TRUE(str == "Hello"sv);
934
EXPECT_FALSE(str == "World"sv);
935
}
936
937
TEST(SmallStringBase, OperatorEqualityStdString)
938
{
939
SmallString str("Hello");
940
std::string same = "Hello";
941
std::string different = "World";
942
EXPECT_TRUE(str == same);
943
EXPECT_FALSE(str == different);
944
}
945
946
TEST(SmallStringBase, OperatorInequality)
947
{
948
SmallString str("Hello");
949
EXPECT_TRUE(str != "World");
950
EXPECT_FALSE(str != "Hello");
951
}
952
953
TEST(SmallStringBase, OperatorLessThan)
954
{
955
SmallString str("apple");
956
EXPECT_TRUE(str < "banana");
957
EXPECT_FALSE(str < "aardvark");
958
}
959
960
TEST(SmallStringBase, OperatorGreaterThan)
961
{
962
SmallString str("banana");
963
EXPECT_TRUE(str > "apple");
964
EXPECT_FALSE(str > "cherry");
965
}
966
967
TEST(SmallStringBase, OperatorAssignConstChar)
968
{
969
SmallString str;
970
str = "Hello";
971
EXPECT_STREQ(str.c_str(), "Hello");
972
}
973
974
TEST(SmallStringBase, OperatorAssignStdString)
975
{
976
SmallString str;
977
std::string s = "Hello";
978
str = s;
979
EXPECT_STREQ(str.c_str(), "Hello");
980
}
981
982
TEST(SmallStringBase, OperatorAssignStringView)
983
{
984
SmallString str;
985
str = "Hello"sv;
986
EXPECT_STREQ(str.c_str(), "Hello");
987
}
988
989
TEST(SmallStringBase, OperatorAssignSmallStringBase)
990
{
991
SmallString str;
992
SmallString other("Hello");
993
str = other;
994
EXPECT_STREQ(str.c_str(), "Hello");
995
}
996
997
TEST(SmallStringBase, OperatorAssignMove)
998
{
999
SmallString str;
1000
SmallString other("Hello");
1001
str = std::move(other);
1002
EXPECT_STREQ(str.c_str(), "Hello");
1003
}
1004
1005
// ShrinkToFit Tests
1006
TEST(SmallStringBase, ShrinkToFit)
1007
{
1008
SmallString str;
1009
str.reserve(1000);
1010
str.assign("Hi");
1011
u32 size_before = str.buffer_size();
1012
str.shrink_to_fit();
1013
EXPECT_LE(str.buffer_size(), size_before);
1014
EXPECT_STREQ(str.c_str(), "Hi");
1015
}
1016
1017
TEST(SmallStringBase, ShrinkToFitEmpty)
1018
{
1019
SmallString str;
1020
str.reserve(1000);
1021
str.clear();
1022
str.shrink_to_fit();
1023
EXPECT_TRUE(str.empty());
1024
}
1025
1026
// Edge Cases
1027
TEST(SmallStringBase, AppendEmptyString)
1028
{
1029
SmallString str("Hello");
1030
str.append("");
1031
EXPECT_STREQ(str.c_str(), "Hello");
1032
}
1033
1034
TEST(SmallStringBase, PrependEmptyString)
1035
{
1036
SmallString str("Hello");
1037
str.prepend("");
1038
EXPECT_STREQ(str.c_str(), "Hello");
1039
}
1040
1041
TEST(SmallStringBase, InsertEmptyString)
1042
{
1043
SmallString str("Hello");
1044
str.insert(2, "");
1045
EXPECT_STREQ(str.c_str(), "Hello");
1046
}
1047
1048
TEST(SmallStringBase, LargeStringAppend)
1049
{
1050
SmallString str;
1051
for (int i = 0; i < 1000; i++)
1052
{
1053
str.append('X');
1054
}
1055
EXPECT_EQ(str.length(), 1000u);
1056
}
1057
1058
TEST(SmallStringBase, EraseNegativeOffsetMiddle)
1059
{
1060
SmallString str("Hello World");
1061
// Erase 3 characters starting from position -6 (i.e., position 5 = ' ')
1062
// Should result in "Hellorld" (erase " Wo")
1063
str.erase(-6, 3);
1064
EXPECT_STREQ(str.c_str(), "Hellorld");
1065
EXPECT_EQ(str.length(), 8u);
1066
}
1067
1068
TEST(SmallStringBase, MoveAssignmentActuallyMoves)
1069
{
1070
// Create a string large enough to force heap allocation
1071
SmallString source;
1072
source.reserve(1000);
1073
source.assign("This is a long string that should be on the heap");
1074
1075
const char* original_buffer = source.c_str();
1076
1077
SmallString dest;
1078
dest = std::move(source);
1079
1080
EXPECT_STREQ(dest.c_str(), "This is a long string that should be on the heap");
1081
EXPECT_TRUE(source.empty() || source.c_str() != original_buffer);
1082
}
1083
1084
TEST(SmallStringBase, SmallStringBaseCaseInsensitive)
1085
{
1086
SmallString str("Hello");
1087
SmallString other("HELLO");
1088
SmallString otherLower("hello");
1089
SmallString otherMixed("hElLo");
1090
1091
EXPECT_TRUE(str.iequals(other));
1092
EXPECT_TRUE(str.iequals(otherLower));
1093
EXPECT_TRUE(str.iequals(otherMixed));
1094
1095
// Check const char* overloads
1096
EXPECT_TRUE(str.iequals("Hello"));
1097
EXPECT_TRUE(str.iequals("HELLO"));
1098
EXPECT_TRUE(str.iequals("hello"));
1099
EXPECT_TRUE(str.iequals("hElLo"));
1100
}
1101
1102
#ifdef _WIN32
1103
1104
TEST(SmallStringBase, WStringViewAssignNullTermination)
1105
{
1106
SmallString str;
1107
// First assign something to ensure the buffer has garbage after
1108
str.assign("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
1109
1110
// Now assign a shorter wstring
1111
std::wstring_view wstr = L"Hello";
1112
str.assign(wstr);
1113
1114
EXPECT_EQ(str.length(), 5u);
1115
EXPECT_STREQ(str.c_str(), "Hello");
1116
1117
// Verify the string is properly null-terminated by checking length matches strlen
1118
EXPECT_EQ(std::strlen(str.c_str()), str.length());
1119
}
1120
1121
TEST(SmallStringBase, WStringViewAssignEmptyFollowedByContent)
1122
{
1123
SmallString str;
1124
str.reserve(100);
1125
1126
// Assign via wstring_view
1127
std::wstring_view wstr = L"Test";
1128
str.assign(wstr);
1129
1130
// The string should be exactly "Test" with no trailing garbage
1131
EXPECT_EQ(str.length(), 4u);
1132
EXPECT_EQ(str.view(), "Test");
1133
1134
// Append should work correctly if null-terminated properly
1135
str.append("123");
1136
EXPECT_STREQ(str.c_str(), "Test123");
1137
}
1138
#endif
1139
1140
TEST(SmallStringBase, EraseNegativeOffsetPreservesRemainder)
1141
{
1142
SmallString str("ABCDEFGHIJ");
1143
// Erase 2 characters starting from -5 (position 5 = 'F')
1144
// Should result in "ABCDEHIJ" (erase "FG")
1145
str.erase(-5, 2);
1146
EXPECT_STREQ(str.c_str(), "ABCDEHIJ");
1147
EXPECT_EQ(str.length(), 8u);
1148
}
1149
1150
TEST(SmallStringBase, AppendHexNullTermination)
1151
{
1152
SmallString str;
1153
// Pre-fill with garbage to detect missing null terminator
1154
str.assign("XXXXXXXXXXXXXXXXXXXX");
1155
str.clear();
1156
1157
const u8 data[] = {0xAB, 0xCD};
1158
str.append_hex(data, sizeof(data));
1159
1160
EXPECT_EQ(str.length(), 4u);
1161
EXPECT_STREQ(str.c_str(), "abcd");
1162
// Verify null termination by checking strlen matches length
1163
EXPECT_EQ(std::strlen(str.c_str()), str.length());
1164
}
1165
1166
TEST(SmallStringBase, AppendHexCommaSeparatedNullTermination)
1167
{
1168
SmallString str;
1169
str.assign("XXXXXXXXXXXXXXXXXXXX");
1170
str.clear();
1171
1172
const u8 data[] = {0xAB, 0xCD};
1173
str.append_hex(data, sizeof(data), true);
1174
1175
EXPECT_EQ(str.length(), 10u);
1176
EXPECT_STREQ(str.c_str(), "0xab, 0xcd");
1177
EXPECT_EQ(std::strlen(str.c_str()), str.length());
1178
}
1179
1180
TEST(SmallStringBase, AppendHexThenAppendMore)
1181
{
1182
SmallString str("Prefix: ");
1183
const u8 data[] = {0xFF};
1184
str.append_hex(data, sizeof(data));
1185
str.append(" Suffix");
1186
1187
// If null terminator is missing, append will start from wrong position
1188
EXPECT_STREQ(str.c_str(), "Prefix: ff Suffix");
1189
}
1190
1191
TEST(SmallStringBase, PrependSprintfLargeString)
1192
{
1193
SmallString str(" end");
1194
1195
std::string largeFormat(1500, 'X');
1196
str.prepend_sprintf("%s", largeFormat.c_str());
1197
1198
std::string expected = largeFormat + " end";
1199
EXPECT_STREQ(str.c_str(), expected.c_str());
1200
}
1201
1202
TEST(SmallStringBase, ShrinkToFitEmptyHeapStringResetsState)
1203
{
1204
SmallString str;
1205
str.reserve(1000); // Force heap allocation
1206
str.clear(); // Empty the string
1207
str.shrink_to_fit(); // Should free heap and restore to valid state
1208
1209
// After shrink_to_fit on empty heap string, string should still be usable
1210
EXPECT_TRUE(str.empty());
1211
EXPECT_EQ(str.length(), 0u);
1212
1213
// These operations should not crash
1214
str.append("Hello");
1215
EXPECT_STREQ(str.c_str(), "Hello");
1216
}
1217
1218
TEST(SmallStringBase, ShrinkToFitEmptyThenClear)
1219
{
1220
SmallString str;
1221
str.reserve(1000); // Force heap allocation
1222
str.clear();
1223
str.shrink_to_fit();
1224
1225
// clear() should not crash after shrink_to_fit on empty heap string
1226
str.clear();
1227
EXPECT_TRUE(str.empty());
1228
}
1229
1230
TEST(SmallStringBase, ShrinkToFitEmptyThenReserve)
1231
{
1232
SmallString str;
1233
str.reserve(1000); // Force heap allocation
1234
str.clear();
1235
str.shrink_to_fit();
1236
1237
// reserve() should work correctly after shrink_to_fit on empty heap string
1238
str.reserve(100);
1239
EXPECT_GE(str.buffer_size(), 100u);
1240
1241
str.assign("Test");
1242
EXPECT_STREQ(str.c_str(), "Test");
1243
}
1244
1245
TEST(SmallStringBase, ReplaceMiddleNullTermination)
1246
{
1247
SmallString str("Hello World End");
1248
str.replace("World", "X");
1249
1250
EXPECT_EQ(str.length(), 11u); // "Hello X End" = 11 chars
1251
EXPECT_STREQ(str.c_str(), "Hello X End");
1252
1253
// Verify null termination by checking strlen matches length
1254
EXPECT_EQ(std::strlen(str.c_str()), str.length());
1255
}
1256
1257
TEST(SmallStringBase, ReplaceMiddleShorterReplacement)
1258
{
1259
SmallString str("AAABBBCCC");
1260
str.replace("BBB", "X");
1261
1262
EXPECT_EQ(str.length(), 7u); // "AAAXCCC" = 7 chars
1263
EXPECT_STREQ(str.c_str(), "AAAXCCC");
1264
EXPECT_EQ(std::strlen(str.c_str()), str.length());
1265
}
1266
1267
TEST(SmallStringBase, ReplaceMiddleThenAppend)
1268
{
1269
SmallString str("Hello World End");
1270
str.replace("World", "X");
1271
1272
// If null terminator is missing, append will start from wrong position
1273
str.append("!");
1274
EXPECT_STREQ(str.c_str(), "Hello X End!");
1275
EXPECT_EQ(str.length(), 12u);
1276
}
1277
1278
TEST(SmallStringBase, ReplaceMultipleInMiddle)
1279
{
1280
SmallString str("aXXXbXXXc");
1281
u32 count = str.replace("XXX", "Y");
1282
1283
EXPECT_EQ(count, 2u);
1284
EXPECT_STREQ(str.c_str(), "aYbYc");
1285
EXPECT_EQ(str.length(), 5u);
1286
EXPECT_EQ(std::strlen(str.c_str()), str.length());
1287
}
1288
1289
TEST(SmallStringBase, ReplaceEmptySearchString)
1290
{
1291
SmallString str("Hello");
1292
1293
// This should either be a no-op or handle gracefully, not infinite loop
1294
// Set a timeout expectation or just verify it completes
1295
u32 count = str.replace("", "X");
1296
1297
// Expected: either 0 replacements, or reasonable behavior
1298
// Actual with bug: infinite loop (test hangs)
1299
EXPECT_EQ(count, 0u);
1300
EXPECT_STREQ(str.c_str(), "Hello");
1301
}
1302
1303
//////////////////////////////////////////////////////////////////////////
1304
// SmallStackString Test Suite
1305
//////////////////////////////////////////////////////////////////////////
1306
1307
TEST(SmallStackString, DefaultConstructor)
1308
{
1309
SmallString s;
1310
EXPECT_TRUE(s.empty());
1311
EXPECT_EQ(s.length(), 0u);
1312
EXPECT_EQ(s.buffer_size(), 256u);
1313
}
1314
1315
TEST(SmallStackString, ConstCharConstructor)
1316
{
1317
SmallString s("Hello");
1318
EXPECT_EQ(s.length(), 5u);
1319
EXPECT_STREQ(s.c_str(), "Hello");
1320
}
1321
1322
TEST(SmallStackString, ConstCharWithLengthConstructor)
1323
{
1324
SmallString s("Hello World", 5);
1325
EXPECT_EQ(s.length(), 5u);
1326
EXPECT_STREQ(s.c_str(), "Hello");
1327
}
1328
1329
TEST(SmallStackString, CopyConstructorFromBase)
1330
{
1331
SmallString original("Test");
1332
SmallStringBase& base = original;
1333
SmallString copy(base);
1334
EXPECT_STREQ(copy.c_str(), "Test");
1335
}
1336
1337
TEST(SmallStackString, MoveConstructorFromBase)
1338
{
1339
SmallString original("Test");
1340
SmallStringBase& base = original;
1341
SmallString moved(std::move(base));
1342
EXPECT_STREQ(moved.c_str(), "Test");
1343
}
1344
1345
TEST(SmallStackString, CopyConstructorFromSame)
1346
{
1347
SmallString original("Test");
1348
SmallString copy(original);
1349
EXPECT_STREQ(copy.c_str(), "Test");
1350
}
1351
1352
TEST(SmallStackString, MoveConstructorFromSame)
1353
{
1354
SmallString original("Test");
1355
SmallString moved(std::move(original));
1356
EXPECT_STREQ(moved.c_str(), "Test");
1357
}
1358
1359
TEST(SmallStackString, StdStringConstructor)
1360
{
1361
std::string s = "Hello";
1362
SmallString ss(s);
1363
EXPECT_STREQ(ss.c_str(), "Hello");
1364
}
1365
1366
TEST(SmallStackString, StringViewConstructor)
1367
{
1368
SmallString ss("Hello"sv);
1369
EXPECT_STREQ(ss.c_str(), "Hello");
1370
}
1371
1372
TEST(SmallStackString, AssignmentFromBase)
1373
{
1374
SmallString str;
1375
SmallString other("Source");
1376
SmallStringBase& base = other;
1377
str = base;
1378
EXPECT_STREQ(str.c_str(), "Source");
1379
}
1380
1381
TEST(SmallStackString, AssignmentMoveFromBase)
1382
{
1383
SmallString str;
1384
SmallString other("Source");
1385
SmallStringBase& base = other;
1386
str = std::move(base);
1387
EXPECT_STREQ(str.c_str(), "Source");
1388
}
1389
1390
TEST(SmallStackString, AssignmentFromSame)
1391
{
1392
SmallString str;
1393
SmallString other("Source");
1394
str = other;
1395
EXPECT_STREQ(str.c_str(), "Source");
1396
}
1397
1398
TEST(SmallStackString, AssignmentMoveFromSame)
1399
{
1400
SmallString str;
1401
SmallString other("Source");
1402
str = std::move(other);
1403
EXPECT_STREQ(str.c_str(), "Source");
1404
}
1405
1406
TEST(SmallStackString, AssignmentFromStdString)
1407
{
1408
SmallString str;
1409
std::string s = "Source";
1410
str = s;
1411
EXPECT_STREQ(str.c_str(), "Source");
1412
}
1413
1414
TEST(SmallStackString, AssignmentFromStringView)
1415
{
1416
SmallString str;
1417
str = "Source"sv;
1418
EXPECT_STREQ(str.c_str(), "Source");
1419
}
1420
1421
TEST(SmallStackString, AssignmentFromConstChar)
1422
{
1423
SmallString str;
1424
str = "Source";
1425
EXPECT_STREQ(str.c_str(), "Source");
1426
}
1427
1428
TEST(SmallStackString, FromSprintf)
1429
{
1430
SmallString s = SmallString::from_sprintf("Value: %d", 42);
1431
EXPECT_STREQ(s.c_str(), "Value: 42");
1432
}
1433
1434
TEST(SmallStackString, FromFormat)
1435
{
1436
SmallString s = SmallString::from_format("Value: {}", 42);
1437
EXPECT_STREQ(s.c_str(), "Value: 42");
1438
}
1439
1440
TEST(SmallStackString, FromVFormat)
1441
{
1442
constexpr int i = 42;
1443
auto args = fmt::make_format_args(i);
1444
SmallString s = SmallString::from_vformat("Value: {}", args);
1445
EXPECT_STREQ(s.c_str(), "Value: 42");
1446
}
1447
1448
TEST(SmallStackString, TinyStringSize)
1449
{
1450
TinyString tiny;
1451
EXPECT_EQ(tiny.buffer_size(), 64u);
1452
}
1453
1454
TEST(SmallStackString, SmallStringSize)
1455
{
1456
SmallString small;
1457
EXPECT_EQ(small.buffer_size(), 256u);
1458
}
1459
1460
TEST(SmallStackString, LargeStringSize)
1461
{
1462
LargeString large;
1463
EXPECT_EQ(large.buffer_size(), 512u);
1464
}
1465
1466
TEST(SmallStackString, StackBufferOverflow)
1467
{
1468
TinyString tiny;
1469
// TinyString has 64 bytes, so appending more should trigger heap allocation
1470
for (int i = 0; i < 100; i++)
1471
{
1472
tiny.append('X');
1473
}
1474
EXPECT_EQ(tiny.length(), 100u);
1475
EXPECT_GE(tiny.buffer_size(), 100u);
1476
}
1477
1478
TEST(SmallStackString, FmtFormatter)
1479
{
1480
SmallString s("test");
1481
std::string formatted = fmt::format("Value: {}", s);
1482
EXPECT_EQ(formatted, "Value: test");
1483
}
1484
1485
TEST(SmallStackString, TinyStringFmtFormatter)
1486
{
1487
TinyString s("tiny");
1488
std::string formatted = fmt::format("Value: {}", s);
1489
EXPECT_EQ(formatted, "Value: tiny");
1490
}
1491
1492
TEST(SmallStackString, LargeStringFmtFormatter)
1493
{
1494
LargeString s("large");
1495
std::string formatted = fmt::format("Value: {}", s);
1496
EXPECT_EQ(formatted, "Value: large");
1497
}
1498
1499
1500
TEST(SmallStackString, MoveConstructorFromSameType)
1501
{
1502
SmallString source;
1503
source.reserve(1000); // Force heap allocation
1504
source.assign("Heap allocated string");
1505
1506
const char* original_buffer = source.c_str();
1507
1508
SmallString dest(std::move(source));
1509
1510
EXPECT_STREQ(dest.c_str(), "Heap allocated string");
1511
// After proper move, source should be empty or have different buffer
1512
EXPECT_TRUE(source.empty() || source.c_str() != original_buffer);
1513
}
1514
1515
TEST(SmallStackString, MoveConstructorFromBaseHeap)
1516
{
1517
SmallString source;
1518
source.reserve(1000); // Force heap allocation
1519
source.assign("Heap allocated string");
1520
1521
const char* original_buffer = source.c_str();
1522
SmallStringBase& baseRef = source;
1523
1524
SmallString dest(std::move(baseRef));
1525
1526
EXPECT_STREQ(dest.c_str(), "Heap allocated string");
1527
// After proper move, source should be empty or have different buffer
1528
EXPECT_TRUE(source.empty() || source.c_str() != original_buffer);
1529
}
1530
1531