#pragma once // KPL testing framework #include "kpl.h" typedef struct _kpl_test kpl_test; typedef void kpl_test_function(__attribute__((unused)) kpl_test *_test); typedef struct _kpl_test { int32_t error_line_number; // -1 for no error char *file_name, *test_name, *error_message; kpl_test_function *test_function; struct _kpl_test *next_test; } kpl_test; void kpl_test_add(kpl_test *_test); #define _KPL_TEST_FN_NAME(NAME) _kpl_test_function_ ## NAME #define _KPL_TEST_FN(NAME) static void _KPL_TEST_FN_NAME(NAME)(__attribute__((unused)) kpl_test *_test) #define KPL_TEST(NAME) _KPL_TEST_FN(NAME); \ static void __attribute__((constructor)) _kpl_test_constructor_ ## NAME(void) { \ static kpl_test _test = { \ .error_line_number = -1, \ .file_name = __FILE__, .test_name = #NAME, .error_message = NULL, \ .test_function = _KPL_TEST_FN_NAME(NAME), \ .next_test = NULL \ }; \ kpl_test_add(&_test); \ } \ _KPL_TEST_FN(NAME) #define _KPL_TEST_FAIL_LINE _test->error_line_number = __LINE__ #define _KPL_TEST_FAIL_MESSAGE(MESSAGE) _test->error_message = MESSAGE #define KPL_FAIL(MESSAGE) do { _KPL_TEST_FAIL_LINE; _KPL_TEST_FAIL_MESSAGE(MESSAGE); } while (0) #define KPL_ASSERT(CONDITION, MESSAGE) do { if (!(CONDITION)) { KPL_FAIL(#CONDITION "; " MESSAGE); } } while (0)