diff options
Diffstat (limited to 'memstack/test/memstack_test.c')
-rw-r--r-- | memstack/test/memstack_test.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/memstack/test/memstack_test.c b/memstack/test/memstack_test.c new file mode 100644 index 0000000..5e9b493 --- /dev/null +++ b/memstack/test/memstack_test.c | |||
@@ -0,0 +1,107 @@ | |||
1 | #include "memstack.h" | ||
2 | |||
3 | #include "test.h" | ||
4 | |||
5 | #define NUM_INTS 10 | ||
6 | #define CAPACITY (NUM_INTS * sizeof(int)) | ||
7 | |||
8 | // Create and destroy a statically-backed stack. | ||
9 | TEST_CASE(memstack_create) { | ||
10 | int memory[CAPACITY]; | ||
11 | |||
12 | memstack stack = {0}; | ||
13 | memstack_make(&stack, CAPACITY, memory); | ||
14 | memstack_del(&stack); | ||
15 | } | ||
16 | |||
17 | // Create and destroy a dynamically-backed stack. | ||
18 | TEST_CASE(mem_create_dyn) { | ||
19 | memstack stack = {0}; | ||
20 | memstack_make(&stack, CAPACITY, nullptr); | ||
21 | memstack_del(&stack); | ||
22 | } | ||
23 | |||
24 | // Allocate all N ints. | ||
25 | TEST_CASE(memstack_allocate_until_full) { | ||
26 | memstack stack = {0}; | ||
27 | memstack_make(&stack, CAPACITY, nullptr); | ||
28 | |||
29 | for (int i = 0; i < NUM_INTS; ++i) { | ||
30 | const int* block = memstack_alloc(&stack, sizeof(int)); | ||
31 | TEST_TRUE(block != nullptr); | ||
32 | } | ||
33 | |||
34 | TEST_TRUE(memstack_size(&stack) == CAPACITY); | ||
35 | } | ||
36 | |||
37 | // Allocate all N ints, then free them. | ||
38 | TEST_CASE(memstack_fill_then_free) { | ||
39 | memstack stack = {0}; | ||
40 | memstack_make(&stack, CAPACITY, nullptr); | ||
41 | |||
42 | int* blocks[NUM_INTS] = {nullptr}; | ||
43 | for (int i = 0; i < NUM_INTS; ++i) { | ||
44 | blocks[i] = memstack_alloc(&stack, sizeof(int)); | ||
45 | TEST_TRUE(blocks[i] != nullptr); | ||
46 | } | ||
47 | |||
48 | memstack_clear(&stack); | ||
49 | |||
50 | TEST_EQUAL(memstack_size(&stack), 0); | ||
51 | } | ||
52 | |||
53 | // Attempt to allocate blocks past the maximum stack size. | ||
54 | // The stack should handle the failed allocations gracefully. | ||
55 | TEST_CASE(memstack_allocate_beyond_max_size) { | ||
56 | memstack stack = {0}; | ||
57 | memstack_make(&stack, CAPACITY, nullptr); | ||
58 | memstack_enable_traps(&stack, false); | ||
59 | |||
60 | // Fully allocate the stack. | ||
61 | for (int i = 0; i < NUM_INTS; ++i) { | ||
62 | TEST_TRUE(memstack_alloc(&stack, sizeof(int)) != nullptr); | ||
63 | } | ||
64 | |||
65 | // Past the end. | ||
66 | for (int i = 0; i < NUM_INTS; ++i) { | ||
67 | TEST_EQUAL(memstack_alloc(&stack, sizeof(int)), nullptr); | ||
68 | } | ||
69 | |||
70 | TEST_TRUE(memstack_size(&stack) == CAPACITY); | ||
71 | } | ||
72 | |||
73 | // Free blocks should always remain zeroed out. | ||
74 | // This tests the invariant right after creating the stack. | ||
75 | TEST_CASE(memstack_zero_free_blocks_after_creation) { | ||
76 | memstack stack = {0}; | ||
77 | memstack_make(&stack, CAPACITY, nullptr); | ||
78 | |||
79 | for (int i = 0; i < NUM_INTS; ++i) { | ||
80 | const int* block = memstack_alloc(&stack, sizeof(int)); | ||
81 | TEST_TRUE(block != nullptr); | ||
82 | TEST_EQUAL(*block, 0); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | // Free blocks should always remain zeroed out. | ||
87 | // This tests the invariant after clearing the stack and allocating a new block. | ||
88 | TEST_CASE(memstack_zero_free_block_after_free) { | ||
89 | memstack stack = {0}; | ||
90 | memstack_make(&stack, CAPACITY, nullptr); | ||
91 | |||
92 | for (int i = 0; i < NUM_INTS; ++i) { | ||
93 | const int* block = memstack_alloc(&stack, sizeof(int)); | ||
94 | TEST_TRUE(block != nullptr); | ||
95 | TEST_EQUAL(*block, 0); | ||
96 | } | ||
97 | |||
98 | memstack_clear(&stack); | ||
99 | |||
100 | for (int i = 0; i < NUM_INTS; ++i) { | ||
101 | const int* block = memstack_alloc(&stack, sizeof(int)); | ||
102 | TEST_TRUE(block != nullptr); | ||
103 | TEST_EQUAL(*block, 0); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | int main() { return 0; } | ||