-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtctest.h
132 lines (118 loc) · 3.9 KB
/
tctest.h
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* TCTest - a tiny unit test framework for C
* Copyright (c) 2013,2019-2021 David H. Hovemeyer <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef TCTEST_H
#define TCTEST_H
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <signal.h>
#ifdef __cplusplus
extern "C" {
#endif
extern sigjmp_buf tctest_env;
extern int tctest_assertion_line;
extern int tctest_failures;
extern int tctest_num_executed;
void tctest_register_signal_handlers(void);
/*
* Setting this pointer to a non-null value will cause tctest to
* only execute the test with the specified name (which must
* exactly match the name of a test function.) This is useful
* for allowing the test driver to run a single test.
*/
extern const char *tctest_testname_to_execute;
/*
* If this function pointer is set to a non-null value, it will
* be called after a test has been executed. The testname parameter
* is the name of the test function. The passed parameter will
* be true (nonzero) if the test passed, and false (zero) if the
* test did not pass.
*/
extern void (*tctest_on_test_executed)(const char *testname, int passed);
/*
* If this function pointer is set to a non-null value, it will
* be called after all tests have executed. The parameters
* are the number of tests passed and the total number of tests
* executed (respectively.)
*/
extern void (*tctest_on_complete)(int num_passed, int num_executed);
#define TEST_INIT() do { \
tctest_register_signal_handlers(); \
} while (0)
#define TEST(func) do { \
if (!tctest_testname_to_execute || strcmp(tctest_testname_to_execute, #func) == 0) { \
TestObjs *t = 0; \
tctest_num_executed++; \
tctest_assertion_line = -1; \
if (sigsetjmp(tctest_env, 1) == 0) { \
t = setup(); \
printf("%s...", #func); \
fflush(stdout); \
func(t); \
printf("passed!\n"); \
if (tctest_on_test_executed) { \
tctest_on_test_executed(#func, 1); \
} \
} else { \
tctest_failures++; \
if (tctest_on_test_executed) { \
tctest_on_test_executed(#func, 0); \
} \
} \
if (t) { \
cleanup(t); \
} \
} \
} while (0)
#define ASSERT(cond) do { \
tctest_assertion_line = __LINE__; \
if (!(cond)) { \
printf("failed ASSERT %s at line %d\n", #cond, __LINE__); \
siglongjmp(tctest_env, 1); \
} \
} while (0)
/*
* Use this macro to unconditionally fail the current test with
* specified error message. This is somewhat nicer than doing
* ASSERT(0).
*/
#define FAIL(msg) do { \
printf("%s\n", msg); \
siglongjmp(tctest_env, 1); \
} while (0)
#define TEST_FINI() do { \
if (tctest_failures == 0) { \
printf("All tests passed!\n"); \
} else { \
printf("%d test(s) failed\n", tctest_failures); \
} \
if (tctest_on_complete) { \
tctest_on_complete(tctest_num_executed - tctest_failures, tctest_num_executed); \
} \
return tctest_failures > 0; \
} while (0)
#ifdef __cplusplus
}
#endif
#endif /* TCTEST_H */