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 #ifndef UCX_TEST_H
68 #define UCX_TEST_H
69
70 #include <stdlib.h>
71 #include <stdio.h>
72 #include <string.h>
73 #include <setjmp.h>
74
75 #ifdef __cplusplus
76 extern "C" {
77 #endif
78
79 #ifndef __FUNCTION__
80
81
82
83
84
85
86 #define __FUNCTION__ __func__
87 #endif
88
89
90 #if !defined(__clang__) &&
__GNUC__ >
3
91 #pragma GCC diagnostic ignored
"-Wclobbered"
92 #endif
93
94 #ifndef UCX_COMMON_H
95
96
97
98 typedef size_t (*cx_write_func)(
99 const void *,
100 size_t,
101 size_t,
102 void *
103 );
104 #endif
105
106
107 typedef struct CxTestSuite CxTestSuite;
108
109
110 typedef void(*CxTest)(CxTestSuite *,
void *, cx_write_func);
111
112
113 typedef struct CxTestSet CxTestSet;
114
115
116 struct CxTestSet {
117
118
119 CxTest test;
120
121
122 CxTestSet *next;
123 };
124
125
126
127
128 struct CxTestSuite {
129
130
131 unsigned int success;
132
133
134 unsigned int failure;
135
136
137 const char *name;
138
139
140
141
142
143 CxTestSet *tests;
144 };
145
146
147
148
149
150
151 static inline CxTestSuite* cx_test_suite_new(
const char *name) {
152 CxTestSuite* suite = (CxTestSuite*) malloc(
sizeof(CxTestSuite));
153 if (suite !=
NULL) {
154 suite->name = name;
155 suite->success =
0;
156 suite->failure =
0;
157 suite->tests =
NULL;
158 }
159
160 return suite;
161 }
162
163
164
165
166
167 static inline
void cx_test_suite_free(CxTestSuite* suite) {
168 CxTestSet *l = suite->tests;
169 while (l !=
NULL) {
170 CxTestSet *e = l;
171 l = l->next;
172 free(e);
173 }
174 free(suite);
175 }
176
177
178
179
180
181
182
183
184 static inline
int cx_test_register(CxTestSuite* suite, CxTest test) {
185 CxTestSet *t = (CxTestSet*) malloc(
sizeof(CxTestSet));
186 if (t) {
187 t->test = test;
188 t->next =
NULL;
189 if (suite->tests ==
NULL) {
190 suite->tests = t;
191 }
else {
192 CxTestSet *last = suite->tests;
193 while (last->next) {
194 last = last->next;
195 }
196 last->next = t;
197 }
198 return 0;
199 }
else {
200 return 1;
201 }
202 }
203
204
205
206
207
208
209
210 static inline
void cx_test_run(CxTestSuite *suite,
211 void *out_target, cx_write_func out_writer) {
212 if (suite->name ==
NULL) {
213 out_writer(
"*** Test Suite ***\n",
1,
19, out_target);
214 }
else {
215 out_writer(
"*** Test Suite : ",
1,
17, out_target);
216 out_writer(suite->name,
1, strlen(suite->name), out_target);
217 out_writer(
" ***\n",
1,
5, out_target);
218 }
219 suite->success =
0;
220 suite->failure =
0;
221 for (CxTestSet *elem = suite->tests; elem; elem = elem->next) {
222 elem->test(suite, out_target, out_writer);
223 }
224 out_writer(
"\nAll test completed.\n",
1,
21, out_target);
225 char total[
80];
226 int len = snprintf(
227 total,
80,
228 " Total: %u\n Success: %u\n Failure: %u\n\n",
229 suite->success + suite->failure, suite->success, suite->failure
230 );
231 out_writer(total,
1, len, out_target);
232 }
233
234
235
236
237
238
239 #define cx_test_run_f(suite, file) cx_test_run(suite, (
void*)file, (cx_write_func)fwrite)
240
241
242
243
244
245 #define cx_test_run_stdout(suite) cx_test_run_f(suite, stdout)
246
247
248
249
250
251
252
253
254 #define CX_TEST(name)
void name(CxTestSuite* _suite_,
void *_output_, cx_write_func _writefnc_)
255
256
257
258
259
260
261 #define CX_TEST_DO _writefnc_(
"Running ",
1,
8, _output_);\
262 _writefnc_(
__FUNCTION__,
1, strlen(
__FUNCTION__), _output_);\
263 _writefnc_(
"... ",
1,
4, _output_);\
264 jmp_buf _env_;\
265 for (
unsigned int _cx_test_loop_ =
0 ;\
266 _cx_test_loop_ ==
0 && !setjmp(_env_);\
267 _writefnc_(
"success.\n",
1,
9, _output_),\
268 _suite_->success++, _cx_test_loop_++)
269
270
271
272
273
274
275
276
277
278 #define CX_TEST_ASSERTM(condition,message)
if (!(condition)) { \
279 const char *_assert_msg_ = message; \
280 _writefnc_(_assert_msg_,
1, strlen(_assert_msg_), _output_); \
281 _writefnc_(
".\n",
1,
2, _output_); \
282 _suite_->failure++; \
283 longjmp(_env_,
1);\
284 } (
void)
0
285
286
287
288
289
290
291
292
293 #define CX_TEST_ASSERT(condition)
CX_TEST_ASSERTM(condition,
#condition " failed")
294
295
296
297
298
299
300
301
302
303
304
305
306 #define CX_TEST_SUBROUTINE(name,...)
void name(CxTestSuite* _suite_,\
307 void *_output_, cx_write_func _writefnc_, jmp_buf _env_,
__VA_ARGS__)
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322 #define CX_TEST_CALL_SUBROUTINE(name,...) \
323 name(_suite_,_output_,_writefnc_,_env_,
__VA_ARGS__)
324
325 #ifdef __cplusplus
326 }
327 #endif
328
329 #endif
330
331