1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#ifndef TEST_HARNESS_H_
#define TEST_HARNESS_H_
#include <stdio.h>
#include <string.h>
#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) \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wpointer-to-int-cast\""); \
_Generic(v1, long: GENPR("%ld == %ld", v1, v2), \
unsigned long: GENPR("%lu == %lu", v1, v2), \
int: GENPR("%d == %d", v1, v2), \
unsigned int: GENPR("%u == %u", v1, v2), \
short: GENPR("%h == %h", v1, v2), \
unsigned short: GENPR("%hu == %hu", v1, v2), \
char: GENPR("%c == %c", v1, v2), \
double: GENPR("%f == %f", v1, v2), \
unsigned char: fprintf( \
stderr, "%02x == %02x\n", (unsigned int) v1, (unsigned int) v2),\
default: GENPR("%p == %p\n", v1, v2)); \
_Pragma("GCC diagnostic pop")
#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
|