begin migration of buffer tests - relates to #342

Mon, 01 Jan 2024 16:42:37 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 01 Jan 2024 16:42:37 +0100
changeset 789
9b2f5661bebd
parent 788
b34ff44e6433
child 790
42877968260c

begin migration of buffer tests - relates to #342

tests/Makefile file | annotate | diff | comparison | revisions
tests/test_buffer.c file | annotate | diff | comparison | revisions
tests/test_buffer.cpp file | annotate | diff | comparison | revisions
tests/ucxtest.c file | annotate | diff | comparison | revisions
--- a/tests/Makefile	Mon Jan 01 15:33:20 2024 +0100
+++ b/tests/Makefile	Mon Jan 01 16:42:37 2024 +0100
@@ -28,8 +28,8 @@
 TEST_DIR=$(build_dir)/tests
 
 SRC = util_allocator.c test_utils.c test_hash_key.c test_allocator.c \
-	test_compare.c \
-	test_string.c test_printf.c test_mempool.c test_hash_map.c ucxtest.c
+	test_compare.c test_string.c test_buffer.c \
+	test_printf.c test_mempool.c test_hash_map.c ucxtest.c
 
 OBJ_EXT=.o
 OBJ=$(SRC:%.c=$(TEST_DIR)/%$(OBJ_EXT))
@@ -52,6 +52,11 @@
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
+$(TEST_DIR)/test_buffer$(OBJ_EXT): test_buffer.c ../src/cx/test.h \
+ ../src/cx/buffer.h ../src/cx/common.h ../src/cx/allocator.h
+	@echo "Compiling $<"
+	$(CC) -o $@ $(CFLAGS) -c $<
+
 $(TEST_DIR)/test_compare$(OBJ_EXT): test_compare.c ../src/cx/test.h \
  ../src/cx/compare.h ../src/cx/common.h
 	@echo "Compiling $<"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test_buffer.c	Mon Jan 01 16:42:37 2024 +0100
@@ -0,0 +1,418 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cx/test.h"
+#include "util_allocator.h"
+
+#include "cx/buffer.h"
+
+static CX_TEST_SUBROUTINE(expect_default_flush_config, CxBuffer *buf) {
+    CX_TEST_ASSERT(buf->flush_blkmax == 0);
+    CX_TEST_ASSERT(buf->flush_blksize == 4096);
+    CX_TEST_ASSERT(buf->flush_threshold == SIZE_MAX);
+    CX_TEST_ASSERT(buf->flush_func == NULL);
+    CX_TEST_ASSERT(buf->flush_target == NULL);
+}
+
+CX_TEST(test_buffer_init_wrap_space) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        CxBuffer buf;
+        void *space = cxMalloc(alloc, 16);
+        cxBufferInit(&buf, space, 16, alloc, CX_BUFFER_DEFAULT);
+        CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
+        CX_TEST_ASSERT(buf.space == space);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(buf.capacity == 16);
+        CX_TEST_ASSERT(buf.allocator == alloc);
+        cxBufferDestroy(&buf);
+        CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
+        cxFree(alloc, space);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_buffer_init_wrap_space_auto_extend) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        CxBuffer buf;
+        void *space = cxMalloc(alloc, 16);
+        cxBufferInit(&buf, space, 16, alloc, CX_BUFFER_AUTO_EXTEND);
+        CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
+        CX_TEST_ASSERT(buf.space == space);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == CX_BUFFER_AUTO_EXTEND);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(buf.capacity == 16);
+        CX_TEST_ASSERT(buf.allocator == alloc);
+        cxBufferDestroy(&buf);
+        CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
+        cxFree(alloc, space);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_buffer_init_wrap_space_auto_free) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        CxBuffer buf;
+        void *space = cxMalloc(alloc, 16);
+        cxBufferInit(&buf, space, 16, alloc, CX_BUFFER_FREE_CONTENTS);
+        CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
+        CX_TEST_ASSERT(buf.space == space);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS);
+        CX_TEST_ASSERT(buf.pos == 0);
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(buf.capacity == 16);
+        CX_TEST_ASSERT(buf.allocator == alloc);
+        CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
+        cxBufferDestroy(&buf);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_buffer_init_fresh_space) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        CxBuffer buf;
+        cxBufferInit(&buf, NULL, 8, alloc, CX_BUFFER_DEFAULT);
+        CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
+        CX_TEST_ASSERT(buf.space != NULL);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0);
+        CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS);
+        CX_TEST_ASSERT(buf.pos == 0);
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(buf.capacity == 8);
+        CX_TEST_ASSERT(buf.allocator == alloc);
+        CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); // space is still allocated
+        cxBufferDestroy(&buf);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_buffer_init_on_heap) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        CxBuffer *buf;
+        void *space = cxMalloc(alloc, 16);
+        buf = cxBufferCreate(space, 16, alloc, CX_BUFFER_FREE_CONTENTS);
+        CX_TEST_ASSERT(buf != NULL);
+        CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, buf);
+        CX_TEST_ASSERT(buf->space == space);
+        CX_TEST_ASSERT((buf->flags & CX_BUFFER_AUTO_EXTEND) == 0);
+        CX_TEST_ASSERT((buf->flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS);
+        CX_TEST_ASSERT(buf->pos == 0);
+        CX_TEST_ASSERT(buf->size == 0);
+        CX_TEST_ASSERT(buf->capacity == 16);
+        CX_TEST_ASSERT(buf->allocator == alloc);
+        cxBufferFree(buf);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_buffer_minimum_capacity_sufficient) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        void *space = cxMalloc(alloc, 8);
+        CxBuffer buf;
+        cxBufferInit(&buf, space, 8, alloc, CX_BUFFER_FREE_CONTENTS);
+        memcpy(space, "Testing", 8);
+        buf.size = 8;
+        cxBufferMinimumCapacity(&buf, 6);
+        CX_TEST_ASSERT(buf.capacity == 8);
+        CX_TEST_ASSERT(buf.size == 8);
+        CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0);
+        cxBufferDestroy(&buf);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_buffer_minimum_capacity_extend) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+    CX_TEST_DO {
+        void *space = cxMalloc(alloc, 8);
+        CxBuffer buf;
+        cxBufferInit(&buf, space, 8, alloc, CX_BUFFER_FREE_CONTENTS); // NO auto extend!
+        memcpy(space, "Testing", 8);
+        buf.size = 8;
+        cxBufferMinimumCapacity(&buf, 16);
+        CX_TEST_ASSERT(buf.capacity == 16);
+        CX_TEST_ASSERT(buf.size == 8);
+        CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0);
+        cxBufferDestroy(&buf);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
+CX_TEST(test_buffer_clear) {
+    char space[16];
+    strcpy(space, "clear test");
+    CxBuffer buf;
+    cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    CX_TEST_DO {
+        CX_TEST_ASSERT(buf.size == 0);
+        // only clear the used part of the buffer
+        cxBufferClear(&buf);
+        CX_TEST_ASSERT(0 == memcmp(space, "clear test", 10));
+        buf.size = 5;
+        buf.pos = 3;
+        cxBufferClear(&buf);
+        CX_TEST_ASSERT(0 == memcmp(space, "\0\0\0\0\0 test", 10));
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_reset) {
+    char space[16];
+    strcpy(space, "reset test");
+    CxBuffer buf;
+    cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    CX_TEST_DO {
+        buf.size = 5;
+        buf.pos = 3;
+        cxBufferReset(&buf);
+        CX_TEST_ASSERT(0 == memcmp(space, "reset test", 10));
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_set_zero) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 0, SEEK_SET);
+        CX_TEST_ASSERT(result == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_set_valid) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 5, SEEK_SET);
+        CX_TEST_ASSERT(result == 0);
+        CX_TEST_ASSERT(buf.pos == 5);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_set_invalid) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 6, SEEK_SET);
+        CX_TEST_ASSERT(result != 0);
+        CX_TEST_ASSERT(buf.pos == 3);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_cur_zero) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 0, SEEK_CUR);
+        CX_TEST_ASSERT(result == 0);
+        CX_TEST_ASSERT(buf.pos == 3);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_cur_valid_positive) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 2, SEEK_CUR);
+        CX_TEST_ASSERT(result == 0);
+        CX_TEST_ASSERT(buf.pos == 5);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_cur_valid_negative) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, -3, SEEK_CUR);
+        CX_TEST_ASSERT(result == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_cur_invalid_positive) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 3, SEEK_CUR);
+        CX_TEST_ASSERT(result != 0);
+        CX_TEST_ASSERT(buf.pos == 3);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_cur_invalid_negative) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, -4, SEEK_CUR);
+        CX_TEST_ASSERT(result != 0);
+        CX_TEST_ASSERT(buf.pos == 3);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_end_zero) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 0, SEEK_END);
+        // the (past-the-)end position is always invalid
+        CX_TEST_ASSERT(result != 0);
+        CX_TEST_ASSERT(buf.pos == 3);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_end_valid) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, -6, SEEK_END);
+        CX_TEST_ASSERT(result == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_end_invalid) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 1, SEEK_END);
+        CX_TEST_ASSERT(result != 0);
+        CX_TEST_ASSERT(buf.pos == 3);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CX_TEST(test_buffer_seek_whence_invalid) {
+    CxBuffer buf;
+    cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    buf.size = 6;
+    buf.pos = 3;
+    CX_TEST_DO {
+        int result = cxBufferSeek(&buf, 2, 9000);
+        CX_TEST_ASSERT(result != 0);
+        CX_TEST_ASSERT(buf.size == 6);
+        CX_TEST_ASSERT(buf.pos == 3);
+    }
+    cxBufferDestroy(&buf);
+}
+
+CxTestSuite *cx_test_suite_buffer(void) {
+    CxTestSuite *suite = cx_test_suite_new("buffer");
+
+    cx_test_register(suite, test_buffer_init_wrap_space);
+    cx_test_register(suite, test_buffer_init_wrap_space_auto_extend);
+    cx_test_register(suite, test_buffer_init_wrap_space_auto_free);
+    cx_test_register(suite, test_buffer_init_fresh_space);
+    cx_test_register(suite, test_buffer_init_on_heap);
+    cx_test_register(suite, test_buffer_minimum_capacity_sufficient);
+    cx_test_register(suite, test_buffer_minimum_capacity_extend);
+    cx_test_register(suite, test_buffer_clear);
+    cx_test_register(suite, test_buffer_reset);
+    cx_test_register(suite, test_buffer_seek_set_zero);
+    cx_test_register(suite, test_buffer_seek_set_valid);
+    cx_test_register(suite, test_buffer_seek_set_invalid);
+    cx_test_register(suite, test_buffer_seek_cur_zero);
+    cx_test_register(suite, test_buffer_seek_cur_valid_positive);
+    cx_test_register(suite, test_buffer_seek_cur_valid_negative);
+    cx_test_register(suite, test_buffer_seek_cur_invalid_positive);
+    cx_test_register(suite, test_buffer_seek_cur_invalid_negative);
+    cx_test_register(suite, test_buffer_seek_end_zero);
+    cx_test_register(suite, test_buffer_seek_end_valid);
+    cx_test_register(suite, test_buffer_seek_end_invalid);
+    cx_test_register(suite, test_buffer_seek_whence_invalid);
+    
+    return suite;
+}
--- a/tests/test_buffer.cpp	Mon Jan 01 15:33:20 2024 +0100
+++ b/tests/test_buffer.cpp	Mon Jan 01 16:42:37 2024 +0100
@@ -34,7 +34,7 @@
 class BufferFixture : public ::testing::Test {
 protected:
     void SetUp() override {
-        cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+        cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
         buf.size = 6;
         buf.pos = 3;
     }
@@ -46,110 +46,11 @@
     CxBuffer buf{};
 };
 
-static void expect_default_flush_config(CxBuffer *buf) {
-    EXPECT_EQ(buf->flush_blkmax, 0);
-    EXPECT_EQ(buf->flush_blksize, 4096);
-    EXPECT_EQ(buf->flush_threshold, SIZE_MAX);
-    EXPECT_EQ(buf->flush_func, nullptr);
-    EXPECT_EQ(buf->flush_target, nullptr);
-}
-
-TEST(BufferInit, WrapSpace) {
-    CxTestingAllocator alloc;
-    CxBuffer buf;
-    void *space = cxMalloc(&alloc, 16);
-    cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_DEFAULT);
-    expect_default_flush_config(&buf);
-    EXPECT_EQ(buf.space, space);
-    EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
-    EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_EQ(buf.capacity, 16);
-    EXPECT_EQ(buf.allocator, &alloc);
-    cxBufferDestroy(&buf);
-    EXPECT_FALSE(alloc.verify());
-    cxFree(&alloc, space);
-    EXPECT_TRUE(alloc.verify());
-}
-
-TEST(BufferInit, WrapSpaceAutoExtend) {
-    CxTestingAllocator alloc;
-    CxBuffer buf;
-    void *space = cxMalloc(&alloc, 16);
-    cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_AUTO_EXTEND);
-    expect_default_flush_config(&buf);
-    EXPECT_EQ(buf.space, space);
-    EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, CX_BUFFER_AUTO_EXTEND);
-    EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_EQ(buf.capacity, 16);
-    EXPECT_EQ(buf.allocator, &alloc);
-    cxBufferDestroy(&buf);
-    EXPECT_FALSE(alloc.verify());
-    cxFree(&alloc, space);
-    EXPECT_TRUE(alloc.verify());
-}
-
-TEST(BufferInit, WrapSpaceAutoFree) {
-    CxTestingAllocator alloc;
-    CxBuffer buf;
-    void *space = cxMalloc(&alloc, 16);
-    cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_FREE_CONTENTS);
-    expect_default_flush_config(&buf);
-    EXPECT_EQ(buf.space, space);
-    EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
-    EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_EQ(buf.capacity, 16);
-    EXPECT_EQ(buf.allocator, &alloc);
-    EXPECT_FALSE(alloc.verify());
-    cxBufferDestroy(&buf);
-    EXPECT_TRUE(alloc.verify());
-}
-
-TEST(BufferInit, FreshSpace) {
-    CxTestingAllocator alloc;
-    CxBuffer buf;
-    cxBufferInit(&buf, nullptr, 8, &alloc, CX_BUFFER_DEFAULT);
-    expect_default_flush_config(&buf);
-    EXPECT_NE(buf.space, nullptr);
-    EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
-    EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_EQ(buf.capacity, 8);
-    EXPECT_EQ(buf.allocator, &alloc);
-    EXPECT_FALSE(alloc.verify()); // space is still allocated
-    cxBufferDestroy(&buf);
-    EXPECT_TRUE(alloc.verify());
-}
-
-TEST(BufferInit, OnHeap) {
-    CxTestingAllocator alloc;
-    CxBuffer *buf;
-    void *space = cxMalloc(&alloc, 16);
-    buf = cxBufferCreate(space, 16, &alloc, CX_BUFFER_FREE_CONTENTS);
-    EXPECT_NE(buf, nullptr);
-    expect_default_flush_config(buf);
-    EXPECT_EQ(buf->space, space);
-    EXPECT_EQ(buf->flags & CX_BUFFER_AUTO_EXTEND, 0);
-    EXPECT_EQ(buf->flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
-    EXPECT_EQ(buf->pos, 0);
-    EXPECT_EQ(buf->size, 0);
-    EXPECT_EQ(buf->capacity, 16);
-    EXPECT_EQ(buf->allocator, &alloc);
-    cxBufferFree(buf);
-    EXPECT_TRUE(alloc.verify());
-}
-
 class BufferShiftFixture : public ::testing::Test {
 protected:
     void SetUp() override {
-        ASSERT_TRUE(alloc.verify());
-        cxBufferInit(&buf, nullptr, 16, &alloc, CX_BUFFER_DEFAULT);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+        cxBufferInit(&buf, NULL, 16, &alloc, CX_BUFFER_DEFAULT);
         memcpy(buf.space, "test____________", 16);
         buf.capacity = 8; // purposely pretend that the buffer has less capacity s.t. we can test beyond the range
         buf.pos = 4;
@@ -158,7 +59,7 @@
 
     void TearDown() override {
         cxBufferDestroy(&buf);
-        EXPECT_TRUE(alloc.verify());
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
     }
 
     CxTestingAllocator alloc;
@@ -169,193 +70,128 @@
 };
 
 TEST_F(BufferShiftLeft, Zero) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShiftLeft(&buf, 0);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 4);
-    EXPECT_EQ(buf.size, 4);
-    EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
+    CX_TEST_ASSERT(memcmp(buf.space, "test________", 8) == 0);
 }
 
 TEST_F(BufferShiftLeft, ZeroOffsetInterface) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShift(&buf, -0);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 4);
-    EXPECT_EQ(buf.size, 4);
-    EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
+    CX_TEST_ASSERT(memcmp(buf.space, "test________", 8) == 0);
 }
 
 TEST_F(BufferShiftLeft, Standard) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShiftLeft(&buf, 2);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 2);
-    EXPECT_EQ(buf.size, 2);
-    EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 2);
+    CX_TEST_ASSERT(buf.size == 2);
+    CX_TEST_ASSERT(memcmp(buf.space, "stst________", 8) == 0);
 }
 
 TEST_F(BufferShiftLeft, Overshift) {
     ASSERT_LT(buf.pos, 6);
     ASSERT_LT(buf.size, 6);
     int ret = cxBufferShiftLeft(&buf, 6);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 0);
+    CX_TEST_ASSERT(buf.size == 0);
+    CX_TEST_ASSERT(memcmp(buf.space, "test________", 8) == 0);
 }
 
 TEST_F(BufferShiftLeft, OvershiftPosOnly) {
     buf.pos = 2;
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShiftLeft(&buf, 3);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 1);
-    EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 0);
+    CX_TEST_ASSERT(buf.size == 1);
+    CX_TEST_ASSERT(memcmp(buf.space, "test________", 8) == 0);
 }
 
 TEST_F(BufferShiftLeft, OffsetInterface) {
     buf.pos = 3;
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShift(&buf, -2);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 1);
-    EXPECT_EQ(buf.size, 2);
-    EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 1);
+    CX_TEST_ASSERT(buf.size == 2);
+    CX_TEST_ASSERT(memcmp(buf.space, "stst________", 8) == 0);
 }
 
-class BufferShiftRight : public BufferShiftFixture {
-};
-
 TEST_F(BufferShiftRight, Zero) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShiftRight(&buf, 0);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 4);
-    EXPECT_EQ(buf.size, 4);
-    EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
+    CX_TEST_ASSERT(memcmp(buf.space, "test________", 8) == 0);
 }
 
 TEST_F(BufferShiftRight, ZeroOffsetInterface) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShift(&buf, +0);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 4);
-    EXPECT_EQ(buf.size, 4);
-    EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
+    CX_TEST_ASSERT(memcmp(buf.space, "test________", 8) == 0);
 }
 
 TEST_F(BufferShiftRight, Standard) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShiftRight(&buf, 3);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 7);
-    EXPECT_EQ(buf.size, 7);
-    EXPECT_TRUE(memcmp(buf.space, "testest_____", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 7);
+    CX_TEST_ASSERT(buf.size == 7);
+    CX_TEST_ASSERT(memcmp(buf.space, "testest_____", 8) == 0);
 }
 
 TEST_F(BufferShiftRight, OvershiftDiscard) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
-    ASSERT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
     int ret = cxBufferShiftRight(&buf, 6);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 8);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_EQ(buf.capacity, 8);
-    EXPECT_TRUE(memcmp(buf.space, "test__te____", 8) == 0);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 8);
+    CX_TEST_ASSERT(buf.size == 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(memcmp(buf.space, "test__te____", 8) == 0);
 }
 
 TEST_F(BufferShiftRight, OvershiftExtend) {
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
-    ASSERT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
     int ret = cxBufferShiftRight(&buf, 6);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 10);
-    EXPECT_EQ(buf.size, 10);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 10);
+    CX_TEST_ASSERT(buf.size == 10);
     EXPECT_GE(buf.capacity, 10);
-    EXPECT_TRUE(memcmp(buf.space, "test__test__", 8) == 0);
+    CX_TEST_ASSERT(memcmp(buf.space, "test__test__", 8) == 0);
 }
 
 TEST_F(BufferShiftRight, OffsetInterface) {
     buf.pos = 3;
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int ret = cxBufferShift(&buf, 2);
-    EXPECT_EQ(ret, 0);
-    EXPECT_EQ(buf.pos, 5);
-    EXPECT_EQ(buf.size, 6);
-    EXPECT_TRUE(memcmp(buf.space, "tetest______", 8) == 0);
-}
-
-TEST(BufferMinimumCapacity, Sufficient) {
-    CxTestingAllocator alloc;
-    auto space = cxMalloc(&alloc, 8);
-    CxBuffer buf;
-    cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS);
-    memcpy(space, "Testing", 8);
-    buf.size = 8;
-    cxBufferMinimumCapacity(&buf, 6);
-    EXPECT_EQ(buf.capacity, 8);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
-    cxBufferDestroy(&buf);
-    EXPECT_TRUE(alloc.verify());
-}
-
-TEST(BufferMinimumCapacity, Extend) {
-    CxTestingAllocator alloc;
-    auto space = cxMalloc(&alloc, 8);
-    CxBuffer buf;
-    cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS); // NO auto extend!
-    memcpy(space, "Testing", 8);
-    buf.size = 8;
-    cxBufferMinimumCapacity(&buf, 16);
-    EXPECT_EQ(buf.capacity, 16);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
-    cxBufferDestroy(&buf);
-    EXPECT_TRUE(alloc.verify());
-}
-
-TEST(BufferClear, Test) {
-    char space[16];
-    strcpy(space, "clear test");
-    CxBuffer buf;
-    cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
-    ASSERT_EQ(buf.size, 0);
-    // only clear the used part of the buffer
-    cxBufferClear(&buf);
-    EXPECT_EQ(memcmp(space, "clear test", 10), 0);
-    buf.size = 5;
-    buf.pos = 3;
-    cxBufferClear(&buf);
-    EXPECT_EQ(memcmp(space, "\0\0\0\0\0 test", 10), 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_EQ(buf.pos, 0);
-    cxBufferDestroy(&buf);
-}
-
-TEST(BufferReset, Test) {
-    char space[16];
-    strcpy(space, "reset test");
-    CxBuffer buf;
-    cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
-    buf.size = 5;
-    buf.pos = 3;
-    cxBufferReset(&buf);
-    EXPECT_EQ(memcmp(space, "reset test", 10), 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_EQ(buf.pos, 0);
-    cxBufferDestroy(&buf);
+    CX_TEST_ASSERT(ret == 0);
+    CX_TEST_ASSERT(buf.pos == 5);
+    CX_TEST_ASSERT(buf.size == 6);
+    CX_TEST_ASSERT(memcmp(buf.space, "tetest______", 8) == 0);
 }
 
 class BufferWrite : public ::testing::Test {
@@ -363,8 +199,8 @@
     CxBuffer buf{}, target{};
 
     void SetUp() override {
-        cxBufferInit(&target, nullptr, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
-        cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+        cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
+        cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
         buf.capacity = 8; // artificially reduce capacity to check OOB writes
         memset(buf.space, 0, 16);
         memcpy(buf.space, "prep", 4);
@@ -402,221 +238,221 @@
 
 TEST_F(BufferWrite, SizeOneFit) {
     const char *data = "test";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferWrite(data, 1, 4, &buf);
-    EXPECT_EQ(written, 4);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_EQ(buf.pos, 8);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(written == 4);
+    CX_TEST_ASSERT(buf.size == 8);
+    CX_TEST_ASSERT(buf.pos == 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
 }
 
 TEST_F(BufferWrite, SizeOneDiscard) {
     const char *data = "testing";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferWrite(data, 1, 7, &buf);
-    EXPECT_EQ(written, 4);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_EQ(buf.pos, 8);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(written == 4);
+    CX_TEST_ASSERT(buf.size == 8);
+    CX_TEST_ASSERT(buf.pos == 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
 }
 
 TEST_F(BufferWrite, SizeOneExtend) {
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
     const char *data = "testing";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferWrite(data, 1, 7, &buf);
-    EXPECT_EQ(written, 7);
-    EXPECT_EQ(buf.size, 11);
-    EXPECT_EQ(buf.pos, 11);
+    CX_TEST_ASSERT(written == 7);
+    CX_TEST_ASSERT(buf.size == 11);
+    CX_TEST_ASSERT(buf.pos == 11);
     EXPECT_GE(buf.capacity, 11);
     EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
 }
 
 TEST_F(BufferWrite, MultibyteFit) {
     const char *data = "test";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferWrite(data, 2, 2, &buf);
-    EXPECT_EQ(written, 2);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_EQ(buf.pos, 8);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(written == 2);
+    CX_TEST_ASSERT(buf.size == 8);
+    CX_TEST_ASSERT(buf.pos == 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
 }
 
 TEST_F(BufferWrite, MultibyteDiscard) {
     const char *data = "testing";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.size == 4);
     buf.pos = 3;
     size_t written = cxBufferWrite(data, 2, 4, &buf);
     // remember: whole elements are discarded if they do not fit
-    EXPECT_EQ(written, 2);
-    EXPECT_EQ(buf.size, 7);
-    EXPECT_EQ(buf.pos, 7);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(written == 2);
+    CX_TEST_ASSERT(buf.size == 7);
+    CX_TEST_ASSERT(buf.pos == 7);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "pretest\0", 8), 0);
 }
 
 TEST_F(BufferWrite, MultibyteExtend) {
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
     const char *data = "tester";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.size == 4);
     buf.pos = 3;
     size_t written = cxBufferWrite(data, 2, 3, &buf);
     // remember: whole elements are discarded if they do not fit
-    EXPECT_EQ(written, 3);
-    EXPECT_EQ(buf.size, 9);
-    EXPECT_EQ(buf.pos, 9);
+    CX_TEST_ASSERT(written == 3);
+    CX_TEST_ASSERT(buf.size == 9);
+    CX_TEST_ASSERT(buf.pos == 9);
     EXPECT_GE(buf.capacity, 9);
     EXPECT_EQ(memcmp(buf.space, "pretester", 9), 0);
 }
 
 TEST_F(BufferWrite, PutcWrapperFit) {
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     int c = cxBufferPut(&buf, 0x200 | 'a');
-    EXPECT_EQ(c, 'a');
-    EXPECT_EQ(buf.size, 5);
-    EXPECT_EQ(buf.pos, 5);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(c == 'a');
+    CX_TEST_ASSERT(buf.size == 5);
+    CX_TEST_ASSERT(buf.pos == 5);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "prepa\0", 6), 0);
 }
 
 TEST_F(BufferWrite, PutcWrapperDiscard) {
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.size == 4);
     buf.pos = 8;
     int c = cxBufferPut(&buf, 0x200 | 'a');
-    EXPECT_EQ(c, EOF);
-    EXPECT_EQ(buf.size, 4);
-    EXPECT_EQ(buf.pos, 8);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(c == EOF);
+    CX_TEST_ASSERT(buf.size == 4);
+    CX_TEST_ASSERT(buf.pos == 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0\0", 9), 0);
 }
 
 TEST_F(BufferWrite, PutcWrapperExtend) {
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.size == 4);
     buf.pos = 8;
     int c = cxBufferPut(&buf, 0x200 | 'a');
-    EXPECT_EQ(c, 'a');
-    EXPECT_EQ(buf.size, 9);
-    EXPECT_EQ(buf.pos, 9);
+    CX_TEST_ASSERT(c == 'a');
+    CX_TEST_ASSERT(buf.size == 9);
+    CX_TEST_ASSERT(buf.pos == 9);
     EXPECT_GE(buf.capacity, 9);
     EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0a", 9), 0);
 }
 
 TEST_F(BufferWrite, PutStringWrapperFit) {
     const char *data = "test";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferPutString(&buf, data);
-    EXPECT_EQ(written, 4);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_EQ(buf.pos, 8);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(written == 4);
+    CX_TEST_ASSERT(buf.size == 8);
+    CX_TEST_ASSERT(buf.pos == 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
 }
 
 TEST_F(BufferWrite, PutStringWrapperDiscard) {
     const char *data = "testing";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferPutString(&buf, data);
-    EXPECT_EQ(written, 4);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_EQ(buf.pos, 8);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(written == 4);
+    CX_TEST_ASSERT(buf.size == 8);
+    CX_TEST_ASSERT(buf.pos == 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
 }
 
 TEST_F(BufferWrite, PutStringWrapperExtend) {
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
     const char *data = "testing";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferPutString(&buf, data);
-    EXPECT_EQ(written, 7);
-    EXPECT_EQ(buf.size, 11);
-    EXPECT_EQ(buf.pos, 11);
+    CX_TEST_ASSERT(written == 7);
+    CX_TEST_ASSERT(buf.size == 11);
+    CX_TEST_ASSERT(buf.pos == 11);
     EXPECT_GE(buf.capacity, 11);
     EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
 }
 
 TEST_F(BufferWrite, MultOverflow) {
     const char *data = "testing";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf);
-    EXPECT_EQ(written, 0);
-    EXPECT_EQ(buf.capacity, 8);
-    EXPECT_EQ(buf.pos, 4);
-    EXPECT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(written == 0);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
 }
 
 TEST_F(BufferWrite, MaxCapaOverflow) {
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
     const char *data = "testing";
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
-    ASSERT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf);
-    EXPECT_EQ(written, 0);
-    EXPECT_EQ(buf.capacity, 8);
-    EXPECT_EQ(buf.pos, 4);
-    EXPECT_EQ(buf.size, 4);
+    CX_TEST_ASSERT(written == 0);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
+    CX_TEST_ASSERT(buf.size == 4);
     EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
 }
 
 TEST_F(BufferWrite, OnlyOverwrite) {
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
-    ASSERT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(buf.capacity == 8);
     memcpy(buf.space, "preptest", 8);
     buf.pos = 3;
     buf.size = 8;
     size_t written = cxBufferWrite("XXX", 2, 2, &buf);
-    EXPECT_EQ(written, 2);
-    EXPECT_EQ(buf.capacity, 8);
-    EXPECT_EQ(buf.size, 8);
-    EXPECT_EQ(buf.pos, 7);
+    CX_TEST_ASSERT(written == 2);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.size == 8);
+    CX_TEST_ASSERT(buf.pos == 7);
     EXPECT_EQ(memcmp(buf.space, "preXXX\0t", 8), 0);
 }
 
 TEST_F(BufferWrite, FlushAtCapacity) {
     enableFlushing();
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
     size_t written = cxBufferWrite("foo", 1, 3, &buf);
-    EXPECT_EQ(written, 3);
-    ASSERT_EQ(buf.pos, 7);
-    ASSERT_EQ(buf.size, 7);
-    ASSERT_EQ(target.pos, 0);
-    ASSERT_EQ(target.size, 0);
+    CX_TEST_ASSERT(written == 3);
+    CX_TEST_ASSERT(buf.pos == 7);
+    CX_TEST_ASSERT(buf.size == 7);
+    CX_TEST_ASSERT(target.pos == 0);
+    CX_TEST_ASSERT(target.size == 0);
     written = cxBufferWrite("hello", 1, 5, &buf);
-    EXPECT_EQ(written, 5);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 0);
-    EXPECT_EQ(buf.capacity, 8);
-    EXPECT_EQ(target.pos, 12);
-    ASSERT_EQ(target.size, 12);
+    CX_TEST_ASSERT(written == 5);
+    CX_TEST_ASSERT(buf.pos == 0);
+    CX_TEST_ASSERT(buf.size == 0);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(target.pos == 12);
+    CX_TEST_ASSERT(target.size == 12);
     EXPECT_EQ(memcmp(target.space, "prepfoohello", 12), 0);
 }
 
@@ -624,23 +460,23 @@
     enableFlushing();
     buf.flush_threshold = 12;
     buf.flags |= CX_BUFFER_AUTO_EXTEND;
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
     size_t written = cxBufferWrite("foobar", 1, 6, &buf);
-    EXPECT_EQ(written, 6);
-    ASSERT_EQ(buf.pos, 10);
-    ASSERT_EQ(buf.size, 10);
+    CX_TEST_ASSERT(written == 6);
+    CX_TEST_ASSERT(buf.pos == 10);
+    CX_TEST_ASSERT(buf.size == 10);
     ASSERT_GE(buf.capacity, 10);
     ASSERT_LE(buf.capacity, 12);
-    ASSERT_EQ(target.pos, 0);
-    ASSERT_EQ(target.size, 0);
+    CX_TEST_ASSERT(target.pos == 0);
+    CX_TEST_ASSERT(target.size == 0);
     written = cxBufferWrite("hello", 1, 5, &buf);
-    EXPECT_EQ(written, 5);
-    EXPECT_EQ(buf.pos, 0);
-    EXPECT_EQ(buf.size, 0);
+    CX_TEST_ASSERT(written == 5);
+    CX_TEST_ASSERT(buf.pos == 0);
+    CX_TEST_ASSERT(buf.size == 0);
     EXPECT_LE(buf.capacity, 12);
-    EXPECT_EQ(target.pos, 15);
-    ASSERT_EQ(target.size, 15);
+    CX_TEST_ASSERT(target.pos == 15);
+    CX_TEST_ASSERT(target.size == 15);
     EXPECT_EQ(memcmp(target.space, "prepfoobarhello", 15), 0);
 }
 
@@ -650,133 +486,43 @@
     target.capacity = 16;
     target.flags &= ~CX_BUFFER_AUTO_EXTEND;
     buf.flush_func = (cx_write_func) mock_write_limited_rate;
-    ASSERT_EQ(buf.capacity, 8);
-    ASSERT_EQ(buf.pos, 4);
+    CX_TEST_ASSERT(buf.capacity == 8);
+    CX_TEST_ASSERT(buf.pos == 4);
     size_t written = cxBufferWrite("foo", 1, 3, &buf);
-    EXPECT_EQ(written, 3);
-    ASSERT_EQ(buf.pos, 7);
-    ASSERT_EQ(buf.size, 7);
-    ASSERT_EQ(target.pos, 0);
-    ASSERT_EQ(target.size, 0);
+    CX_TEST_ASSERT(written == 3);
+    CX_TEST_ASSERT(buf.pos == 7);
+    CX_TEST_ASSERT(buf.size == 7);
+    CX_TEST_ASSERT(target.pos == 0);
+    CX_TEST_ASSERT(target.size == 0);
     written = cxBufferWrite("hello, world!", 1, 13, &buf);
     // " world!" fits into this buffer, the remaining stuff is flushed out
-    EXPECT_EQ(written, 13);
-    EXPECT_EQ(buf.pos, 7);
-    EXPECT_EQ(buf.size, 7);
-    EXPECT_EQ(buf.capacity, 8);
+    CX_TEST_ASSERT(written == 13);
+    CX_TEST_ASSERT(buf.pos == 7);
+    CX_TEST_ASSERT(buf.size == 7);
+    CX_TEST_ASSERT(buf.capacity == 8);
     EXPECT_EQ(memcmp(buf.space, " world!", 7), 0);
-    EXPECT_EQ(target.pos, 13);
-    ASSERT_EQ(target.size, 13);
-    EXPECT_EQ(target.capacity, 16);
+    CX_TEST_ASSERT(target.pos == 13);
+    CX_TEST_ASSERT(target.size == 13);
+    CX_TEST_ASSERT(target.capacity == 16);
     EXPECT_EQ(memcmp(target.space, "prepfoohello,", 13), 0);
 }
 
-class BufferSeek : public BufferFixture {
-};
-
-TEST_F(BufferSeek, SetZero) {
-    int result = cxBufferSeek(&buf, 0, SEEK_SET);
-    EXPECT_EQ(result, 0);
-    EXPECT_EQ(buf.pos, 0);
-}
-
-TEST_F(BufferSeek, SetValid) {
-    int result = cxBufferSeek(&buf, 5, SEEK_SET);
-    EXPECT_EQ(result, 0);
-    EXPECT_EQ(buf.pos, 5);
-}
-
-TEST_F(BufferSeek, SetInvalid) {
-    ASSERT_EQ(buf.pos, 3);
-    int result = cxBufferSeek(&buf, 6, SEEK_SET);
-    EXPECT_NE(result, 0);
-    EXPECT_EQ(buf.pos, 3);
-}
-
-TEST_F(BufferSeek, CurZero) {
-    ASSERT_EQ(buf.pos, 3);
-    int result = cxBufferSeek(&buf, 0, SEEK_CUR);
-    EXPECT_EQ(result, 0);
-    EXPECT_EQ(buf.pos, 3);
-}
-
-TEST_F(BufferSeek, CurValidPositive) {
-    ASSERT_EQ(buf.pos, 3);
-    int result = cxBufferSeek(&buf, 2, SEEK_CUR);
-    EXPECT_EQ(result, 0);
-    EXPECT_EQ(buf.pos, 5);
-}
-
-TEST_F(BufferSeek, CurValidNegative) {
-    ASSERT_EQ(buf.pos, 3);
-    int result = cxBufferSeek(&buf, -3, SEEK_CUR);
-    EXPECT_EQ(result, 0);
-    EXPECT_EQ(buf.pos, 0);
-}
-
-TEST_F(BufferSeek, CurInvalidPositive) {
-    ASSERT_EQ(buf.pos, 3);
-    int result = cxBufferSeek(&buf, 3, SEEK_CUR);
-    EXPECT_NE(result, 0);
-    EXPECT_EQ(buf.pos, 3);
-}
-
-TEST_F(BufferSeek, CurInvalidNegative) {
-    ASSERT_EQ(buf.pos, 3);
-    int result = cxBufferSeek(&buf, -4, SEEK_CUR);
-    EXPECT_NE(result, 0);
-    EXPECT_EQ(buf.pos, 3);
-}
-
-TEST_F(BufferSeek, EndZero) {
-    ASSERT_EQ(buf.size, 6);
-    int result = cxBufferSeek(&buf, 0, SEEK_END);
-    // the (past-the-)end position is always invalid
-    EXPECT_NE(result, 0);
-    EXPECT_EQ(buf.pos, 3);
-}
-
-TEST_F(BufferSeek, EndValid) {
-    ASSERT_EQ(buf.size, 6);
-    int result = cxBufferSeek(&buf, -6, SEEK_END);
-    EXPECT_EQ(result, 0);
-    EXPECT_EQ(buf.pos, 0);
-}
-
-TEST_F(BufferSeek, EndInvalid) {
-    ASSERT_EQ(buf.size, 6);
-    int result = cxBufferSeek(&buf, 1, SEEK_END);
-    EXPECT_NE(result, 0);
-    EXPECT_EQ(buf.pos, 3);
-}
-
-TEST_F(BufferSeek, WhenceInvalid) {
-    ASSERT_EQ(buf.size, 6);
-    ASSERT_EQ(buf.pos, 3);
-    int result = cxBufferSeek(&buf, 2, 9000);
-    EXPECT_NE(result, 0);
-    EXPECT_EQ(buf.size, 6);
-    EXPECT_EQ(buf.pos, 3);
-}
-
-class BufferEof : public BufferFixture {
-};
 
 TEST_F(BufferEof, Reached) {
     buf.pos = buf.size;
-    EXPECT_TRUE(cxBufferEof(&buf));
+    CX_TEST_ASSERT(cxBufferEof(&buf));
     buf.pos = buf.size - 1;
-    ASSERT_FALSE(cxBufferEof(&buf));
+    CX_TEST_ASSERT(!cxBufferEof(&buf));
     cxBufferPut(&buf, 'a');
-    EXPECT_TRUE(cxBufferEof(&buf));
+    CX_TEST_ASSERT(cxBufferEof(&buf));
 }
 
 TEST_F(BufferEof, NotReached) {
     buf.pos = buf.size - 1;
-    EXPECT_FALSE(cxBufferEof(&buf));
+    CX_TEST_ASSERT(!cxBufferEof(&buf));
     buf.pos = 0;
     cxBufferWrite("test", 1, 5, &buf);
-    EXPECT_FALSE(cxBufferEof(&buf));
+    CX_TEST_ASSERT(!cxBufferEof(&buf));
 }
 
 class BufferRead : public ::testing::Test {
@@ -784,7 +530,7 @@
     CxBuffer buf{};
 
     void SetUp() override {
-        cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+        cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
         buf.capacity = 8; // artificially reduce capacity to check OOB writes
         memset(buf.space, 0, 16);
         memcpy(buf.space, "some data", 9);
@@ -802,7 +548,7 @@
     EXPECT_EQ(cxBufferGet(&buf), 'e');
     EXPECT_EQ(cxBufferGet(&buf), ' ');
     EXPECT_EQ(cxBufferGet(&buf), 'd');
-    EXPECT_EQ(buf.pos, 6);
+    CX_TEST_ASSERT(buf.pos == 6);
 }
 
 TEST_F(BufferRead, GetEof) {
@@ -814,18 +560,18 @@
     buf.pos = 2;
     char target[4];
     auto read = cxBufferRead(&target, 1, 4, &buf);
-    ASSERT_EQ(read, 4);
+    CX_TEST_ASSERT(read == 4);
     EXPECT_EQ(memcmp(&target, "me d", 4), 0);
-    EXPECT_EQ(buf.pos, 6);
+    CX_TEST_ASSERT(buf.pos == 6);
 }
 
 TEST_F(BufferRead, ReadOutOfBounds) {
     buf.pos = 6;
     char target[4];
     auto read = cxBufferRead(&target, 1, 4, &buf);
-    ASSERT_EQ(read, 3);
+    CX_TEST_ASSERT(read == 3);
     EXPECT_EQ(memcmp(&target, "ata", 3), 0);
-    EXPECT_EQ(buf.pos, 9);
+    CX_TEST_ASSERT(buf.pos == 9);
 }
 
 TEST_F(BufferRead, ReadOutOfBoundsMultibyte) {
@@ -833,15 +579,15 @@
     char target[4];
     target[2] = '\0';
     auto read = cxBufferRead(&target, 2, 2, &buf);
-    ASSERT_EQ(read, 1);
+    CX_TEST_ASSERT(read == 1);
     EXPECT_EQ(memcmp(&target, "at\0", 3), 0);
-    EXPECT_EQ(buf.pos, 8);
+    CX_TEST_ASSERT(buf.pos == 8);
 }
 
 TEST_F(BufferRead, ReadEof) {
     buf.pos = 9;
     char target[4];
     auto read = cxBufferRead(&target, 1, 1, &buf);
-    ASSERT_EQ(read, 0);
-    EXPECT_EQ(buf.pos, 9);
+    CX_TEST_ASSERT(read == 0);
+    CX_TEST_ASSERT(buf.pos == 9);
 }
--- a/tests/ucxtest.c	Mon Jan 01 15:33:20 2024 +0100
+++ b/tests/ucxtest.c	Mon Jan 01 16:42:37 2024 +0100
@@ -34,6 +34,7 @@
 CxTestSuite *cx_test_suite_hash_key(void);
 CxTestSuite *cx_test_suite_allocator(void);
 CxTestSuite *cx_test_suite_string(void);
+CxTestSuite *cx_test_suite_buffer(void);
 CxTestSuite *cx_test_suite_printf(void);
 CxTestSuite *cx_test_suite_mempool(void);
 CxTestSuite *cx_test_suite_hash_map(void);
@@ -53,6 +54,7 @@
             cx_test_suite_hash_key(),
             cx_test_suite_allocator(),
             cx_test_suite_string(),
+            cx_test_suite_buffer(),
             cx_test_suite_printf(),
             cx_test_suite_mempool(),
             cx_test_suite_hash_map()

mercurial