]> git.ipfire.org Git - thirdparty/git.git/blob - t/unit-tests/t-strbuf.c
Merge branch 'rs/parse-options-with-keep-unknown-abbrev-fix'
[thirdparty/git.git] / t / unit-tests / t-strbuf.c
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 }