Skip to content

Commit 0506ed3

Browse files
committed
Add unit tests for dynarr_t
Add a set of unit tests for 'dynarr_t' to verify correctness and serve as usage examples. These tests cover initialization, resizing, appending, retrieval, and error conditions, helping contributors understand how to use the API safely and correctly.
1 parent 058cb2d commit 0506ed3

File tree

3 files changed

+190
-0
lines changed

3 files changed

+190
-0
lines changed

tests/snapshots/test_dynarr-arm.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

tests/snapshots/test_dynarr-riscv.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

tests/test_dynarr.c

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#include "../src/globals.c"
2+
3+
/*
4+
* Simple assert‑style helper.
5+
*/
6+
void ensure(bool cond, char *message)
7+
{
8+
if (!cond) {
9+
printf("ERROR: %s\n", message);
10+
exit(1);
11+
}
12+
}
13+
14+
/* === Test: initialization and basic properties === */
15+
void test_init_and_properties(arena_t *arena)
16+
{
17+
printf("=== Running test_init_and_properties ===\n");
18+
19+
dynarr_t *bytes = dynarr_init(arena, 0, 1);
20+
ensure(bytes->size == 0, "bytes initial size == 0");
21+
ensure(bytes->capacity == 0, "bytes initial capacity == 0");
22+
ensure(bytes->elem_size == 1, "bytes elem_size == 1");
23+
24+
dynarr_t *words = dynarr_init(arena, 8, sizeof(int));
25+
ensure(words->size == 0, "words initial size == 0");
26+
ensure(words->capacity >= 8, "words capacity >= init_cap (8)");
27+
ensure(words->elem_size == sizeof(int), "words elem_size == sizeof(int)");
28+
29+
printf("[OK] init & property checks passed\n\n");
30+
}
31+
32+
/* === Test: push_byte / get_byte === */
33+
void test_push_and_get_byte(arena_t *arena)
34+
{
35+
printf("=== Running test_push_and_get_byte ===\n");
36+
37+
dynarr_t *arr = dynarr_init(arena, 4, 1);
38+
39+
char sample[] = "DynamicArray";
40+
for (int i = 0; sample[i] != '\0'; ++i) {
41+
dynarr_push_byte(arr, sample[i]);
42+
}
43+
44+
ensure(arr->size == strlen(sample), "size after pushes == strlen(sample)");
45+
for (int i = 0; i < arr->size; ++i) {
46+
char c = dynarr_get_byte(arr, i);
47+
ensure(c == sample[i], "push/get byte round-trip");
48+
}
49+
50+
printf("[OK] push_byte / get_byte passed\n\n");
51+
}
52+
53+
/* === Test: push_word / get_word === */
54+
void test_push_and_get_word(arena_t *arena)
55+
{
56+
printf("=== Running test_push_and_get_word ===\n");
57+
58+
dynarr_t *arr = dynarr_init(arena, 0, sizeof(int));
59+
60+
for (int i = 0; i < 32; ++i)
61+
dynarr_push_word(arr, i * 3);
62+
63+
ensure(arr->size == 32, "size after 32 pushes == 32");
64+
65+
for (int i = 0; i < 32; ++i) {
66+
int v = dynarr_get_word(arr, i);
67+
ensure(v == i * 3, "push/get word round‑trip");
68+
}
69+
70+
printf("[OK] push_word / get_word passed\n\n");
71+
}
72+
73+
/* === Test: push_raw, set_raw, get_raw === */
74+
typedef struct {
75+
int a;
76+
int b;
77+
} Pair;
78+
79+
void test_push_raw_and_set_raw(arena_t *arena)
80+
{
81+
printf("=== Running test_push_raw_and_set_raw ===\n");
82+
83+
dynarr_t *arr = dynarr_init(arena, 0, sizeof(Pair));
84+
85+
Pair p1;
86+
p1.a = 1;
87+
p1.b = 2;
88+
Pair p2;
89+
p2.a = 3;
90+
p2.b = 4;
91+
dynarr_push_raw(arr, &p1);
92+
dynarr_push_raw(arr, &p2);
93+
94+
Pair *got1 = dynarr_get_raw(arr, 0);
95+
Pair *got2 = dynarr_get_raw(arr, 1);
96+
ensure(got1->a == 1 && got1->b == 2, "get_raw element 0 matches");
97+
ensure(got2->a == 3 && got2->b == 4, "get_raw element 1 matches");
98+
99+
got1->a = 100;
100+
got1->b = 200;
101+
got1 = dynarr_get_raw(arr, 0);
102+
ensure(got1->a == 100 && got1->b == 200,
103+
"get_raw element 0 reflects modification");
104+
105+
Pair p3;
106+
p3.a = 7;
107+
p3.b = 8;
108+
dynarr_set_raw(arr, 0, &p3);
109+
got1 = dynarr_get_raw(arr, 0);
110+
ensure(got1->a == 7 && got1->b == 8, "set_raw overwrote element 0");
111+
112+
printf("[OK] push_raw / set_raw / get_raw passed\n\n");
113+
}
114+
115+
/* === Test: extend and resize === */
116+
void test_extend_and_resize(arena_t *arena)
117+
{
118+
printf("=== Running test_extend_and_resize ===\n");
119+
120+
dynarr_t *arr = dynarr_init(arena, 2, 1);
121+
122+
char buf1[5];
123+
buf1[0] = 'h';
124+
buf1[1] = 'e';
125+
buf1[2] = 'l';
126+
buf1[3] = 'l';
127+
buf1[4] = 'o';
128+
dynarr_extend(arr, buf1, 5);
129+
130+
ensure(arr->size == 5, "size after first extend == 5");
131+
ensure(dynarr_get_byte(arr, 0) == 'h' && dynarr_get_byte(arr, 4) == 'o',
132+
"extend copied bytes matches");
133+
134+
dynarr_resize(arr, 10);
135+
ensure(arr->size == 10, "resize enlarged size to 10");
136+
ensure(arr->capacity >= 10, "capacity grew to >= 10");
137+
138+
dynarr_resize(arr, 4);
139+
ensure(arr->size == 4, "resize shrink to 4");
140+
141+
printf("[OK] extend / resize passed\n\n");
142+
}
143+
144+
/* === Test: reallocation move & data preservation === */
145+
void test_realloc_move_and_preserve(arena_t *arena)
146+
{
147+
printf("=== Running test_realloc_move_and_preserve ===\n");
148+
149+
dynarr_t *arr = dynarr_init(arena, 2, 1);
150+
dynarr_push_byte(arr, 'x');
151+
dynarr_push_byte(arr, 'y');
152+
153+
void *old_ptr = arr->elements;
154+
155+
/* trigger growth several times */
156+
for (int i = 0; i < 100; ++i)
157+
dynarr_push_byte(arr, ('a' + (i % 26)));
158+
159+
/* data still valid */
160+
ensure(dynarr_get_byte(arr, 0) == 'x', "data before reallocation intact");
161+
ensure(dynarr_get_byte(arr, 1) == 'y', "data before reallocation intact");
162+
163+
/* ensure capacity >= size */
164+
ensure(arr->capacity >= arr->size, "capacity >= size after growth");
165+
166+
if (arr->elements != old_ptr)
167+
printf(
168+
"[Info] internal buffer moved after reallocation, as expected.\n");
169+
170+
printf("[OK] realloc move & data preservation passed\n");
171+
}
172+
173+
int main(void)
174+
{
175+
/* 1 MiB arena for tests */
176+
arena_t *arena = arena_init(1 << 20);
177+
178+
test_init_and_properties(arena);
179+
test_push_and_get_byte(arena);
180+
test_push_and_get_word(arena);
181+
test_push_raw_and_set_raw(arena);
182+
test_extend_and_resize(arena);
183+
test_realloc_move_and_preserve(arena);
184+
185+
printf("\nAll dynamic array tests passed!\n");
186+
arena_free(arena);
187+
return 0;
188+
}

0 commit comments

Comments
 (0)