From 3d0008b49698d49fa3a7d4c851c93c4092c368bb Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Thu, 24 Oct 2024 12:29:18 +0100 Subject: [PATCH] Write test framework --- scripts/build.sh | 3 +++ tests/testing.c | 21 +++++++++++++++++ tests/testing.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 tests/testing.c create mode 100644 tests/testing.h diff --git a/scripts/build.sh b/scripts/build.sh index e7e86e1..594d166 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -5,6 +5,9 @@ CFLAGS="$CFLAGS -Og -ggdb" mkdir -p build +# Build tests +clang $CFLAGS -Itests -c -o build/testing.o tests/testing.c + # Build application clang $CFLAGS -c -o build/main.o app/main.c clang $CFLAGS -o build/infix-calculator build/main.o diff --git a/tests/testing.c b/tests/testing.c new file mode 100644 index 0000000..d911fb8 --- /dev/null +++ b/tests/testing.c @@ -0,0 +1,21 @@ +#include "testing.h" + +#include + +test_run_t test_run; + +void testing_fail_msg(const char *func, const char *file, int line) +{ + printf("%s: failed assert @ %s:%d\n", func, file, line); +} + +void testing_end_msg(void) +{ + const double success_rate + = 1 - (double)test_run.fail_count / (double)test_run.test_count; + printf( + "%d tests ran (%d assertions), " + "%0.2f%% successful (%d failures)\n", + test_run.test_count, test_run.assertion_count, 100 * success_rate, + test_run.fail_count); +} diff --git a/tests/testing.h b/tests/testing.h new file mode 100644 index 0000000..8e66d9b --- /dev/null +++ b/tests/testing.h @@ -0,0 +1,60 @@ +#ifndef TESTING_H +#define TESTING_H + +#include +#include + +#define TESTING_BEGIN() \ + do { \ + memset(&test_run, 0, sizeof(test_run)); \ + } while (0) + +#define TESTING_END() \ + do { \ + testing_end_msg(); \ + return 0 == test_run.fail_count ? EXIT_SUCCESS : EXIT_FAILURE; \ + } while (0) + +#define RUN_TEST(test) \ + do { \ + ++test_run.test_count; \ + test(); \ + } while (0) + +#define ASSERT_FAIL() \ + do { \ + ++test_run.fail_count; \ + testing_fail_msg(__func__, __FILE__, __LINE__); \ + return; \ + } while (0) + +#define ASSERT_TRUE(p) \ + do { \ + ++test_run.assertion_count; \ + if (!(p)) \ + ASSERT_FAIL(); \ + } while (0) + +#define ASSERT_FALSE(p) ASSERT_TRUE(!(p)) +#define ASSERT_EQUAL(x, y) ASSERT_TRUE((x) == (y)) +#define ASSERT_NOT_EQUAL(x, y) ASSERT_TRUE((x) != (y)) +#define ASSERT_NULL(p) ASSERT_TRUE(NULL == (p)) +#define ASSERT_NOT_NULL(p) ASSERT_TRUE(NULL != (p)) +#define ASSERT_GT(x, y) ASSERT_TRUE((y) > (x)) +#define ASSERT_GE(x, y) ASSERT_TRUE((y) >= (x)) +#define ASSERT_LT(x, y) ASSERT_TRUE((y) < (x)) +#define ASSERT_LE(x, y) ASSERT_TRUE((y) <= (x)) +#define ASSERT_MEM_EQUAL(p, q, n) ASSERT_TRUE(memcmp(p, q, n) == 0) + +typedef struct { + int test_count; + int fail_count; + int assertion_count; +} test_run_t; + +extern test_run_t test_run; + +void testing_fail_msg(const char *func, const char *file, int line); +void testing_end_msg(void); + +#endif