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

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

cpp: finished tests for string find functions

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