diff options
Diffstat (limited to 'lily-test.h')
-rw-r--r-- | lily-test.h | 81 |
1 files changed, 74 insertions, 7 deletions
diff --git a/lily-test.h b/lily-test.h index c9ae02d..1bc4e74 100644 --- a/lily-test.h +++ b/lily-test.h @@ -55,6 +55,7 @@ #include <setjmp.h> #include <stdio.h> #include <stdarg.h> +#include <stdlib.h> #define STR_IMP(x) #x #define STR(x) STR_IMP(x) @@ -89,7 +90,10 @@ typedef struct lily_ll_node_t { void (*f)(); } lily_ll_node_t; #define LILY_FILE_BEGIN(unique_id) \ -static lily_ll_node_t lily_ll_last = { NULL, NULL }; +static lily_ll_node_t lily_ll_last = { NULL, NULL }; \ +static void file_runner(); \ +void (*unique_id)() = file_runner; + #define LILY_LIST_HEAD lily_ll_last #define LILY_LIST_NEXT lily_ll_last #define LILY_PUSH_TEST() LILY_TEST_H_LOCATION @@ -98,15 +102,21 @@ static lily_ll_node_t lily_ll_last = { NULL, NULL }; #define LILY_CAT_(x, y) x##y #define LILY_CAT(x, y) LILY_CAT_(x, y) #define LILY_ANON(x) LILY_CAT(x, LILY_COUNTER) +#define LILY_ANON_WRAP LILY_ANON(LILY_WRAP_) #define LILY_ANON_FUNC LILY_ANON(LILY_FUNCTION_) #define LILY_ANON_NODE LILY_ANON(LILY_NODE_) #define LILY_ANON_DESC LILY_ANON(LILY_DESCRIPTION_) -#define LILY_TEST_(f, desc_str, description) \ -static const char * const desc_str = description; \ +#define LILY_TEST_(wrap, f, desc_str, description) \ +static void f(); \ +static void wrap() \ +{ \ + lily_g.test_name = description; \ + f(); \ +} \ static void f() -#define LILY_TEST(description) LILY_TEST_(LILY_ANON_FUNC, LILY_ANON_DESC, description) +#define LILY_TEST(description) LILY_TEST_(LILY_ANON_WRAP, LILY_ANON_FUNC, LILY_ANON_DESC, description) /* assertions */ typedef struct lily_test_msg_t { @@ -124,23 +134,36 @@ void lily_info(const char *location, const char *fmt, ...); void lily_check(int x, const char *location, const char *fmt, ...); #define LILY_CHECK_(str, x, location) \ - lily_check(x, location, "%s", str) + lily_check(x, location, "CHECK failed: %s", str) #define LILY_CHECK(x) LILY_CHECK_(STR(x), x, LILY_LOCATION) #define CHECK(x) LILY_CHECK(x) +#define LILY_CHECK_EQ_(test, location, fmt, x, y, xstr, ystr) \ + lily_check(test, location, "CHECK failed: %s == %s (" fmt " == " fmt ")", xstr, ystr, x, y) +#define LILY_CHECK_EQ(x, y, xstr, ystr, fmt) LILY_CHECK_EQ_(x == y, LILY_LOCATION, fmt, x, y, xstr, ystr) +#define CHECK_EQ(x, y, fmt) LILY_CHECK_EQ(x, y, #x, #y, fmt) + void lily_require(int x, const char *location, const char *fmt, ...); #define LILY_REQUIRE_(str, x, location) \ - lily_require(x, location, "%s", str) + lily_require(x, location, "REQUIRE failed: %s", str) #define LILY_REQUIRE(x) LILY_REQUIRE_(STR(x), x, LILY_LOCATION) #define REQUIRE(x) LILY_REQUIRE(x) +void lily_run_test(void (*test)()); + + struct lily_global_t { int failed; jmp_buf env; + const char *test_name; lily_test_msg_t HEAD; lily_test_msg_t *TAIL; + int n_assertions; + int n_assertions_failed; + int n_tests; + int n_tests_failed; } extern lily_g; #ifdef LILY_IMPLEMENTATION @@ -172,6 +195,11 @@ lily_test_msg_t *lily_msg_create(const char *location, const char *fmt, va_list void lily_msg_destroy(lily_test_msg_t *m) { + if (m == NULL) { + /* ignore */ + return; + } + if (m->next != NULL) { // destroy the whole chain lily_msg_destroy(m->next); @@ -182,6 +210,31 @@ void lily_msg_destroy(lily_test_msg_t *m) } +void lily_run_test(void (*test)()) +{ + lily_g.n_tests += 1; + lily_g.HEAD.next = NULL; + lily_g.TAIL = &(lily_g.HEAD); + lily_g.failed = 0; + int jumped = setjmp(lily_g.env); + + if (!jumped) { + test(); + } + + if (lily_g.failed) { + printf("================================================================================\n\n"); + printf("test \"%s\" failed!\n\n", lily_g.test_name); + lily_test_msg_t *n = lily_g.HEAD.next; + while(n != NULL) { + printf(" %s\n [%s]\n\n", n->msg, n->location); + n = n->next; + } + lily_msg_destroy(lily_g.HEAD.next); + } +} + + void lily_info(const char *location, const char *fmt, ...) { va_list args; @@ -195,8 +248,11 @@ void lily_info(const char *location, const char *fmt, ...) void lily_check(int x, const char *location, const char *fmt, ...) { + lily_g.n_assertions += 1; if (!x) { // assertion failed + lily_g.n_assertions_failed += 1; + va_list args; va_start(args, fmt); lily_test_msg_t *m = lily_msg_create(location, fmt, args); @@ -211,8 +267,11 @@ void lily_check(int x, const char *location, const char *fmt, ...) void lily_require(int x, const char *location, const char *fmt, ...) { + lily_g.n_assertions += 1; if (!x) { // assertion failed + lily_g.n_assertions_failed += 1; + va_list args; va_start(args, fmt); lily_test_msg_t *m = lily_msg_create(location, fmt, args); @@ -548,6 +607,14 @@ void lily_require(int x, const char *location, const char *fmt, ...) #define LILY_COUNTER_DECREMENT #include LILY_TEST_H_LOCATION +void file_runner() +{ + lily_ll_node_t *n = &LILY_LIST_HEAD; + while (n->next != NULL) { + lily_run_test(n->f); + n = n->next; + } +} #else /* register new test */ @@ -558,7 +625,7 @@ static lily_ll_node_t LILY_ANON_NODE = { &LILY_LIST_HEAD, #define LILY_COUNTER_INCREMENT #include LILY_TEST_H_LOCATION - LILY_ANON_FUNC, + LILY_ANON_WRAP, }; #undef LILY_LIST_HEAD #define LILY_LIST_HEAD LILY_ANON_NODE |