1 /*
2 * SysDB - t/unit/utils/strings_test.c
3 * Copyright (C) 2016 Sebastian 'tokkee' Harl <sh@tokkee.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. 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 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
28 #if HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include "core/data.h"
33 #include "utils/strings.h"
34 #include "testutils.h"
36 #include <check.h>
38 /*
39 * tests
40 */
42 START_TEST(test_stringv)
43 {
44 char **dst = NULL;
45 size_t dst_len = 0;
47 char *src[] = { "a", "b", "c", "d", "e" };
48 size_t src_len = SDB_STATIC_ARRAY_LEN(src);
49 size_t i;
51 int check;
53 /* Test no-op, empty operations. */
54 check = stringv_copy(&dst, &dst_len, NULL, 0);
55 fail_unless(check == 0,
56 "stringv_copy(&<null>, &<0>, <null>, 0) = %d; expected: 0",
57 check);
58 fail_unless((dst == NULL) && (dst_len == 0),
59 "stringv_copy(&<null>, &<0>, <null>, 0) produced %p, %d; "
60 "expected <null>, 0", dst, dst_len);
61 stringv_free(&dst, &dst_len);
62 fail_unless((dst == NULL) && (dst_len == 0),
63 "stringv_free(&<null>, &<0>) produced %p, %d; expected <null>, 0",
64 dst, dst_len);
66 /* Now, append some content. */
67 for (i = 0; i < src_len; i++) {
68 sdb_data_t d1 = {
69 SDB_TYPE_STRING | SDB_TYPE_ARRAY,
70 { .array = { 0, NULL } },
71 };
72 sdb_data_t d2 = d1;
74 char buf1[256], buf2[256];
75 size_t j;
77 if (i < 3) {
78 check = stringv_append(&dst, &dst_len, src[i]);
79 fail_unless(check == 0,
80 "stringv_append(<s>, <len>, '%s') = %d; expected: 0",
81 src[i], check);
82 fail_unless((dst != NULL) && (dst_len == i + 1),
83 "stringv_append(<s>, <len>, '%s') produced s=%p, len=%zu; "
84 "expected: s=<v>, len=%zu", src[i], dst, dst_len, i + 1);
85 }
87 /* A no-op for the first three iterations but then it appends the
88 * other elements. */
89 check = stringv_append_if_missing(&dst, &dst_len, src[i]);
90 fail_unless(check == 0,
91 "stringv_append_if_missing(<s>, <len>, '%s') = %d; expected: 0",
92 src[i], check);
93 fail_unless((dst != NULL) && (dst_len == i + 1),
94 "stringv_append_if_missing(<s>, <len>, '%s') produced s=%p, len=%zu; "
95 "expected: s=<v>, len=%zu", src[i], dst, dst_len, i + 1);
97 for (j = 0; j <= i; j++)
98 if ((! dst[j]) || (strcmp(dst[j], src[j]) != 0))
99 break;
101 if (j <= i) {
102 d1.data.array.values = dst;
103 d1.data.array.length = dst_len;
104 sdb_data_format(&d1, buf1, sizeof(buf1), 0);
106 d2.data.array.values = src;
107 d2.data.array.length = dst_len;
108 sdb_data_format(&d2, buf2, sizeof(buf2), 0);
110 fail("stringv_append(<s>, <len>, '%s') produced unexpected result: "
111 "vectors differ at position %zu: '%s' <-> '%s'",
112 src[i], j, buf1, buf2);
113 }
114 }
115 stringv_free(&dst, &dst_len);
117 /* Copy all in one go. */
118 for (i = 0; i < src_len; i++) {
119 sdb_data_t d1 = {
120 SDB_TYPE_STRING | SDB_TYPE_ARRAY,
121 { .array = { 0, NULL } },
122 };
123 sdb_data_t d2 = d1;
125 char buf1[256], buf2[256];
126 size_t j;
128 /* stringv_copy is expected to free memory as needed, so simply copy
129 * over the old values from the previous iteration. */
130 check = stringv_copy(&dst, &dst_len, (const char * const *)src, i + 1);
131 fail_unless(check == 0,
132 "stringv_copy(<s>, <len>, <src>, %zu) = %d; expected: 0",
133 i, check);
134 fail_unless((dst != NULL) && (dst_len == i + 1),
135 "stringv_copy(<s>, <len>, <src>, %zu) produced s=%p, len=%zu; "
136 "expected: s=<v>, len=%zu", i, dst, dst_len, i + 1);
138 for (j = 0; j <= i; j++)
139 if ((! dst[j]) || (strcmp(dst[j], src[j]) != 0))
140 break;
142 if (j <= i) {
143 d1.data.array.values = dst;
144 d1.data.array.length = dst_len;
145 sdb_data_format(&d1, buf1, sizeof(buf1), 0);
147 d2.data.array.values = src;
148 d2.data.array.length = dst_len;
149 sdb_data_format(&d2, buf2, sizeof(buf2), 0);
151 fail("stringv_copy(<s>, <len>, <src>, %zu) produced unexpected result: "
152 "vectors differ at position %zu: '%s' <-> '%s'",
153 i, j, buf1, buf2);
154 }
155 }
156 stringv_free(&dst, &dst_len);
157 }
158 END_TEST
160 TEST_MAIN("utils::strings")
161 {
162 TCase *tc = tcase_create("core");
163 tcase_add_test(tc, test_stringv);
164 ADD_TCASE(tc);
165 }
166 TEST_MAIN_END
168 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */