X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=blobdiff_plain;f=t%2Futils%2Fstrbuf_test.c;h=bb03296d79da887181e4ac9d992fa989320f9dc3;hp=851cb983221d75768127f4f896209ba60ff36b91;hb=3ba81224dac4d31ea5ad651db569543825ea5078;hpb=3509e19b205784e1b56374683127d3fd845afb15 diff --git a/t/utils/strbuf_test.c b/t/utils/strbuf_test.c index 851cb98..bb03296 100644 --- a/t/utils/strbuf_test.c +++ b/t/utils/strbuf_test.c @@ -55,6 +55,60 @@ teardown(void) * tests */ +START_TEST(test_null) +{ + sdb_strbuf_t *b = NULL; + va_list ap; + + /* check that methods don't crash */ + sdb_strbuf_destroy(b); + sdb_strbuf_skip(b, 0, 0); + sdb_strbuf_skip(b, 0, 10); + sdb_strbuf_skip(b, 10, 10); + sdb_strbuf_clear(b); + + /* check that methods return an error */ + fail_unless(sdb_strbuf_vappend(b, "test", ap) < 0, + "sdb_strbuf_vappend(NULL) didn't report failure"); + fail_unless(sdb_strbuf_append(b, "test") < 0, + "sdb_strbuf_append(NULL) didn't report failure"); + fail_unless(sdb_strbuf_vsprintf(b, "test", ap) < 0, + "sdb_strbuf_vsprintf(NULL) didn't report failure"); + fail_unless(sdb_strbuf_sprintf(b, "test") < 0, + "sdb_strbuf_sprintf(NULL) didn't report failure"); + fail_unless(sdb_strbuf_memcpy(b, "test", 4) < 0, + "sdb_strbuf_memcpy(NULL) didn't report failure"); + fail_unless(sdb_strbuf_memappend(b, "test", 4) < 0, + "sdb_strbuf_memappend(NULL) didn't report failure"); + fail_unless(sdb_strbuf_read(b, 0, 32) < 0, + "sdb_strbuf_read(NULL) didn't report failure"); + fail_unless(sdb_strbuf_chomp(b) < 0, + "sdb_strbuf_chomp(NULL) didn't report failure"); +} +END_TEST + +START_TEST(test_empty) +{ + sdb_strbuf_t *b = sdb_strbuf_create(0); + const char *data; + size_t len; + + /* check that methods don't crash */ + sdb_strbuf_skip(b, 1, 1); + sdb_strbuf_clear(b); + sdb_strbuf_chomp(b); + + data = sdb_strbuf_string(b); + fail_unless(data && (*data == '\0'), + "sdb_strbuf_string() = '%s'; expected: ''", data); + len = sdb_strbuf_len(b); + fail_unless(len == 0, + "sdb_strbuf_len() = %zu; expected: 0", len); + + sdb_strbuf_destroy(b); +} +END_TEST + START_TEST(test_sdb_strbuf_create) { sdb_strbuf_t *s; @@ -177,63 +231,303 @@ START_TEST(test_sdb_strbuf_sprintf) } END_TEST -START_TEST(test_sdb_strbuf_chomp) +START_TEST(test_incremental) { ssize_t n; - const char *check; - - /* empty buffer */ - n = sdb_strbuf_chomp(buf); - fail_unless(n == 0, - "sdb_strbuf_chomp() = %zi; expected: 0", n); - - sdb_strbuf_sprintf(buf, "\n"); - n = sdb_strbuf_chomp(buf); - fail_unless(n == 1, - "sdb_strbuf_chomp() = %zi; expected: 1", n); - check = sdb_strbuf_string(buf); - fail_unless(!strcmp(check, ""), - "sdb_strbuf_chomp() did not correctly remove newlines; " - "got string '%s'; expected: ''", check); - - sdb_strbuf_sprintf(buf, "12345\n\n"); - n = sdb_strbuf_chomp(buf); - fail_unless(n == 2, - "sdb_strbuf_chomp() = %zi; expected: 2", n); - check = sdb_strbuf_string(buf); - fail_unless(!strcmp(check, "12345"), - "sdb_strbuf_chomp() did not correctly remove newlines; " - "got string '%s'; expected: '12345'", check); + size_t i; + + sdb_strbuf_destroy(buf); + buf = sdb_strbuf_create(1024); + + /* fill buffer one by one; leave room for nul-byte */ + for (i = 0; i < 1023; ++i) { + n = sdb_strbuf_append(buf, "."); + fail_unless(n == 1, "sdb_strbuf_append() = %zi; expected: 1", n); + } + + /* write another byte; this has to trigger a resize */ + n = sdb_strbuf_append(buf, "."); + fail_unless(n == 1, "sdb_strbuf_append() = %zi; expected: 1", n); + + /* write more bytes; this should trigger at least one more resize but + * that's an implementation detail */ + for (i = 0; i < 1024; ++i) { + n = sdb_strbuf_append(buf, "."); + fail_unless(n == 1, "sdb_strbuf_append() = %zi; expected: 1", n); + } + + n = (ssize_t)sdb_strbuf_len(buf); + fail_unless(n == 2048, "sdb_strbuf_len() = %zi; expectd: 2048", n); } END_TEST -START_TEST(test_sdb_strbuf_string) +static struct { + const char *input; + size_t size; +} mem_golden_data[] = { + { "abc\0\x10\x42", 6 }, + { "\0\1\2\3\4", 5 }, + { "\n\n\0\n\n", 5 }, + { "", 0 }, +}; + +START_TEST(test_sdb_strbuf_memcpy) +{ + size_t i; + + for (i = 0; i < SDB_STATIC_ARRAY_LEN(mem_golden_data); ++i) { + ssize_t n; + const char *check; + + n = sdb_strbuf_memcpy(buf, mem_golden_data[i].input, + mem_golden_data[i].size); + fail_unless(n >= 0, + "sdb_strbuf_memcpy() = %zi; expected: >=0", n); + fail_unless((size_t)n == mem_golden_data[i].size, + "sdb_strbuf_memcpy() = %zi; expected: %zu", + n, mem_golden_data[i].size); + + n = (ssize_t)sdb_strbuf_len(buf); + fail_unless((size_t)n == mem_golden_data[i].size, + "sdb_strbuf_len() = %zu (after memcpy); expected: %zu", + n, mem_golden_data[i].size); + + check = sdb_strbuf_string(buf); + fail_unless(check != NULL, + "sdb_strbuf_string() = NULL (after memcpy); expected: data"); + fail_unless(check[mem_golden_data[i].size] == '\0', + "sdb_strbuf_memcpy() did not nil-terminate the data"); + fail_unless(!memcmp(check, mem_golden_data[i].input, + mem_golden_data[i].size), + "sdb_strbuf_memcpy() did not set the buffer correctly"); + } +} +END_TEST + +START_TEST(test_sdb_strbuf_memappend) { - const char *check; + size_t i; + + for (i = 0; i < SDB_STATIC_ARRAY_LEN(mem_golden_data); ++i) { + ssize_t n; + const char *check; + + size_t total, j; + + n = sdb_strbuf_memappend(buf, mem_golden_data[i].input, + mem_golden_data[i].size); + fail_unless(n >= 0, + "sdb_strbuf_memappend() = %zi; expected: >=0", n); + fail_unless((size_t)n == mem_golden_data[i].size, + "sdb_strbuf_memappend() = %zi; expected: %zu", + n, mem_golden_data[i].size); + + check = sdb_strbuf_string(buf); + fail_unless(check != NULL, + "sdb_strbuf_string() = NULL (after memappend); " + "expected: data"); + + n = (ssize_t)sdb_strbuf_len(buf); + total = 0; + for (j = 0; j <= i; ++j) { + fail_unless(total + mem_golden_data[j].size <= (size_t)n, + "sdb_strbuf_len() = %zu (after memappend); " + "expected: >=%zu", n, total + mem_golden_data[j].size); + + fail_unless(!memcmp(check + total, mem_golden_data[j].input, + mem_golden_data[j].size), + "sdb_strbuf_memappend() did not " + "set the buffer correctly"); + total += mem_golden_data[j].size; + } + fail_unless((size_t)n == total, + "sdb_strbuf_len() = %zu (after memappend); expected: %zu", + n, total); + + fail_unless(check[total] == '\0', + "sdb_strbuf_memappend() did not nil-terminate the data"); + } +} +END_TEST - check = sdb_strbuf_string(buf); - fail_unless(!strcmp(check, ""), - "sdb_strbuf_string() = '%s'; expected: ''", check); +static struct { + const char *input; + ssize_t expected; + const char *expected_string; +} chomp_golden_data[] = { + { NULL, 0, "" }, + { "\n", 1, "" }, + { "\n\n", 2, "" }, + { "12345\n\n\n", 3, "12345" }, + { "abcd", 0, "abcd" }, +}; - sdb_strbuf_sprintf(buf, "abcdef"); - check = sdb_strbuf_string(buf); - fail_unless(!strcmp(check, "abcdef"), - "sdb_strbuf_string() = '%s'; expected: 'abcdef'", check); +START_TEST(test_sdb_strbuf_chomp) +{ + size_t i; + + for (i = 0; i < SDB_STATIC_ARRAY_LEN(chomp_golden_data); ++i) { + ssize_t n; + const char *check; + + if (chomp_golden_data[i].input) + sdb_strbuf_sprintf(buf, chomp_golden_data[i].input); + + /* empty buffer */ + n = sdb_strbuf_chomp(buf); + fail_unless(n == chomp_golden_data[i].expected, + "sdb_strbuf_chomp() = %zi; expected: %zi", n, + chomp_golden_data[i].expected); + + check = sdb_strbuf_string(buf); + fail_unless(!strcmp(check, chomp_golden_data[i].expected_string), + "sdb_strbuf_chomp() did not correctly remove newlines; " + "got string '%s'; expected: '%s'", check, + chomp_golden_data[i].expected_string); + } } END_TEST -START_TEST(test_sdb_strbuf_len) +/* input is "1234567890" */ +static struct { + size_t offset; + size_t n; + const char *expected; + size_t expected_len; +} skip_golden_data[] = { + { 0, 0, "1234567890", 10 }, + { 0, 1, "234567890", 9 }, + { 0, 2, "34567890", 8 }, + { 0, 9, "0", 1 }, + { 0, 10, "", 0 }, + { 0, 11, "", 0 }, + { 0, 100, "", 0 }, + { 1, 0, "1234567890", 10 }, + { 1, 1, "134567890", 9 }, + { 1, 2, "14567890", 8 }, + { 2, 0, "1234567890", 10 }, + { 2, 1, "124567890", 9 }, + { 2, 2, "12567890", 8 }, + { 2, 3, "1267890", 7 }, + { 2, 4, "127890", 6 }, + { 2, 5, "12890", 5 }, + { 2, 6, "1290", 4 }, + { 2, 7, "120", 3 }, + { 2, 8, "12", 2 }, + { 2, 9, "12", 2 }, + { 2, 10, "12", 2 }, + { 8, 1, "123456780", 9 }, + { 8, 2, "12345678", 8 }, + { 8, 3, "12345678", 8 }, + { 9, 1, "123456789", 9 }, + { 9, 2, "123456789", 9 }, + { 10, 1, "1234567890", 10 }, + { 10, 2, "1234567890", 10 }, +}; + +START_TEST(test_sdb_strbuf_skip) +{ + const char *input = "1234567890"; + size_t i; + + for (i = 0; i < SDB_STATIC_ARRAY_LEN(skip_golden_data); ++i) { + const char *check; + size_t n; + + sdb_strbuf_sprintf(buf, input); + sdb_strbuf_skip(buf, skip_golden_data[i].offset, + skip_golden_data[i].n); + + n = sdb_strbuf_len(buf); + fail_unless(n == skip_golden_data[i].expected_len, + "sdb_strbuf_len() = %zu (after skip); expected: %zu", + n, skip_golden_data[i].expected_len); + + check = sdb_strbuf_string(buf); + fail_unless(!!check, + "sdb_strbuf_string() = NULL (after skip); expected: string"); + + fail_unless(check[n] == '\0', + "sdb_strbuf_skip() did not nil-terminate the string"); + + fail_unless(! strcmp(skip_golden_data[i].expected, check), + "sdb_strbuf_skip('%s', %zu) did not skip correctly; " + "got string '%s'; expected: '%s'", input, + skip_golden_data[i].n, check, skip_golden_data[i].expected); + } +} +END_TEST + +START_TEST(test_sdb_strbuf_clear) +{ + const char *data; + size_t len; + + sdb_strbuf_append(buf, "abc"); + len = sdb_strbuf_len(buf); + fail_unless(len != 0, + "sdb_strbuf_len() = %zu; expected: != 0", len); + + sdb_strbuf_clear(buf); + len = sdb_strbuf_len(buf); + fail_unless(len == 0, + "sdb_strbuf_len() = %zu (after clear); expected: 0", len); + + data = sdb_strbuf_string(buf); + fail_unless(*data == '\0', + "sdb_strbuf_string() = '%s' (after clear); expected: ''", data); +} +END_TEST + +static struct { + const char *input; + const char *expected; +} string_golden_data[] = { + { NULL, "" }, + { "a", "a" }, + { "abcdef", "abcdef" }, +}; + +START_TEST(test_sdb_strbuf_string) { - size_t check; + size_t i; + + for (i = 0; i < SDB_STATIC_ARRAY_LEN(string_golden_data); ++i) { + const char *check; + + if (string_golden_data[i].input) + sdb_strbuf_sprintf(buf, string_golden_data[i].input); + check = sdb_strbuf_string(buf); + fail_unless(!strcmp(check, string_golden_data[i].expected), + "sdb_strbuf_string() = '%s'; expected: '%s'", + check, string_golden_data[i].expected); + } +} +END_TEST - check = sdb_strbuf_len(buf); - fail_unless(check == 0, - "sdb_strbuf_len() = %zu; expected: 0", check); +static struct { + const char *input; + size_t expected; +} len_golden_data[] = { + { NULL, 0 }, + { "a", 1 }, + { "12345", 5 }, +}; - sdb_strbuf_sprintf(buf, "a"); - check = sdb_strbuf_len(buf); - fail_unless(check == 1, - "sdb_strbuf_len() = %zu; expected: 1", check); +START_TEST(test_sdb_strbuf_len) +{ + size_t i; + + for (i = 0; i < SDB_STATIC_ARRAY_LEN(len_golden_data); ++i) { + size_t check; + + if (len_golden_data[i].input) + sdb_strbuf_sprintf(buf, len_golden_data[i].input); + check = sdb_strbuf_len(buf); + fail_unless(check == len_golden_data[i].expected, + "sdb_strbuf_len() = %zu; expected: %zu", + check, len_golden_data[i].expected); + } } END_TEST @@ -243,12 +537,22 @@ util_strbuf_suite(void) Suite *s = suite_create("utils::strbuf"); TCase *tc; + tc = tcase_create("empty"); + tcase_add_test(tc, test_null); + tcase_add_test(tc, test_empty); + suite_add_tcase(s, tc); + tc = tcase_create("core"); tcase_add_checked_fixture(tc, setup, teardown); tcase_add_test(tc, test_sdb_strbuf_create); tcase_add_test(tc, test_sdb_strbuf_append); tcase_add_test(tc, test_sdb_strbuf_sprintf); + tcase_add_test(tc, test_incremental); + tcase_add_test(tc, test_sdb_strbuf_memcpy); + tcase_add_test(tc, test_sdb_strbuf_memappend); tcase_add_test(tc, test_sdb_strbuf_chomp); + tcase_add_test(tc, test_sdb_strbuf_skip); + tcase_add_test(tc, test_sdb_strbuf_clear); tcase_add_test(tc, test_sdb_strbuf_string); tcase_add_test(tc, test_sdb_strbuf_len); suite_add_tcase(s, tc);