]>
Commit | Line | Data |
---|---|---|
e137fe3b PW |
1 | #include "test-lib.h" |
2 | #include "strbuf.h" | |
3 | ||
4 | /* wrapper that supplies tests with an empty, initialized strbuf */ | |
5 | static void setup(void (*f)(struct strbuf*, void*), void *data) | |
6 | { | |
7 | struct strbuf buf = STRBUF_INIT; | |
8 | ||
9 | f(&buf, data); | |
10 | strbuf_release(&buf); | |
11 | check_uint(buf.len, ==, 0); | |
12 | check_uint(buf.alloc, ==, 0); | |
13 | } | |
14 | ||
15 | /* wrapper that supplies tests with a populated, initialized strbuf */ | |
16 | static void setup_populated(void (*f)(struct strbuf*, void*), char *init_str, void *data) | |
17 | { | |
18 | struct strbuf buf = STRBUF_INIT; | |
19 | ||
20 | strbuf_addstr(&buf, init_str); | |
21 | check_uint(buf.len, ==, strlen(init_str)); | |
22 | f(&buf, data); | |
23 | strbuf_release(&buf); | |
24 | check_uint(buf.len, ==, 0); | |
25 | check_uint(buf.alloc, ==, 0); | |
26 | } | |
27 | ||
28 | static int assert_sane_strbuf(struct strbuf *buf) | |
29 | { | |
30 | /* Initialized strbufs should always have a non-NULL buffer */ | |
31 | if (!check(!!buf->buf)) | |
32 | return 0; | |
33 | /* Buffers should always be NUL-terminated */ | |
34 | if (!check_char(buf->buf[buf->len], ==, '\0')) | |
35 | return 0; | |
36 | /* | |
37 | * Freshly-initialized strbufs may not have a dynamically allocated | |
38 | * buffer | |
39 | */ | |
40 | if (buf->len == 0 && buf->alloc == 0) | |
41 | return 1; | |
42 | /* alloc must be at least one byte larger than len */ | |
43 | return check_uint(buf->len, <, buf->alloc); | |
44 | } | |
45 | ||
46 | static void t_static_init(void) | |
47 | { | |
48 | struct strbuf buf = STRBUF_INIT; | |
49 | ||
50 | check_uint(buf.len, ==, 0); | |
51 | check_uint(buf.alloc, ==, 0); | |
52 | check_char(buf.buf[0], ==, '\0'); | |
53 | } | |
54 | ||
55 | static void t_dynamic_init(void) | |
56 | { | |
57 | struct strbuf buf; | |
58 | ||
59 | strbuf_init(&buf, 1024); | |
60 | check(assert_sane_strbuf(&buf)); | |
61 | check_uint(buf.len, ==, 0); | |
62 | check_uint(buf.alloc, >=, 1024); | |
63 | check_char(buf.buf[0], ==, '\0'); | |
64 | strbuf_release(&buf); | |
65 | } | |
66 | ||
67 | static void t_addch(struct strbuf *buf, void *data) | |
68 | { | |
69 | const char *p_ch = data; | |
70 | const char ch = *p_ch; | |
71 | size_t orig_alloc = buf->alloc; | |
72 | size_t orig_len = buf->len; | |
73 | ||
74 | if (!check(assert_sane_strbuf(buf))) | |
75 | return; | |
76 | strbuf_addch(buf, ch); | |
77 | if (!check(assert_sane_strbuf(buf))) | |
78 | return; | |
79 | if (!(check_uint(buf->len, ==, orig_len + 1) && | |
80 | check_uint(buf->alloc, >=, orig_alloc))) | |
81 | return; /* avoid de-referencing buf->buf */ | |
82 | check_char(buf->buf[buf->len - 1], ==, ch); | |
83 | check_char(buf->buf[buf->len], ==, '\0'); | |
84 | } | |
85 | ||
86 | static void t_addstr(struct strbuf *buf, void *data) | |
87 | { | |
88 | const char *text = data; | |
89 | size_t len = strlen(text); | |
90 | size_t orig_alloc = buf->alloc; | |
91 | size_t orig_len = buf->len; | |
92 | ||
93 | if (!check(assert_sane_strbuf(buf))) | |
94 | return; | |
95 | strbuf_addstr(buf, text); | |
96 | if (!check(assert_sane_strbuf(buf))) | |
97 | return; | |
98 | if (!(check_uint(buf->len, ==, orig_len + len) && | |
99 | check_uint(buf->alloc, >=, orig_alloc) && | |
100 | check_uint(buf->alloc, >, orig_len + len) && | |
101 | check_char(buf->buf[orig_len + len], ==, '\0'))) | |
102 | return; | |
103 | check_str(buf->buf + orig_len, text); | |
104 | } | |
105 | ||
106 | int cmd_main(int argc, const char **argv) | |
107 | { | |
108 | if (!TEST(t_static_init(), "static initialization works")) | |
109 | test_skip_all("STRBUF_INIT is broken"); | |
110 | TEST(t_dynamic_init(), "dynamic initialization works"); | |
111 | TEST(setup(t_addch, "a"), "strbuf_addch adds char"); | |
112 | TEST(setup(t_addch, ""), "strbuf_addch adds NUL char"); | |
113 | TEST(setup_populated(t_addch, "initial value", "a"), | |
114 | "strbuf_addch appends to initial value"); | |
115 | TEST(setup(t_addstr, "hello there"), "strbuf_addstr adds string"); | |
116 | TEST(setup_populated(t_addstr, "initial value", "hello there"), | |
117 | "strbuf_addstr appends string to initial value"); | |
118 | ||
119 | return test_done(); | |
120 | } |