-
Notifications
You must be signed in to change notification settings - Fork 0
/
tctest.h
129 lines (115 loc) · 3.87 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
/*
* TCTest - a tiny unit test framework for C
* Copyright (c) 2013,2019-2020 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) { \
tctest_num_executed++; \
tctest_assertion_line = -1; \
if (sigsetjmp(tctest_env, 1) == 0) { \
TestObjs *t = setup(); \
printf("%s...", #func); \
fflush(stdout); \
func(t); \
cleanup(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); \
} \
} \
} \
} 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 */