1 /* $NetBSD: dynstr_test.c,v 1.3 2014/12/10 04:38:03 christos Exp $ */
4 * Automated Testing Framework (atf)
6 * Copyright (c) 2008 The NetBSD Foundation, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #include "test_helpers.h"
43 /* ---------------------------------------------------------------------
44 * Tests for the "atf_dynstr" type.
45 * --------------------------------------------------------------------- */
48 * Constructors and destructors.
54 atf_tc_set_md_var(tc
, "descr", "Checks the empty constructor");
60 RE(atf_dynstr_init(&str
));
61 ATF_REQUIRE_EQ(atf_dynstr_length(&str
), 0);
62 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "") == 0);
63 atf_dynstr_fini(&str
);
68 init_fmt(atf_dynstr_t
*str
, const char *fmt
, ...)
73 RE(atf_dynstr_init_ap(str
, fmt
, ap
));
78 ATF_TC_HEAD(init_ap
, tc
)
80 atf_tc_set_md_var(tc
, "descr", "Checks the formatted constructor using "
81 "a va_list argument");
83 ATF_TC_BODY(init_ap
, tc
)
87 init_fmt(&str
, "String 1");
88 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 1") == 0);
89 atf_dynstr_fini(&str
);
91 init_fmt(&str
, "String %d", 2);
92 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 2") == 0);
93 atf_dynstr_fini(&str
);
95 init_fmt(&str
, "%s %d", "String", 3);
96 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 3") == 0);
97 atf_dynstr_fini(&str
);
99 init_fmt(&str
, "%s%s%s%s%s%s%s", "This ", "should ", "be ", "a ",
100 "large ", "string ", "aaaabbbbccccdddd");
101 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
),
102 "This should be a large string "
103 "aaaabbbbccccdddd") == 0);
104 atf_dynstr_fini(&str
);
108 ATF_TC_HEAD(init_fmt
, tc
)
110 atf_tc_set_md_var(tc
, "descr", "Checks the formatted constructor using "
111 "a variable list of parameters");
113 ATF_TC_BODY(init_fmt
, tc
)
117 RE(atf_dynstr_init_fmt(&str
, "String 1"));
118 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 1") == 0);
119 atf_dynstr_fini(&str
);
121 RE(atf_dynstr_init_fmt(&str
, "String %d", 2));
122 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 2") == 0);
123 atf_dynstr_fini(&str
);
125 RE(atf_dynstr_init_fmt(&str
, "%s %d", "String", 3));
126 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 3") == 0);
127 atf_dynstr_fini(&str
);
129 RE(atf_dynstr_init_fmt(&str
, "%s%s%s%s%s%s%s", "This ", "should ",
130 "be ", "a ", "large ", "string ",
131 "aaaabbbbccccdddd"));
132 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
),
133 "This should be a large string "
134 "aaaabbbbccccdddd") == 0);
135 atf_dynstr_fini(&str
);
139 ATF_TC_HEAD(init_raw
, tc
)
141 atf_tc_set_md_var(tc
, "descr", "Checks the construction of a string "
142 "using a raw memory pointer");
144 ATF_TC_BODY(init_raw
, tc
)
146 const char *src
= "String 1, String 2";
149 RE(atf_dynstr_init_raw(&str
, src
, 0));
150 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "") == 0);
151 atf_dynstr_fini(&str
);
153 RE(atf_dynstr_init_raw(&str
, src
, 8));
154 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 1") == 0);
155 atf_dynstr_fini(&str
);
157 RE(atf_dynstr_init_raw(&str
, src
+ 10, 8));
158 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String 2") == 0);
159 atf_dynstr_fini(&str
);
161 RE(atf_dynstr_init_raw(&str
, "String\0Lost", 11));
162 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "String") == 0);
163 atf_dynstr_fini(&str
);
166 atf_error_t err
= atf_dynstr_init_raw(&str
, "NULL", SIZE_MAX
- 1);
167 ATF_REQUIRE(atf_is_error(err
));
168 ATF_REQUIRE(atf_error_is(err
, "no_memory"));
174 ATF_TC_HEAD(init_rep
, tc
)
176 atf_tc_set_md_var(tc
, "descr", "Checks the construction of a string by "
177 "repeating characters");
179 ATF_TC_BODY(init_rep
, tc
)
181 const size_t maxlen
= 8192;
182 char buf
[maxlen
+ 1];
187 for (i
= 0; i
< maxlen
; i
++) {
190 RE(atf_dynstr_init_rep(&str
, i
, 'a'));
192 if (strcmp(atf_dynstr_cstring(&str
), buf
) != 0) {
193 fprintf(stderr
, "Failed at iteration %zd\n", i
);
194 atf_tc_fail("Failed to construct dynstr by repeating %zd "
195 "times the '%c' character", i
, 'a');
198 atf_dynstr_fini(&str
);
207 err
= atf_dynstr_init_rep(&str
, SIZE_MAX
, 'a');
208 ATF_REQUIRE(atf_is_error(err
));
209 ATF_REQUIRE(atf_error_is(err
, "no_memory"));
212 err
= atf_dynstr_init_rep(&str
, SIZE_MAX
- 1, 'a');
213 ATF_REQUIRE(atf_is_error(err
));
214 ATF_REQUIRE(atf_error_is(err
, "no_memory"));
220 ATF_TC_HEAD(init_substr
, tc
)
222 atf_tc_set_md_var(tc
, "descr", "Checks the construction of a string "
223 "using a substring of another one");
225 ATF_TC_BODY(init_substr
, tc
)
230 RE(atf_dynstr_init_fmt(&src
, "Str 1, Str 2"));
232 RE(atf_dynstr_init_substr(&str
, &src
, 0, 0));
233 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "") == 0);
234 atf_dynstr_fini(&str
);
236 RE(atf_dynstr_init_substr(&str
, &src
, 0, atf_dynstr_npos
));
237 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "Str 1, Str 2") == 0);
238 atf_dynstr_fini(&str
);
240 RE(atf_dynstr_init_substr(&str
, &src
, 0, 100));
241 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "Str 1, Str 2") == 0);
242 atf_dynstr_fini(&str
);
244 RE(atf_dynstr_init_substr(&str
, &src
, 0, 5));
245 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "Str 1") == 0);
246 atf_dynstr_fini(&str
);
248 RE(atf_dynstr_init_substr(&str
, &src
, 100, atf_dynstr_npos
));
249 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "") == 0);
250 atf_dynstr_fini(&str
);
252 RE(atf_dynstr_init_substr(&str
, &src
, 7, atf_dynstr_npos
));
253 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "Str 2") == 0);
254 atf_dynstr_fini(&str
);
256 atf_dynstr_fini(&src
);
260 ATF_TC_HEAD(copy
, tc
)
262 atf_tc_set_md_var(tc
, "descr", "Checks the atf_dynstr_copy constructor");
264 ATF_TC_BODY(copy
, tc
)
266 atf_dynstr_t str
, str2
;
268 RE(atf_dynstr_init_fmt(&str
, "Test string"));
269 RE(atf_dynstr_copy(&str2
, &str
));
271 ATF_REQUIRE(atf_equal_dynstr_dynstr(&str
, &str2
));
273 RE(atf_dynstr_append_fmt(&str2
, " non-shared text"));
275 ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str
, &str2
));
277 atf_dynstr_fini(&str2
);
278 atf_dynstr_fini(&str
);
282 ATF_TC_HEAD(fini_disown
, tc
)
284 atf_tc_set_md_var(tc
, "descr", "Checks grabbing ownership of the "
285 "internal plain C string");
287 ATF_TC_BODY(fini_disown
, tc
)
293 RE(atf_dynstr_init_fmt(&str
, "Test string 1"));
294 cstr
= atf_dynstr_cstring(&str
);
295 cstr2
= atf_dynstr_fini_disown(&str
);
297 ATF_REQUIRE_EQ(cstr
, cstr2
);
306 ATF_TC_HEAD(cstring
, tc
)
308 atf_tc_set_md_var(tc
, "descr", "Checks the method to obtain a plain C "
311 ATF_TC_BODY(cstring
, tc
)
316 RE(atf_dynstr_init_fmt(&str
, "Test string 1"));
317 cstr
= atf_dynstr_cstring(&str
);
318 ATF_REQUIRE(cstr
!= NULL
);
319 ATF_REQUIRE(strcmp(cstr
, "Test string 1") == 0);
320 atf_dynstr_fini(&str
);
322 RE(atf_dynstr_init_fmt(&str
, "Test string 2"));
323 cstr
= atf_dynstr_cstring(&str
);
324 ATF_REQUIRE(cstr
!= NULL
);
325 ATF_REQUIRE(strcmp(cstr
, "Test string 2") == 0);
326 atf_dynstr_fini(&str
);
330 ATF_TC_HEAD(length
, tc
)
332 atf_tc_set_md_var(tc
, "descr", "Checks the method to obtain the length");
334 ATF_TC_BODY(length
, tc
)
338 for (i
= 0; i
< 8192; i
++) {
340 RE(atf_dynstr_init_rep(&str
, i
, 'a'));
341 ATF_REQUIRE_EQ(atf_dynstr_length(&str
), i
);
342 atf_dynstr_fini(&str
);
347 ATF_TC_HEAD(rfind_ch
, tc
)
349 atf_tc_set_md_var(tc
, "descr", "Checks the method to locate the first "
350 "occurrence of a character starting from the end");
352 ATF_TC_BODY(rfind_ch
, tc
)
356 RE(atf_dynstr_init_fmt(&str
, "Foo1/Bar2/,.Baz"));
358 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str
, '\0'), atf_dynstr_npos
);
360 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str
, '0'), atf_dynstr_npos
);
361 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str
, 'b'), atf_dynstr_npos
);
363 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str
, 'F'), 0);
364 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str
, '/'), 9);
365 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str
, 'a'), 13);
366 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str
, 'z'), 14);
368 atf_dynstr_fini(&str
);
377 check_append(atf_error_t (*append
)(atf_dynstr_t
*, const char *, ...))
379 const size_t maxlen
= 8192;
380 char buf
[maxlen
+ 1];
384 printf("Appending with plain string\n");
386 RE(atf_dynstr_init(&str
));
387 for (i
= 0; i
< maxlen
; i
++) {
388 if (strcmp(atf_dynstr_cstring(&str
), buf
) != 0) {
389 fprintf(stderr
, "Failed at iteration %zd\n", i
);
390 atf_tc_fail("Failed to append character at iteration %zd", i
);
393 RE(append(&str
, "a"));
396 atf_dynstr_fini(&str
);
398 printf("Appending with formatted string\n");
400 RE(atf_dynstr_init(&str
));
401 for (i
= 0; i
< maxlen
; i
++) {
402 if (strcmp(atf_dynstr_cstring(&str
), buf
) != 0) {
403 fprintf(stderr
, "Failed at iteration %zd\n", i
);
404 atf_tc_fail("Failed to append character at iteration %zd", i
);
407 RE(append(&str
, "%s", "a"));
410 atf_dynstr_fini(&str
);
415 append_ap_aux(atf_dynstr_t
*str
, const char *fmt
, ...)
421 err
= atf_dynstr_append_ap(str
, fmt
, ap
);
428 ATF_TC_HEAD(append_ap
, tc
)
430 atf_tc_set_md_var(tc
, "descr", "Checks that appending a string to "
431 "another one works");
433 ATF_TC_BODY(append_ap
, tc
)
435 check_append(append_ap_aux
);
439 ATF_TC_HEAD(append_fmt
, tc
)
441 atf_tc_set_md_var(tc
, "descr", "Checks that appending a string to "
442 "another one works");
444 ATF_TC_BODY(append_fmt
, tc
)
446 check_append(atf_dynstr_append_fmt
);
450 ATF_TC_HEAD(clear
, tc
)
452 atf_tc_set_md_var(tc
, "descr", "Checks clearing a string");
454 ATF_TC_BODY(clear
, tc
)
458 printf("Clear an empty string\n");
459 RE(atf_dynstr_init(&str
));
460 atf_dynstr_clear(&str
);
461 ATF_REQUIRE_EQ(atf_dynstr_length(&str
), 0);
462 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "") == 0);
463 atf_dynstr_fini(&str
);
465 printf("Clear a non-empty string\n");
466 RE(atf_dynstr_init_fmt(&str
, "Not empty"));
467 ATF_REQUIRE_EQ(atf_dynstr_length(&str
), strlen("Not empty"));
468 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "Not empty") == 0);
469 atf_dynstr_clear(&str
);
470 ATF_REQUIRE_EQ(atf_dynstr_length(&str
), 0);
471 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str
), "") == 0);
472 atf_dynstr_fini(&str
);
477 check_prepend(atf_error_t (*prepend
)(atf_dynstr_t
*, const char *, ...))
479 const size_t maxlen
= 8192;
480 char buf
[maxlen
+ 1];
484 printf("Prepending with plain string\n");
486 RE(atf_dynstr_init(&str
));
487 for (i
= 0; i
< maxlen
; i
++) {
488 if (strcmp(atf_dynstr_cstring(&str
), buf
) != 0) {
489 fprintf(stderr
, "Failed at iteration %zd\n", i
);
490 atf_tc_fail("Failed to prepend character at iteration %zd", i
);
493 memmove(buf
+ 1, buf
, i
+ 1);
495 RE(prepend(&str
, "%s", "a"));
498 RE(prepend(&str
, "%s", "b"));
502 atf_dynstr_fini(&str
);
504 printf("Prepending with formatted string\n");
506 RE(atf_dynstr_init(&str
));
507 for (i
= 0; i
< maxlen
; i
++) {
508 if (strcmp(atf_dynstr_cstring(&str
), buf
) != 0) {
509 fprintf(stderr
, "Failed at iteration %zd\n", i
);
510 atf_tc_fail("Failed to prepend character at iteration %zd", i
);
513 memmove(buf
+ 1, buf
, i
+ 1);
515 RE(prepend(&str
, "%s", "a"));
518 RE(prepend(&str
, "%s", "b"));
522 atf_dynstr_fini(&str
);
527 prepend_ap_aux(atf_dynstr_t
*str
, const char *fmt
, ...)
533 err
= atf_dynstr_prepend_ap(str
, fmt
, ap
);
540 ATF_TC_HEAD(prepend_ap
, tc
)
542 atf_tc_set_md_var(tc
, "descr", "Checks that prepending a string to "
543 "another one works");
545 ATF_TC_BODY(prepend_ap
, tc
)
547 check_prepend(prepend_ap_aux
);
551 ATF_TC_HEAD(prepend_fmt
, tc
)
553 atf_tc_set_md_var(tc
, "descr", "Checks that prepending a string to "
554 "another one works");
556 ATF_TC_BODY(prepend_fmt
, tc
)
558 check_prepend(atf_dynstr_prepend_fmt
);
565 ATF_TC(equal_cstring
);
566 ATF_TC_HEAD(equal_cstring
, tc
)
568 atf_tc_set_md_var(tc
, "descr", "Checks the atf_equal_dynstr_cstring "
571 ATF_TC_BODY(equal_cstring
, tc
)
575 RE(atf_dynstr_init(&str
));
576 ATF_REQUIRE( atf_equal_dynstr_cstring(&str
, ""));
577 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str
, "Test"));
578 atf_dynstr_fini(&str
);
580 RE(atf_dynstr_init_fmt(&str
, "Test"));
581 ATF_REQUIRE( atf_equal_dynstr_cstring(&str
, "Test"));
582 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str
, ""));
583 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str
, "Tes"));
584 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str
, "Test "));
585 atf_dynstr_fini(&str
);
588 ATF_TC(equal_dynstr
);
589 ATF_TC_HEAD(equal_dynstr
, tc
)
591 atf_tc_set_md_var(tc
, "descr", "Checks the atf_equal_dynstr_dynstr "
594 ATF_TC_BODY(equal_dynstr
, tc
)
596 atf_dynstr_t str
, str2
;
598 RE(atf_dynstr_init(&str
));
599 RE(atf_dynstr_init_fmt(&str2
, "Test"));
600 ATF_REQUIRE( atf_equal_dynstr_dynstr(&str
, &str
));
601 ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str
, &str2
));
602 atf_dynstr_fini(&str2
);
603 atf_dynstr_fini(&str
);
606 /* ---------------------------------------------------------------------
608 * --------------------------------------------------------------------- */
612 /* Constructors and destructors. */
613 ATF_TP_ADD_TC(tp
, init
);
614 ATF_TP_ADD_TC(tp
, init_ap
);
615 ATF_TP_ADD_TC(tp
, init_fmt
);
616 ATF_TP_ADD_TC(tp
, init_raw
);
617 ATF_TP_ADD_TC(tp
, init_rep
);
618 ATF_TP_ADD_TC(tp
, init_substr
);
619 ATF_TP_ADD_TC(tp
, copy
);
620 ATF_TP_ADD_TC(tp
, fini_disown
);
623 ATF_TP_ADD_TC(tp
, cstring
);
624 ATF_TP_ADD_TC(tp
, length
);
625 ATF_TP_ADD_TC(tp
, rfind_ch
);
628 ATF_TP_ADD_TC(tp
, append_ap
);
629 ATF_TP_ADD_TC(tp
, append_fmt
);
630 ATF_TP_ADD_TC(tp
, clear
);
631 ATF_TP_ADD_TC(tp
, prepend_ap
);
632 ATF_TP_ADD_TC(tp
, prepend_fmt
);
635 ATF_TP_ADD_TC(tp
, equal_cstring
);
636 ATF_TP_ADD_TC(tp
, equal_dynstr
);
638 return atf_no_error();