1 /*
2 * SysDB - t/utils/strbuf_test.c
3 * Copyright (C) 2013 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 #include "utils/strbuf.h"
29 #include "libsysdb_test.h"
31 #include <check.h>
33 /*
34 * private data types
35 */
37 static sdb_strbuf_t *buf;
39 static void
40 setup(void)
41 {
42 buf = sdb_strbuf_create(0);
43 fail_unless(buf != NULL,
44 "sdb_strbuf_create() = NULL; expected strbuf object");
45 } /* setup */
47 static void
48 teardown(void)
49 {
50 sdb_strbuf_destroy(buf);
51 buf = NULL;
52 } /* teardown */
54 /*
55 * tests
56 */
58 START_TEST(test_sdb_strbuf_create)
59 {
60 sdb_strbuf_t *s;
61 size_t len;
63 s = sdb_strbuf_create(0);
64 fail_unless(s != NULL,
65 "sdb_strbuf_create() = NULL; expected strbuf object");
66 len = sdb_strbuf_len(s);
67 fail_unless(len == 0,
68 "sdb_strbuf_create() created buffer with len = %zu; "
69 "expected: 0", len);
70 sdb_strbuf_destroy(s);
72 s = sdb_strbuf_create(128);
73 fail_unless(s != NULL,
74 "sdb_strbuf_create() = NULL; expected strbuf object");
75 len = sdb_strbuf_len(s);
76 /* len still has to be 0 -- there's no content */
77 fail_unless(len == 0,
78 "sdb_strbuf_create() created buffer with len = %zu; "
79 "expected: 0", len);
80 sdb_strbuf_destroy(s);
81 }
82 END_TEST
84 START_TEST(test_sdb_strbuf_append)
85 {
86 ssize_t n, expected;
87 size_t len;
88 const char *test;
90 n = sdb_strbuf_append(buf, "1234567890");
91 fail_unless(n == 10,
92 "sdb_strbuf_append() appended %zi bytes; expected: 10", n);
93 len = sdb_strbuf_len(buf);
94 fail_unless(len == 10,
95 "sdb_strbuf_append() left behind buffer with len = %zu; "
96 "expected: 10", len);
98 n = sdb_strbuf_append(buf, "ABCDE");
99 fail_unless(n == 5,
100 "sdb_strbuf_append() appended %zi bytes; expected: 5", n);
101 len = sdb_strbuf_len(buf);
102 fail_unless(len == 15,
103 "sdb_strbuf_append() left behind buffer with len = %zu; "
104 "expected: 15", len);
106 test = sdb_strbuf_string(buf);
107 fail_unless(test[len] == '\0',
108 "sdb_strbuf_append() did not nil-terminate the string");
109 fail_unless(!strcmp(test, "1234567890ABCDE"),
110 "sdb_strbuf_append() did not correctly concatenate two string; "
111 "got: %s; expected: 1234567890ABCDE", test);
113 n = sdb_strbuf_append(buf, "%zu; %5.4f", len, (double)len / 10.0);
114 expected = /* len */ 2 + /* "; " */ 2 + /* decimal len/10 */ 6;
115 fail_unless(n == expected,
116 "sdb_strbuf_append() appended %zi bytes; expected: %zi",
117 n, expected);
118 len = sdb_strbuf_len(buf);
119 fail_unless(len == 15 + (size_t)expected,
120 "sdb_strbuf_append() left behind buffer with len = %zu; "
121 "expected: %zu", len, 15 + (size_t)expected);
123 test = sdb_strbuf_string(buf);
124 fail_unless(test[len] == '\0',
125 "sdb_strbuf_append() did not nil-terminate the string");
126 fail_unless(!strcmp(test, "1234567890ABCDE15; 1.5000"),
127 "sdb_strbuf_append() did not correctly concatenate two string; "
128 "got: %s; expected: 1234567890ABCDE15; 1.5000", test);
129 }
130 END_TEST
132 START_TEST(test_sdb_strbuf_sprintf)
133 {
134 ssize_t n, expected;
135 size_t len;
136 const char *test;
138 n = sdb_strbuf_sprintf(buf, "1234567890");
139 fail_unless(n == 10,
140 "sdb_strbuf_sprintf() wrote %zi bytes; expected: 10", n);
141 len = sdb_strbuf_len(buf);
142 fail_unless(len == 10,
143 "sdb_strbuf_sprintf() left behind buffer with len = %zu; "
144 "expected: 10", len);
146 n = sdb_strbuf_sprintf(buf, "ABCDE");
147 fail_unless(n == 5,
148 "sdb_strbuf_sprintf() wrote %zi bytes; expected: 5", n);
149 len = sdb_strbuf_len(buf);
150 fail_unless(len == 5,
151 "sdb_strbuf_sprintf() left behind buffer with len = %zu; "
152 "expected: 5", len);
154 test = sdb_strbuf_string(buf);
155 fail_unless(test[len] == '\0',
156 "sdb_strbuf_sprintf() did not nil-terminate the string");
157 fail_unless(!strcmp(test, "ABCDE"),
158 "sdb_strbuf_sprintf() did not format string correctly; "
159 "got: %s; expected: ABCDE", test);
161 n = sdb_strbuf_sprintf(buf, "%zu; %5.4f", len, (double)len / 10.0);
162 expected = /* len */ 1 + /* "; " */ 2 + /* decimal len/10 */ 6;
163 fail_unless(n == expected,
164 "sdb_strbuf_sprintf() wrote %zi bytes; expected: %zi",
165 n, expected);
166 len = sdb_strbuf_len(buf);
167 fail_unless(len == (size_t)expected,
168 "sdb_strbuf_sprintf() left behind buffer with len = %zu; "
169 "expected: %zu", len, (size_t)expected);
171 test = sdb_strbuf_string(buf);
172 fail_unless(test[len] == '\0',
173 "sdb_strbuf_sprintf() did not nil-terminate the string");
174 fail_unless(!strcmp(test, "5; 0.5000"),
175 "sdb_strbuf_sprintf() did not format string correctly; "
176 "got: %s; expected: 5; 0.5000", test);
177 }
178 END_TEST
180 static struct {
181 const char *input;
182 size_t size;
183 } mem_golden_data[] = {
184 { "abc\0\x10\x42", 6 },
185 { "\0\1\2\3\4", 5 },
186 { "\n\n\0\n\n", 5 },
187 { "", 0 },
188 };
190 START_TEST(test_sdb_strbuf_memcpy)
191 {
192 size_t i;
194 for (i = 0; i < SDB_STATIC_ARRAY_LEN(mem_golden_data); ++i) {
195 ssize_t n;
196 const char *check;
198 n = sdb_strbuf_memcpy(buf, mem_golden_data[i].input,
199 mem_golden_data[i].size);
200 fail_unless(n >= 0,
201 "sdb_strbuf_memcpy() = %zi; expected: >=0", n);
202 fail_unless((size_t)n == mem_golden_data[i].size,
203 "sdb_strbuf_memcpy() = %zi; expected: %zu",
204 n, mem_golden_data[i].size);
206 n = (ssize_t)sdb_strbuf_len(buf);
207 fail_unless((size_t)n == mem_golden_data[i].size,
208 "sdb_strbuf_len() = %zu (after memcpy); expected: %zu",
209 n, mem_golden_data[i].size);
211 check = sdb_strbuf_string(buf);
212 fail_unless(check != NULL,
213 "sdb_strbuf_string() = NULL (after memcpy); expected: data");
214 fail_unless(check[mem_golden_data[i].size] == '\0',
215 "sdb_strbuf_memcpy() did not nil-terminate the data");
216 fail_unless(!memcmp(check, mem_golden_data[i].input,
217 mem_golden_data[i].size),
218 "sdb_strbuf_memcpy() did not set the buffer correctly");
219 }
220 }
221 END_TEST
223 START_TEST(test_sdb_strbuf_memappend)
224 {
225 size_t i;
227 for (i = 0; i < SDB_STATIC_ARRAY_LEN(mem_golden_data); ++i) {
228 ssize_t n;
229 const char *check;
231 size_t total, j;
233 n = sdb_strbuf_memappend(buf, mem_golden_data[i].input,
234 mem_golden_data[i].size);
235 fail_unless(n >= 0,
236 "sdb_strbuf_memappend() = %zi; expected: >=0", n);
237 fail_unless((size_t)n == mem_golden_data[i].size,
238 "sdb_strbuf_memappend() = %zi; expected: %zu",
239 n, mem_golden_data[i].size);
241 check = sdb_strbuf_string(buf);
242 fail_unless(check != NULL,
243 "sdb_strbuf_string() = NULL (after memappend); "
244 "expected: data");
246 n = (ssize_t)sdb_strbuf_len(buf);
247 total = 0;
248 for (j = 0; j <= i; ++j) {
249 fail_unless(total + mem_golden_data[j].size <= (size_t)n,
250 "sdb_strbuf_len() = %zu (after memappend); "
251 "expected: >=%zu", n, total + mem_golden_data[j].size);
253 fail_unless(!memcmp(check + total, mem_golden_data[j].input,
254 mem_golden_data[j].size),
255 "sdb_strbuf_memappend() did not "
256 "set the buffer correctly");
257 total += mem_golden_data[j].size;
258 }
259 fail_unless((size_t)n == total,
260 "sdb_strbuf_len() = %zu (after memappend); expected: %zu",
261 n, total);
263 fail_unless(check[total] == '\0',
264 "sdb_strbuf_memappend() did not nil-terminate the data");
265 }
266 }
267 END_TEST
269 static struct {
270 const char *input;
271 ssize_t expected;
272 const char *expected_string;
273 } chomp_golden_data[] = {
274 { NULL, 0, "" },
275 { "\n", 1, "" },
276 { "\n\n", 2, "" },
277 { "12345\n\n\n", 3, "12345" },
278 { "abcd", 0, "abcd" },
279 };
281 START_TEST(test_sdb_strbuf_chomp)
282 {
283 size_t i;
285 for (i = 0; i < SDB_STATIC_ARRAY_LEN(chomp_golden_data); ++i) {
286 ssize_t n;
287 const char *check;
289 if (chomp_golden_data[i].input)
290 sdb_strbuf_sprintf(buf, chomp_golden_data[i].input);
292 /* empty buffer */
293 n = sdb_strbuf_chomp(buf);
294 fail_unless(n == chomp_golden_data[i].expected,
295 "sdb_strbuf_chomp() = %zi; expected: %zi", n,
296 chomp_golden_data[i].expected);
298 check = sdb_strbuf_string(buf);
299 fail_unless(!strcmp(check, chomp_golden_data[i].expected_string),
300 "sdb_strbuf_chomp() did not correctly remove newlines; "
301 "got string '%s'; expected: '%s'", check,
302 chomp_golden_data[i].expected_string);
303 }
304 }
305 END_TEST
307 /* input is "1234567890" */
308 static struct {
309 size_t n;
310 const char *expected;
311 size_t expected_len;
312 } skip_golden_data[] = {
313 { 0, "1234567890", 10 },
314 { 1, "234567890", 9 },
315 { 2, "34567890", 8 },
316 { 9, "0", 1 },
317 { 10, "", 0 },
318 { 11, "", 0 },
319 { 100, "", 0 },
320 };
322 START_TEST(test_sdb_strbuf_skip)
323 {
324 const char *input = "1234567890";
325 size_t i;
327 for (i = 0; i < SDB_STATIC_ARRAY_LEN(skip_golden_data); ++i) {
328 const char *check;
329 size_t n;
331 sdb_strbuf_sprintf(buf, input);
332 sdb_strbuf_skip(buf, skip_golden_data[i].n);
334 n = sdb_strbuf_len(buf);
335 fail_unless(n == skip_golden_data[i].expected_len,
336 "sdb_strbuf_len() = %zu (after skip); expected: %zu",
337 n, skip_golden_data[i].expected_len);
339 check = sdb_strbuf_string(buf);
340 fail_unless(!!check,
341 "sdb_strbuf_string() = NULL (after skip); expected: string");
343 fail_unless(check[n] == '\0',
344 "sdb_strbuf_skip() did not nil-terminate the string");
346 fail_unless(! strcmp(skip_golden_data[i].expected, check),
347 "sdb_strbuf_skip('%s', %zu) did not skip correctly; "
348 "got string '%s'; expected: '%s'", input,
349 skip_golden_data[i].n, check, skip_golden_data[i].expected);
350 }
351 }
352 END_TEST
354 static struct {
355 const char *input;
356 const char *expected;
357 } string_golden_data[] = {
358 { NULL, "" },
359 { "a", "a" },
360 { "abcdef", "abcdef" },
361 };
363 START_TEST(test_sdb_strbuf_string)
364 {
365 size_t i;
367 for (i = 0; i < SDB_STATIC_ARRAY_LEN(string_golden_data); ++i) {
368 const char *check;
370 if (string_golden_data[i].input)
371 sdb_strbuf_sprintf(buf, string_golden_data[i].input);
372 check = sdb_strbuf_string(buf);
373 fail_unless(!strcmp(check, string_golden_data[i].expected),
374 "sdb_strbuf_string() = '%s'; expected: '%s'",
375 check, string_golden_data[i].expected);
376 }
377 }
378 END_TEST
380 static struct {
381 const char *input;
382 size_t expected;
383 } len_golden_data[] = {
384 { NULL, 0 },
385 { "a", 1 },
386 { "12345", 5 },
387 };
389 START_TEST(test_sdb_strbuf_len)
390 {
391 size_t i;
393 for (i = 0; i < SDB_STATIC_ARRAY_LEN(len_golden_data); ++i) {
394 size_t check;
396 if (len_golden_data[i].input)
397 sdb_strbuf_sprintf(buf, len_golden_data[i].input);
398 check = sdb_strbuf_len(buf);
399 fail_unless(check == len_golden_data[i].expected,
400 "sdb_strbuf_len() = %zu; expected: %zu",
401 check, len_golden_data[i].expected);
402 }
403 }
404 END_TEST
406 Suite *
407 util_strbuf_suite(void)
408 {
409 Suite *s = suite_create("utils::strbuf");
410 TCase *tc;
412 tc = tcase_create("core");
413 tcase_add_checked_fixture(tc, setup, teardown);
414 tcase_add_test(tc, test_sdb_strbuf_create);
415 tcase_add_test(tc, test_sdb_strbuf_append);
416 tcase_add_test(tc, test_sdb_strbuf_sprintf);
417 tcase_add_test(tc, test_sdb_strbuf_memcpy);
418 tcase_add_test(tc, test_sdb_strbuf_memappend);
419 tcase_add_test(tc, test_sdb_strbuf_chomp);
420 tcase_add_test(tc, test_sdb_strbuf_skip);
421 tcase_add_test(tc, test_sdb_strbuf_string);
422 tcase_add_test(tc, test_sdb_strbuf_len);
423 suite_add_tcase(s, tc);
425 return s;
426 } /* util_strbuf_suite */
428 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */