source: mainline/uspace/lib/cpp/src/internal/test/string.cpp@ 035a35c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 035a35c was 035a35c, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added tests for std::string::compare

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