Code

Merged branch 'master' of git://git.tokkee.org/sysdb.
[sysdb.git] / t / utils / strbuf_test.c
index ad04b87e66a0f617812b7be96638f9f0155ebd9f..bb03296d79da887181e4ac9d992fa989320f9dc3 100644 (file)
@@ -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(<empty>) = '%s'; expected: ''", data);
+       len = sdb_strbuf_len(b);
+       fail_unless(len == 0,
+                       "sdb_strbuf_len(<empty>) = %zu; expected: 0", len);
+
+       sdb_strbuf_destroy(b);
+}
+END_TEST
+
 START_TEST(test_sdb_strbuf_create)
 {
        sdb_strbuf_t *s;
@@ -177,6 +231,36 @@ START_TEST(test_sdb_strbuf_sprintf)
 }
 END_TEST
 
+START_TEST(test_incremental)
+{
+       ssize_t n;
+       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
+
 static struct {
        const char *input;
        size_t size;
@@ -304,6 +388,97 @@ START_TEST(test_sdb_strbuf_chomp)
 }
 END_TEST
 
+/* 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;
@@ -362,14 +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);