aboutsummaryrefslogtreecommitdiff
path: root/include/kpl_test.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/kpl_test.h')
-rw-r--r--include/kpl_test.h69
1 files changed, 69 insertions, 0 deletions
diff --git a/include/kpl_test.h b/include/kpl_test.h
new file mode 100644
index 0000000..a656761
--- /dev/null
+++ b/include/kpl_test.h
@@ -0,0 +1,69 @@
+/*
+ * This is the only header included in any c test file
+ */
+
+#pragma once
+
+#include "kpl.h"
+
+typedef enum : int32_t {
+ KPL_TEST_ERROR_LINE_NUMBER_INIT = -1,
+} kpl_test_enum;
+
+typedef struct _kpl_test kpl_test;
+
+typedef void kpl_test_fn(__attribute__((unused)) kpl_test *_test);
+
+/*
+ * The kpl_test object is used to build a static singly linked list and a static tree
+ * The list is for running all tests and moving failed tests to an error linked list
+ * The tree is used for running tests by name
+ */
+typedef struct _kpl_test {
+ KPL_TREE_HEADER(_kpl_test);
+ int32_t error_line_number; // -1 line number for no error
+ struct _kpl_test *list_next;
+ const char *source_file, *name, *error_message; // static c strings only
+ kpl_test_fn *test_fn;
+} kpl_test; // Per test object, lists and trees are globals
+
+void _kpl_test_add(kpl_test *_test); // do not call outside KPL_TEST macro
+
+#define _KPL_TEST_FN_DEFINITION(NAME) static void NAME(__attribute__((unused)) kpl_test *_test)
+
+/*
+ * Each test is a static function added to the test list and tree by a static gnu constructor function
+ * The NAME becomes the function name _NAME becomes the constructor name, only one name can be used per file
+ */
+#define KPL_TEST(NAME) _KPL_TEST_FN_DEFINITION(NAME); \
+static void __attribute__((constructor)) _ ## NAME(void) { \
+ static kpl_test _test = { \
+ .tree_left = NULL, .tree_right = NULL, .tree_duplicate = NULL, \
+ .tree_height = KPL_TREE_TREE_HEIGHT_INIT, \
+ .error_line_number = KPL_TEST_ERROR_LINE_NUMBER_INIT, \
+ .list_next = NULL, \
+ .source_file = __FILE__, .name = #NAME, .error_message = NULL, \
+ .test_fn = NAME \
+ }; \
+ _kpl_test_add(&_test); \
+} \
+_KPL_TEST_FN_DEFINITION(NAME)
+
+/*
+ * MESSAGE is a static c string, sets the error fields in a test once, aborting the rest of test
+ * Can only be called within a KPL_TEST
+ */
+#define KPL_FAIL(MESSAGE) do { \
+ _test->error_line_number = __LINE__; \
+ _test->error_message = MESSAGE; \
+ return; \
+} while (0)
+
+/*
+ * CONDITION is statement evaluating to true or false, MESSAGE is a static c string, false invokes KPL_FAIL
+ * Can only be called within KPL_TEST
+ */
+#define KPL_ASSERT(CONDITION, MESSAGE) do { \
+ if (!(CONDITION)) \
+ KPL_FAIL(#CONDITION "; " MESSAGE); \
+} while (0)