1 // minunit.h comes from http://www.jera.com/techinfo/jtns/jtn002.html
2 //
3 // You may use the code in this tech note for any purpose,
4 // with the understanding that it comes with NO WARRANTY.
5 
6 #ifndef TERMCOLOR_H
7 #define TERMCOLOR_H
8 
9 #define TRED     "\x1b[31m"
10 #define TGREEN   "\x1b[32m"
11 #define TYELLOW  "\x1b[33m"
12 #define TBLUE    "\x1b[34m"
13 #define TMAGENTA "\x1b[35m"
14 #define TCYAN    "\x1b[36m"
15 #define TBOLD    "\x1b[1m"
16 #define TRESET   "\x1b[0m"
17 #endif
18 
19 #define MU_PASSED 1
20 #define MU_ERR 0
21 
22 #define MU_TEST_UNBROKEN 0
23 #define MU_TEST_BROKEN 1
24 
25 #define MU_BUF_SIZE 5120
26 
snprint_mem(char * out,size_t out_size,const ut8 * buf,size_t len)27 void snprint_mem(char *out, size_t out_size, const ut8 *buf, size_t len) {
28 	size_t i;
29 	*out = '\0';
30 	for (i = 0; i < len; i++) {
31 		size_t out_len;
32 		if (i > 0) {
33 			out_len = strlen (out);
34 			snprintf (out + out_len, out_size - out_len, " ");
35 		}
36 		out_len = strlen (out);
37 		snprintf (out + out_len, out_size - out_len, "%02x", buf[i]);
38 	}
39 }
40 
41 #define mu_assert(message, test) do { \
42 		if (!(test)) { \
43 						mu_fail(message); \
44 						mu_test_status = MU_TEST_UNBROKEN; \
45 					} \
46 		} while (0)
47 
48 #define mu_perror(message) do { \
49 		if (mu_test_status != MU_TEST_BROKEN) { \
50 			printf(TBOLD TRED "ERR\n[XX] Fail at line %d: " TRESET "%s\n\n", __LINE__, message); \
51 		} else { \
52 			printf(TBOLD TYELLOW "Broken at line %d: " TRESET "%s\n\n", __LINE__, message); \
53 		} \
54 	} while (0)
55 
56 #define mu_psyserror(message) do { perror(message); mu_perror(message); } while (0)
57 
58 #define mu_fail(message) do { mu_perror(message); if (mu_test_status != MU_TEST_BROKEN) return MU_ERR; } while(0)
59 
60 #define mu_ignore do { printf(TYELLOW "IGN\n" TRESET); return MU_PASSED; } while(0)
61 
62 #define mu_end do { \
63 		printf(TGREEN "OK\n" TRESET); \
64 		return MU_PASSED; \
65 } while(0)
66 
67 #define mu_cleanup_end do { \
68 		if(retval == MU_PASSED) { mu_end; } \
69 		else { return retval; } \
70 } while(0)
71 
72 #define mu_sysfail(message) do { perror(message); mu_fail(message); } while(0)
73 
74 #define mu_assert_true(actual, message) do { \
75 		bool act__ = (actual); \
76 		if (!(act__)) { \
77 			char _meqstr[MU_BUF_SIZE]; \
78 			snprintf (_meqstr, MU_BUF_SIZE, "%s: expected true, got false", (message)); \
79 			mu_assert (_meqstr, false); \
80 		} \
81 	} while (0)
82 
83 #define mu_assert_false(actual, message) \
84 	do { \
85 		bool act__ = (actual); \
86 		if ((act__)) { \
87 			char _meqstr[MU_BUF_SIZE]; \
88 			snprintf (_meqstr, MU_BUF_SIZE, "%s: expected false, got true", (message)); \
89 			mu_assert (_meqstr, false); \
90 		} \
91 	} while (0)
92 
93 #define mu_assert_eq(actual, expected, message) do { \
94 		ut64 act__ = (ut64)(actual); \
95 		ut64 exp__ = (ut64)(expected); \
96 		if ((exp__) != (act__)) { \
97 			char _meqstr[MU_BUF_SIZE]; \
98 			snprintf (_meqstr, MU_BUF_SIZE, "%s: expected %" PFMT64d ", got %" PFMT64d ".", (message), (ut64)(exp__), (ut64)(act__)); \
99 			mu_assert(_meqstr, false); \
100 		} \
101 	} while(0)
102 
103 #define mu_assert_neq(actual, expected, message) do { \
104 		char _meqstr[MU_BUF_SIZE]; \
105 		ut64 act__ = (ut64)(actual); \
106 		ut64 exp__ = (ut64)(expected); \
107 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected not %" PFMT64d ", got %" PFMT64d ".", (message), (exp__), (act__)); \
108 		mu_assert(_meqstr, (exp__) != (act__)); \
109 	} while(0)
110 
111 #define mu_assert_ptreq(actual, expected, message) do {	\
112 		char _meqstr[MU_BUF_SIZE]; \
113 		const void *act__ = (actual); \
114 		const void *exp__ = (expected); \
115 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected %p, got %p.", (message), (exp__), (act__)); \
116 		mu_assert (_meqstr, (exp__) == (act__)); \
117 	} while (0)
118 
119 #define mu_assert_ptrneq(actual, expected, message) do { \
120 		char _meqstr[MU_BUF_SIZE]; \
121 		const void *act__ = (actual); \
122 		const void *exp__ = (expected); \
123 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected not %p, got %p.", (message), (exp__), (act__)); \
124 		mu_assert (_meqstr, (exp__) != (act__)); \
125 	} while (0)
126 
127 #define mu_assert_null(actual, message) do {			\
128 		char _meqstr[MU_BUF_SIZE];					\
129 		const void *act__ = (actual); \
130 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected to be NULL but it wasn't.", (message)); \
131 		mu_assert(_meqstr, (act__) == NULL);		\
132 	} while(0)
133 
134 #define mu_assert_notnull(actual, message) do {				\
135 		char _meqstr[MU_BUF_SIZE];					\
136 		const void *act__ = (actual); \
137 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected to not be NULL but it was.", (message)); \
138 		mu_assert(_meqstr, (act__) != NULL);			\
139 	} while(0)
140 
141 #define mu_assert_eq_fmt(actual, expected, message, fmt) do { \
142 		ut64 act__ = (ut64)(actual); \
143 		ut64 exp__ = (ut64)(expected); \
144 		if ((exp__) != (act__)) { \
145 			char _meqstr[MU_BUF_SIZE]; \
146 			snprintf (_meqstr, MU_BUF_SIZE, "%s: expected "fmt", got "fmt".", (message), (exp__), (act__)); \
147 			mu_assert(_meqstr, false); \
148 		} \
149 	} while(0)
150 
151 #define mu_assert_streq(actual, expected, message) do { \
152 		char _meqstr[MU_BUF_SIZE]; \
153 		const char *act__ = (actual); \
154 		const char *exp__ = (expected); \
155 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected %s, got %s.", (message), (exp__), (act__)); \
156 		mu_assert(_meqstr, strcmp((exp__), (act__)) == 0); \
157 } while(0)
158 
159 #define mu_assert_streq_free(actual, expected, message) do { \
160 		char *act2__ = (actual); \
161 		mu_assert_streq (act2__, (expected), (message)); \
162 		free (act2__); \
163 } while (0)
164 
165 #define mu_assert_nullable_streq(actual, expected, message) do { \
166 		char _meqstr[MU_BUF_SIZE]; \
167 		const char *act__ = (actual); \
168 		const char *exp__ = (expected); \
169 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected %s, got %s.", (message), (exp__ ? exp__ : "NULL"), (act__ ? act__ : "NULL")); \
170 		mu_assert(_meqstr, ((act__) == NULL && (exp__) == NULL) || ((act__) != NULL && (exp__) != NULL && strcmp((exp__), (act__)) == 0)); \
171 } while(0)
172 
173 #define mu_assert_memeq(actual, expected, len, message) do { \
174 		char _meqstr[MU_BUF_SIZE]; \
175 		size_t _meqstr_len; \
176 		const ut8 *act__ = (actual); \
177 		const ut8 *exp__ = (expected); \
178 		snprintf (_meqstr, MU_BUF_SIZE, "%s: expected ", message); \
179 		_meqstr_len = strlen (_meqstr); \
180 		snprint_mem (_meqstr + _meqstr_len, MU_BUF_SIZE - _meqstr_len, (exp__), (len)); \
181 		_meqstr_len = strlen (_meqstr); \
182 		snprintf (_meqstr + _meqstr_len, MU_BUF_SIZE - _meqstr_len, ", got "); \
183 		_meqstr_len = strlen (_meqstr); \
184 		snprint_mem (_meqstr + _meqstr_len, MU_BUF_SIZE - _meqstr_len, (act__), (len)); \
185 		mu_assert(_meqstr, memcmp((exp__), (act__), (len)) == 0); \
186 } while(0)
187 
188 #define mu_run_test_named(test, name, ...) do { int result; \
189 		printf(TBOLD "%s" TRESET " ", name); \
190 		result = test(__VA_ARGS__); \
191 		tests_run++; \
192 		tests_passed += result; \
193 } while (0)
194 
195 #define mu_run_test(test, ...) mu_run_test_named (test, #test, __VA_ARGS__)
196 
197 #define mu_cleanup_fail(label, message) do { mu_perror(message); retval = MU_ERR; goto label; } while(0)
198 #define mu_cleanup_sysfail(label, message) do { mu_psyserror(message); retval = MU_ERR; goto label; } while(0)
199 int tests_run = 0;
200 int tests_passed = 0;
201 int mu_test_status = MU_TEST_UNBROKEN;
202