source: mainline/uspace/lib/cpp/src/__bits/test/string.cpp@ c6f23a7

Last change on this file since c6f23a7 was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 17.2 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <initializer_list>
8#include <__bits/test/tests.hpp>
9#include <string>
10#include <cstdio>
11
12namespace std::test
13{
14 bool string_test::run(bool report)
15 {
16 report_ = report;
17 start();
18
19 test_construction_and_assignment();
20 test_append();
21 test_insert();
22 test_erase();
23 test_replace();
24 test_copy();
25 test_find();
26 test_substr();
27 test_compare();
28
29 return end();
30 }
31
32 const char* string_test::name()
33 {
34 return "string";
35 }
36
37 void string_test::test_construction_and_assignment()
38 {
39 const char* check1 = "hello";
40
41 std::string str1{"hello"};
42 test_eq(
43 "size of string",
44 str1.size(), 5ul
45 );
46 test_eq(
47 "initialization from a cstring literal",
48 str1.begin(), str1.end(),
49 check1, check1 + 5
50 );
51
52 std::string str2{str1};
53 test_eq(
54 "copy constructor",
55 str1.begin(), str1.end(),
56 str2.begin(), str2.end()
57 );
58
59 std::string str3{std::move(str1)};
60 test_eq(
61 "move constructor equality",
62 str2.begin(), str2.end(),
63 str3.begin(), str3.end()
64 );
65 test_eq(
66 "move constructor source empty",
67 str1.size(), 0ul
68 );
69
70 std::string str4{};
71 test_eq(
72 "default constructor empty",
73 str4.size(), 0ul
74 );
75
76 str4.assign(str3, 2ul, 2ul);
77 test_eq(
78 "assign substring to an empty string",
79 str4.begin(), str4.end(),
80 str3.begin() + 2, str3.begin() + 4
81 );
82
83 std::string str5{str3.begin() + 2, str3.begin() + 4};
84 test_eq(
85 "constructor from a pair of iterators",
86 str5.begin(), str5.end(),
87 str3.begin() + 2, str3.begin() + 4
88 );
89 }
90
91 void string_test::test_append()
92 {
93 std::string check{"hello, world"};
94
95 std::string str1{"hello, "};
96 str1.append("world");
97 test_eq(
98 "append cstring",
99 str1.begin(), str1.end(),
100 check.begin(), check.end()
101 );
102
103 std::string str2{"hello, "};
104 str2.append(std::string{"world"});
105 test_eq(
106 "append rvalue string",
107 str2.begin(), str2.end(),
108 check.begin(), check.end()
109 );
110
111 std::string str3{"hello, "};
112 std::string apendee{"world"};
113 str3.append(apendee);
114 test_eq(
115 "append lvalue string",
116 str3.begin(), str3.end(),
117 check.begin(), check.end()
118 );
119
120 std::string str4{"hello, "};
121 str4.append(apendee.begin(), apendee.end());
122 test_eq(
123 "append iterator range",
124 str4.begin(), str4.end(),
125 check.begin(), check.end()
126 );
127
128 std::string str5{"hello, "};
129 str5.append({'w', 'o', 'r', 'l', 'd'});
130 test_eq(
131 "append initializer list",
132 str5.begin(), str5.end(),
133 check.begin(), check.end()
134 );
135
136 std::string str6{"hello, "};
137 str6 += "world";
138 test_eq(
139 "append using +=",
140 str6.begin(), str6.end(),
141 check.begin(), check.end()
142 );
143 }
144
145 void string_test::test_insert()
146 {
147 std::string check{"hello, world"};
148
149 std::string str1{", world"};
150 str1.insert(0, "hello");
151 test_eq(
152 "insert at the beggining",
153 str1.begin(), str1.end(),
154 check.begin(), check.end()
155 );
156
157 std::string str2{"hello,world"};
158 str2.insert(str2.begin() + 6, ' ');
159 test_eq(
160 "insert char in the middle",
161 str2.begin(), str2.end(),
162 check.begin(), check.end()
163 );
164
165 std::string str3{"heo, world"};
166 str3.insert(str3.begin() + 2, 2ul, 'l');
167 test_eq(
168 "insert n chars",
169 str3.begin(), str3.end(),
170 check.begin(), check.end()
171 );
172
173 std::string str4{"h, world"};
174 std::string insertee{"ello"};
175 str4.insert(str4.begin() + 1, insertee.begin(),
176 insertee.end());
177 test_eq(
178 "insert iterator range",
179 str4.begin(), str4.end(),
180 check.begin(), check.end()
181 );
182
183 std::string str5{"hel, world"};
184 std::initializer_list<char> init{'l', 'o'};
185 str5.insert(str5.begin() + 3, init);
186 test_eq(
187 "insert initializer list",
188 str5.begin(), str5.end(),
189 check.begin(), check.end()
190 );
191 }
192
193 void string_test::test_erase()
194 {
195 std::string check{"hello"};
196
197 std::string str1{"heXllo"};
198 str1.erase(str1.begin() + 2);
199 test_eq(
200 "erase single char in the middle",
201 str1.begin(), str1.end(),
202 check.begin(), check.end()
203 );
204
205 std::string str2{"Xhello"};
206 str2.erase(str2.begin());
207 test_eq(
208 "erase single char at the beginning",
209 str2.begin(), str2.end(),
210 check.begin(), check.end()
211 );
212
213 std::string str3{"helloX"};
214 str3.erase(str3.begin() + 5);
215 test_eq(
216 "erase single char at the end",
217 str3.begin(), str3.end(),
218 check.begin(), check.end()
219 );
220
221 std::string str4{"XXXhello"};
222 str4.erase(0, 3);
223 test_eq(
224 "erase string at the beginning",
225 str4.begin(), str4.end(),
226 check.begin(), check.end()
227 );
228
229 std::string str5{"heXXXllo"};
230 str5.erase(2, 3);
231 test_eq(
232 "erase string in the middle",
233 str5.begin(), str5.end(),
234 check.begin(), check.end()
235 );
236
237 std::string str6{"helloXXX"};
238 str6.erase(5);
239 test_eq(
240 "erase string at the end",
241 str6.begin(), str6.end(),
242 check.begin(), check.end()
243 );
244
245 std::string str7{"hellXXXo"};
246 str7.erase(str7.begin() + 4, str7.begin() + 7);
247 test_eq(
248 "erase iterator range",
249 str7.begin(), str7.end(),
250 check.begin(), check.end()
251 );
252 }
253
254 void string_test::test_replace()
255 {
256 std::string check{"hello, world"};
257
258 std::string str1{"helXXX world"};
259 str1.replace(3, 3, "lo,", 3);
260 test_eq(
261 "replace with full string",
262 str1.begin(), str1.end(),
263 check.begin(), check.end()
264 );
265
266 std::string str2{"helXXX world"};
267 str2.replace(3, 3, "lo,YYY", 3);
268 test_eq(
269 "replace with prefix of a string",
270 str2.begin(), str2.end(),
271 check.begin(), check.end()
272 );
273
274 std::string str3{"helXXX world"};
275 str3.replace(3, 3, "YYlo,YYY", 2, 3);
276 test_eq(
277 "replace with substring of a string",
278 str3.begin(), str3.end(),
279 check.begin(), check.end()
280 );
281
282 std::string str4{"heXXo, world"};
283 str4.replace(2, 2, 2, 'l');
284 test_eq(
285 "replace with repeated characters",
286 str4.begin(), str4.end(),
287 check.begin(), check.end()
288 );
289
290 std::string str5{"heXXXXo, world"};
291 str5.replace(2, 4, 2, 'l');
292 test_eq(
293 "replace with repeated characters (shrinking)",
294 str5.begin(), str5.end(),
295 check.begin(), check.end()
296 );
297
298 std::string str6{"helXXXXX world"};
299 str6.replace(3, 5, "YYlo,YYY", 2, 3);
300 test_eq(
301 "replace with substring of a string (shrinking)",
302 str6.begin(), str6.end(),
303 check.begin(), check.end()
304 );
305
306 std::string str7{"helXXXXX world"};
307 std::string replacer{"YYlo,YYY"};
308 str7.replace(3, 5, replacer, 2, 3);
309 test_eq(
310 "replace with substring of a string (shrinking, std::string)",
311 str7.begin(), str7.end(),
312 check.begin(), check.end()
313 );
314
315 std::string str8{"helXXXXX world"};
316 str8.replace(str8.begin() + 3, str8.begin() + 8, "lo,");
317 test_eq(
318 "replace with a string (iterators)",
319 str8.begin(), str8.end(),
320 check.begin(), check.end()
321 );
322
323 std::string str9{"heXXXXo, world"};
324 str9.replace(str9.begin() + 2, str9.begin() + 6, 2, 'l');
325 test_eq(
326 "replace with repeated characters (shrinking, iterators)",
327 str9.begin(), str9.end(),
328 check.begin(), check.end()
329 );
330
331 std::string str10{"helXXXXX world"};
332 str10.replace(str10.begin() + 3, str10.begin() + 8,
333 replacer.begin() + 2, replacer.begin() + 5);
334 test_eq(
335 "replace with substring of a string (shrinking, iterators x2)",
336 str10.begin(), str10.end(),
337 check.begin(), check.end()
338 );
339
340 std::string str11{"helXXXXX world"};
341 str11.replace(str11.begin() + 3, str11.begin() + 8,
342 {'l', 'o', ','});
343 test_eq(
344 "replace with an initializer list (shrinking, iterators)",
345 str11.begin(), str11.end(),
346 check.begin(), check.end()
347 );
348
349 std::string str12{"helXXX world"};
350 str12.replace(str12.begin() + 3, str12.begin() + 6,
351 {'l', 'o', ','});
352 test_eq(
353 "replace with an initializer list (iterators)",
354 str12.begin(), str12.end(),
355 check.begin(), check.end()
356 );
357 }
358
359 void string_test::test_copy()
360 {
361 std::string check{"CCABB"};
362
363 std::string str1{"ACCCA"};
364 std::string str2{"BBBBB"};
365
366 str1.copy(const_cast<char*>(str2.c_str()), 3, 2);
367 test_eq(
368 "copy",
369 str2.begin(), str2.end(),
370 check.begin(), check.end()
371 );
372 }
373
374 void string_test::test_find()
375 {
376 std::string target{"ABC"};
377 auto miss = std::string::npos;
378
379 std::string str1{"xxABCxx"};
380
381 auto idx = str1.find(target, 0);
382 test_eq(
383 "find from start (success)",
384 idx, 2ul
385 );
386
387 idx = str1.find(target, 3);
388 test_eq(
389 "find from start (fail, late start)",
390 idx, miss
391 );
392
393 idx = str1.rfind(target, miss);
394 test_eq(
395 "rfind from end (success)",
396 idx, 2ul
397 );
398
399 idx = str1.rfind(target, 1);
400 test_eq(
401 "rfind from start (fail, late start)",
402 idx, miss
403 );
404
405 idx = str1.find('B', 2);
406 test_eq(
407 "find char from middle (success)",
408 idx, 3ul
409 );
410
411 idx = str1.rfind('B', 2);
412 test_eq(
413 "rfind char from middle (success)",
414 idx, 3ul
415 );
416
417 std::string str2{"xxABCxxABCxx"};
418
419 idx = str2.find(target, 0);
420 test_eq(
421 "find from start (success, multiple)",
422 idx, 2ul
423 );
424
425 idx = str2.find(target, 5);
426 test_eq(
427 "find from middle (success, multiple)",
428 idx, 7ul
429 );
430
431 idx = str2.rfind(target, miss);
432 test_eq(
433 "rfind from end (success, multiple)",
434 idx, 7ul
435 );
436
437 idx = str2.rfind(target, 6);
438 test_eq(
439 "rfind from mid (success, multiple)",
440 idx, 2ul
441 );
442
443 std::string str3{"xxBxxAxxCxx"};
444
445 idx = str3.find_first_of(target);
446 test_eq(
447 "find first of from start (success)",
448 idx, 2ul
449 );
450
451 idx = str3.find_first_of(target, 6);
452 test_eq(
453 "find first of from middle (success)",
454 idx, 8ul
455 );
456
457 idx = str3.find_first_of("DEF", 3);
458 test_eq(
459 "find first of from middle (fail, not in string)",
460 idx, miss
461 );
462
463 idx = str3.find_first_of(target, 9);
464 test_eq(
465 "find first of from middle (fail, late start)",
466 idx, miss
467 );
468
469 idx = str3.find_first_of("");
470 test_eq(
471 "find first of from start (fail, no target)",
472 idx, miss
473 );
474
475 idx = str3.find_first_of('A', 1);
476 test_eq(
477 "find first of char (success)",
478 idx, 5ul
479 );
480
481 idx = str3.find_first_of('A', 6);
482 test_eq(
483 "find first of char (fail)",
484 idx, miss
485 );
486
487 idx = str3.find_last_of(target);
488 test_eq(
489 "find last of from start (success)",
490 idx, 8ul
491 );
492
493 idx = str3.find_last_of(target, 6);
494 test_eq(
495 "find last of from middle (success)",
496 idx, 5ul
497 );
498
499 idx = str3.find_last_of("DEF", 3);
500 test_eq(
501 "find last of from middle (fail, not in string)",
502 idx, miss
503 );
504
505 idx = str3.find_last_of(target, 1);
506 test_eq(
507 "find last of from middle (fail, late start)",
508 idx, miss
509 );
510
511 idx = str3.find_last_of("");
512 test_eq(
513 "find last of from start (fail, no target)",
514 idx, miss
515 );
516
517 idx = str3.find_last_of('A', str3.size() - 1);
518 test_eq(
519 "find last of char (success)",
520 idx, 5ul
521 );
522
523 idx = str3.find_last_of('A', 3);
524 test_eq(
525 "find last of char (fail)",
526 idx, miss
527 );
528
529 std::string not_target{"xB"};
530
531 idx = str3.find_first_not_of(not_target);
532 test_eq(
533 "find first not of from start (success)",
534 idx, 5ul
535 );
536
537 idx = str3.find_first_not_of(not_target, 6);
538 test_eq(
539 "find first not of from middle (success)",
540 idx, 8ul
541 );
542
543 idx = str3.find_first_not_of("xABC", 3);
544 test_eq(
545 "find first not of from middle (fail, not in string)",
546 idx, miss
547 );
548
549 idx = str3.find_first_not_of(not_target, 9);
550 test_eq(
551 "find first not of from middle (fail, late start)",
552 idx, miss
553 );
554
555 idx = str3.find_first_not_of("");
556 test_eq(
557 "find first not of from start (success, no target)",
558 idx, 0ul
559 );
560
561 idx = str3.find_first_not_of('x', 3);
562 test_eq(
563 "find first not of char (success)",
564 idx, 5ul
565 );
566
567 idx = str3.find_first_of('a', 9);
568 test_eq(
569 "find first not of char (fail)",
570 idx, miss
571 );
572
573 std::string not_last_target{"xC"};
574
575 idx = str3.find_last_not_of(not_last_target);
576 test_eq(
577 "find last not of from start (success)",
578 idx, 5ul
579 );
580
581 idx = str3.find_last_not_of(not_last_target, 4);
582 test_eq(
583 "find last not of from middle (success)",
584 idx, 2ul
585 );
586
587 idx = str3.find_last_not_of("xABC");
588 test_eq(
589 "find last not of from middle (fail, not in string)",
590 idx, miss
591 );
592
593 idx = str3.find_last_not_of(not_last_target, 1);
594 test_eq(
595 "find last not of from middle (fail, late start)",
596 idx, miss
597 );
598
599 idx = str3.find_last_not_of("");
600 test_eq(
601 "find last not of from start (success, no target)",
602 idx, str3.size() - 1
603 );
604
605 idx = str3.find_last_not_of('x', str3.size() - 1);
606 test_eq(
607 "find last not of char (success)",
608 idx, 8ul
609 );
610
611 idx = str3.find_last_not_of('x', 1);
612 test_eq(
613 "find last not of char (fail)",
614 idx, miss
615 );
616 }
617
618 void string_test::test_substr()
619 {
620 std::string check1{"abcd"};
621 std::string check2{"bcd"};
622 std::string check3{"def"};
623
624 std::string str{"abcdef"};
625 auto substr1 = str.substr(0, 4);
626 auto substr2 = str.substr(1, 3);
627 auto substr3 = str.substr(3);
628
629 test_eq(
630 "prefix substring",
631 substr1.begin(), substr1.end(),
632 check1.begin(), check1.end()
633 );
634
635 test_eq(
636 "substring",
637 substr2.begin(), substr2.end(),
638 check2.begin(), check2.end()
639 );
640
641 test_eq(
642 "suffix substring",
643 substr3.begin(), substr3.end(),
644 check3.begin(), check3.end()
645 );
646 }
647
648 void string_test::test_compare()
649 {
650 std::string str1{"aabbb"};
651 std::string str2{"bbbaa"};
652 std::string str3{"bbb"};
653
654 auto res = str1.compare(str1);
655 test_eq(
656 "compare equal",
657 res, 0
658 );
659
660 res = str1.compare(str2.c_str());
661 test_eq(
662 "compare less",
663 res, -1
664 );
665
666 res = str2.compare(str1);
667 test_eq(
668 "compare greater",
669 res, 1
670 );
671
672 res = str1.compare(2, 3, str2);
673 test_eq(
674 "compare substring less",
675 res, -1
676 );
677
678 res = str1.compare(2, 3, str3);
679 test_eq(
680 "compare substring equal",
681 res, 0
682 );
683 }
684}
Note: See TracBrowser for help on using the repository browser.