-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiunte.h
113 lines (105 loc) · 6.55 KB
/
miunte.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
#ifndef MIUNTE_H
#define MIUNTE_H
#include <stdio.h>
#ifndef MIUNTE_STOP_ON_FAILURE
# define MIUNTE_STOP_ON_FAILURE (0)
#endif
// #if (!defined MIUNTE_TA_PASSED && !defined MIUNTE_TA_FAILED && !defined
// MIUNTE_TA_CLEAR)
#ifdef MIUNTE_NO_TA
# define MIUNTE_TA_PASSED ""
# define MIUNTE_TA_FAILED ""
# define MILO_TA_CLEAR ""
#else
# define MIUNTE_TA_PASSED "\033[0;32m"
# define MIUNTE_TA_FAILED "\033[0;31m"
# define MIUNTE_TA_CLEAR "\033[0m"
#endif
// #endif
typedef struct MiunteResult {
char const *const fn_name;
char const *const err_msg;
} MiunteResult;
typedef MiunteResult (*MiunteTest)(void);
/// @brief Runs all tests, surrounding with `setup` and `teardown`.
/// @param setup function to call before every test
/// @param setup function to call after every test
/// @param ... tests themselves
#define MIUNTE_RUN(setup, teardown, ...) \
{ \
MiunteTest const _setup = (setup), _teardown = (teardown); \
\
MiunteTest const tests[] = __VA_ARGS__; \
size_t const test_count = sizeof(tests) / sizeof(*tests); \
\
int main_result = 0; \
for (MiunteTest const *test = tests; test < tests + test_count; \
test++) { \
if (_setup != NULL) { \
MiunteResult const result = _setup(); \
if (result.err_msg != NULL) { \
printf( \
"%s " MIUNTE_TA_FAILED "failed: %s" MIUNTE_TA_CLEAR \
"\n", \
result.fn_name, \
result.err_msg \
); \
return 1; \
} \
} \
{ \
MiunteResult const result = (*test)(); \
if (result.err_msg != NULL) { \
printf( \
"%s " MIUNTE_TA_FAILED "failed: %s" MIUNTE_TA_CLEAR \
"\n", \
result.fn_name, \
result.err_msg \
); \
if (MIUNTE_STOP_ON_FAILURE) { \
return 1; \
} else { \
main_result = 1; \
} \
} else { \
printf( \
"%s " MIUNTE_TA_PASSED "passed!" MIUNTE_TA_CLEAR "\n", \
result.fn_name \
); \
} \
} \
if (_teardown != NULL) { \
MiunteResult const result = _teardown(); \
if (result.err_msg != NULL) { \
printf( \
"%s " MIUNTE_TA_FAILED "failed: %s" MIUNTE_TA_CLEAR \
"\n", \
result.fn_name, \
result.err_msg \
); \
if (MIUNTE_STOP_ON_FAILURE) { \
return 1; \
} else { \
main_result = 1; \
} \
} \
} \
} \
\
return main_result; \
} \
((void)0)
/// @brief Test `cond`, if false, mark test as failed with `message`.
/// @param cond condition to test
/// @param message
#define MIUNTE_EXPECT(cond, message) \
{ \
if (!(cond)) \
return (MiunteResult){.fn_name = __func__, .err_msg = (message)}; \
} \
((void)0)
// @brief Mark test as passed.
#define MIUNTE_PASS() \
{ return (MiunteResult){.fn_name = __func__}; } \
((void)0)
#endif