summaryrefslogtreecommitdiffstats
path: root/tests/test_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_buffer.c')
-rw-r--r--tests/test_buffer.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/tests/test_buffer.c b/tests/test_buffer.c
new file mode 100644
index 0000000..f6e61dc
--- /dev/null
+++ b/tests/test_buffer.c
@@ -0,0 +1,134 @@
+// Tests for buffer.h - dynamic buffer allocation and resizing
+#define BUFFER_IMPLEMENTATION
+#include "../include/buffer.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ASSERT(cond, msg) \
+ do { \
+ if (!(cond)) { \
+ fprintf(stderr, "FAIL: %s (test_buffer.c:%d)\n", msg, __LINE__); \
+ failures++; \
+ } \
+ } while (0)
+
+static int failures = 0;
+
+void test_malloc_and_free() {
+ void *buf = buffer_malloc(10, sizeof(int));
+ ASSERT(buf != NULL, "buffer_malloc returns non-NULL");
+ buffer_free(buf);
+}
+
+void test_capacity() {
+ void *buf = buffer_malloc(10, sizeof(int));
+ ASSERT(buffer_capacity(buf) == 10, "initial capacity");
+ buffer_free(buf);
+}
+
+void test_count() {
+ void *buf = buffer_malloc(10, sizeof(int));
+ ASSERT(buffer_count(buf) == 0, "initial count is 0");
+ buffer_free(buf);
+}
+
+void test_resize_grow() {
+ void *buf = buffer_malloc(10, sizeof(int));
+ ASSERT(buf != NULL, "buffer_malloc returns non-NULL");
+ if (!buf) return;
+ buffer_meta_t *meta = (buffer_meta_t *)_buffer_to_meta(buf);
+ meta->i = 9;
+
+ void *new_buf = buffer_resize(buf);
+ meta = (buffer_meta_t *)_buffer_to_meta(new_buf);
+ ASSERT(meta->n == 20, "capacity doubles when ratio > 0.8");
+
+ buffer_free(new_buf);
+}
+
+void test_resize_shrink() {
+ void *buf = buffer_malloc(100, sizeof(int));
+ ASSERT(buf != NULL, "buffer_malloc returns non-NULL");
+ if (!buf) return;
+ buffer_meta_t *meta = (buffer_meta_t *)_buffer_to_meta(buf);
+ meta->i = 5;
+
+ void *new_buf = buffer_resize(buf);
+ meta = (buffer_meta_t *)_buffer_to_meta(new_buf);
+ ASSERT(meta->n == 50, "capacity halves when ratio < 0.2 and n > 32");
+
+ buffer_free(new_buf);
+}
+
+void test_resize_no_change() {
+ void *buf = buffer_malloc(32, sizeof(int));
+ ASSERT(buf != NULL, "buffer_malloc returns non-NULL");
+ if (!buf) return;
+ buffer_meta_t *meta = (buffer_meta_t *)_buffer_to_meta(buf);
+ meta->i = 10;
+
+ void *new_buf = buffer_resize(buf);
+ ASSERT(new_buf == buf, "no realloc when capacity unchanged");
+
+ buffer_free(buf);
+}
+
+void test_resize_small_no_shrink() {
+ void *buf = buffer_malloc(30, sizeof(int));
+ ASSERT(buf != NULL, "buffer_malloc returns non-NULL");
+ if (!buf) return;
+ buffer_meta_t *meta = (buffer_meta_t *)_buffer_to_meta(buf);
+ meta->i = 1;
+
+ void *new_buf = buffer_resize(buf);
+ meta = (buffer_meta_t *)_buffer_to_meta(new_buf);
+ ASSERT(meta->n == 30, "does not shrink below 32");
+
+ buffer_free(new_buf);
+}
+
+void test_data_integrity() {
+ int *buf = (int *)buffer_malloc(10, sizeof(int));
+ for (int i = 0; i < 10; i++) {
+ buf[i] = i * 100;
+ }
+
+ buffer_meta_t *meta = (buffer_meta_t *)_buffer_to_meta(buf);
+ meta->i = 9;
+
+ int *new_buf = (int *)buffer_resize(buf);
+ for (int i = 0; i < 10; i++) {
+ ASSERT(new_buf[i] == i * 100, "data preserved after resize");
+ }
+
+ buffer_free(new_buf);
+}
+
+void test_different_sizes() {
+ void *buf1 = buffer_malloc(5, sizeof(char));
+ void *buf2 = buffer_malloc(5, sizeof(int));
+ void *buf3 = buffer_malloc(5, sizeof(double));
+ ASSERT(buffer_capacity(buf1) == 5, "char capacity");
+ ASSERT(buffer_capacity(buf2) == 5, "int capacity");
+ ASSERT(buffer_capacity(buf3) == 5, "double capacity");
+ buffer_free(buf1);
+ buffer_free(buf2);
+ buffer_free(buf3);
+}
+
+int main() {
+ test_malloc_and_free();
+ test_capacity();
+ test_count();
+ test_resize_grow();
+ test_resize_shrink();
+ test_resize_no_change();
+ test_resize_small_no_shrink();
+ test_data_integrity();
+ test_different_sizes();
+
+ printf("test_buffer: %d failures\n", failures);
+ return failures;
+}