#ifndef TEST_HARNESS_H_ #define TEST_HARNESS_H_ #include #include #define YELLOW "\x1b[00;33m" #define GREEN "\x1b[01;32m" #define RED "\x1b[01;31m" #define RESET "\x1b[0m" typedef struct { const char* test_suite; const char* test_name; int (*fn_ptr)(); void* alignment; } test_t; #define GENPR(fmt, v1, v2) \ fprintf(stderr, fmt "\n", v1, v2) #define FORMAT_STRING(v1, v2) \ fprintf( \ stderr, \ _Generic((v1), long: "%ld == %ld\n", \ unsigned long: "%lu == %lu\n", \ int: "%d == %d\n", \ unsigned int: "%u == %u\n", \ short: "%hu == %hu\n", \ unsigned short: "%hu == %hu\n", \ char: "%c == %c\n", \ double: "%f == %f\n", \ default: "%p == %p\n"), \ (v1), (v2)); \ #define TRY_PRINT_TYPE(v1, v2, type, fmt) \ else if (__builtin_types_compatible_p(typeof (v1), type)) { \ fprintf(stderr, fmt " == " fmt "\n", v1, v2); \ } #define TYPE_STR(t) #t #define ASSERT_TRUE(x) \ do { \ if (!(x)) { \ fprintf(stderr, RED "ASSERT_TRUE FAILED!\n" RESET); \ fprintf(stderr, " - " YELLOW "In expression ASSERT_TRUE(" #x ")\n"); \ fprintf(stderr, RESET " - " YELLOW "At " __FILE__ ":%d\n" RESET, __LINE__); \ test_harness_abort(1); \ } \ } while (0) #define ASSERT_EQ(x, y) \ do { \ if ((x) != (y)) { \ fprintf(stderr, RED "ASSERT_EQ FAILED! " RESET "Not true that "); \ FORMAT_STRING(x, y); \ fprintf(stderr, " - " YELLOW "In expression ASSERT_EQ(" #x ", " #y ")\n"); \ fprintf(stderr, RESET " - " YELLOW "At " __FILE__ ":%d\n" RESET, __LINE__); \ test_harness_abort(1); \ } \ } while (0) #define ASSERT_EQ_STR(x, y) \ do { \ if (strcmp(x, y)) { \ fprintf(stderr, \ RED "ASSSERT_EQ_STR FAILED! " RESET "Not true that \"%s\" equals \"%s\"", \ x, y); \ fprintf(stderr, " - " YELLOW "In expression ASSERT_EQ_STR(" #x ", " #y ")\n"); \ fprintf(stderr, RESET " - " YELLOW "At " __FILE__":%d\n" RESET, __LINE__); \ test_harness_abort(1); \ } \ } while (0) #define TEST(test_suite, test_name) \ int test_suite ## _ ## test_name ## _fn (void); \ volatile test_t test_suite ## _ ## test_name ## _testing_struct__ \ __attribute((__section__("tests"))) __attribute((__used__)) = \ {#test_suite, #test_name, test_suite ## _ ## test_name ## _fn}; \ int test_suite ## _ ## test_name ## _fn (void) void test_harness_abort(int ec); #endif