ihct
(I Hate C Testing)
ihct.h
1 #ifndef IHCT_H
2 #define IHCT_H
3 
4 #include <stdbool.h>
5 #include <stdlib.h>
6 #include <string.h>
7 
8 // Structure for a testunits return value. Contains state, the code (assert) which
9 // failed the test, and a reference to where the code is.
10 typedef struct {
11  enum {PASS, FAIL, FAIL_FORCE, ERR, TIMEOUT} status;
12  char *code;
13  char *file;
14  unsigned long line;
16 
17 // Short for a function returning a test_result pointer, with no arguments.
18 typedef void (*ihct_test_proc)(ihct_test_result *);
19 
20 // Called within a test.
21 bool ihct_assert_impl(bool eval, ihct_test_result *result, char *code, char *file,
22  unsigned long line);
23 
24 void ihct_pass_impl(ihct_test_result *result, char *file, unsigned long line);
25 void ihct_fail_impl(ihct_test_result *result, char *file, unsigned long line);
26 
27 // Called on test unit construction.
28 void ihct_construct_test_impl(char *s, ihct_test_proc proc);
29 
30 // Runs all tests.
31 int ihct_run(int argc, char **argv);
32 
33 // Initializes the unitlist (Has to be done before all testing units are created).
34 // Using priority to ensure that the unit list is constructed before it gets populated.
35 void ihct_init(void) __attribute__((constructor(101)));
36 
37 // Assertions
43 
50 #define IHCT_ASSERT(expr) \
51  if(!ihct_assert_impl(expr, result, #expr, __FILE__, __LINE__)) return
52 
59 #define IHCT_NASSERT(expr) \
60  if(!ihct_assert_impl(!expr, result, "!(" #expr ")", __FILE__, __LINE__)) return
61 
69 #define IHCT_ASSERT_STR(s1, s2) \
70  if(!ihct_assert_impl(!strcmp(s1, s2), result, #s1 " == " #s2, __FILE__, \
71  __LINE__)) return
79 #define IHCT_NASSERT_STR(s1, s2) \
80  if(!ihct_assert_impl(strcmp(s1, s2), result, #s1 " != " #s2, __FILE__, \
81  __LINE__)) return
82 
88 #define IHCT_PASS() \
89  do { ihct_pass_impl(result, __FILE__, __LINE__); return; } while(0)
90 
96 #define IHCT_FAIL() \
97  do { ihct_fail_impl(result, __FILE__, __LINE__); return; } while(0)
98 
99 // Function macros
102 
112 #define IHCT_RUN(argc, argv) \
113  ihct_run(argc, argv)
114 
115 // Create a new test unit, and adds it using 'ihct_add_test'.
126 #define IHCT_TEST(name) \
127  static void test_##name(ihct_test_result *result); \
128  static void __attribute__((constructor(102))) __construct_test_##name(void) { \
129  ihct_construct_test_impl(#name, &test_##name); \
130  } \
131  static void test_##name(ihct_test_result *result)
132 
135 #define IHCT_FIXTURE(name) _Static_assert(0, "Fixtures not implemented.")
136 
139 #define IHCT_REQUIRE(...) _Static_assert(0, "Fixture requirements not implemented.")
140 
141 #ifdef IHCT_SHORT
142 #define TEST(name) IHCT_TEST(name)
143 #define ASSERT(expr) IHCT_ASSERT(expr)
144 #define NASSERT(expr) IHCT_NASSERT(expr)
145 #define ASSERT_STR(s1, s2) IHCT_ASSERT_STR(s1, s2)
146 #define NASSERT_STR(s1, s2) IHCT_NASSERT_STR(s1, s2)
147 #define PASS() IHCT_PASS()
148 #define FAIL() IHCT_FAIL()
149 #endif
150 
151 #endif
Definition: ihct.h:10