33 * |
33 * |
34 * Usage of this test framework: |
34 * Usage of this test framework: |
35 * |
35 * |
36 * **** IN HEADER FILE: **** |
36 * **** IN HEADER FILE: **** |
37 * |
37 * |
38 * <pre> |
38 * <code> |
39 * CX_TEST(function_name); |
39 * CX_TEST(function_name); |
40 * CX_TEST_SUBROUTINE(subroutine_name, paramlist); // optional |
40 * CX_TEST_SUBROUTINE(subroutine_name, paramlist); // optional |
41 * </pre> |
41 * </code> |
42 * |
42 * |
43 * **** IN SOURCE FILE: **** |
43 * **** IN SOURCE FILE: **** |
44 * <pre> |
44 * <code> |
45 * CX_TEST_SUBROUTINE(subroutine_name, paramlist) { |
45 * CX_TEST_SUBROUTINE(subroutine_name, paramlist) { |
46 * // tests with CX_TEST_ASSERT() |
46 * // tests with CX_TEST_ASSERT() |
47 * } |
47 * } |
48 * |
48 * |
49 * CX_TEST(function_name) { |
49 * CX_TEST(function_name) { |
52 * // tests with CX_TEST_ASSERT() and/or |
52 * // tests with CX_TEST_ASSERT() and/or |
53 * // calls with CX_TEST_CALL_SUBROUTINE() here |
53 * // calls with CX_TEST_CALL_SUBROUTINE() here |
54 * } |
54 * } |
55 * // cleanup of memory here |
55 * // cleanup of memory here |
56 * } |
56 * } |
57 * </pre> |
57 * </code> |
58 * |
58 * |
59 * @attention Do not call own functions within a test, that use |
59 * @attention Do not call own functions within a test, that use |
60 * CX_TEST_ASSERT() macros and are not defined by using CX_TEST_SUBROUTINE(). |
60 * CX_TEST_ASSERT() macros and are not defined by using CX_TEST_SUBROUTINE(). |
61 * |
61 * |
62 * @author Mike Becker |
62 * @author Mike Becker |
84 * <code>__func__</code>. |
85 * <code>__func__</code>. |
85 */ |
86 */ |
86 #define __FUNCTION__ __func__ |
87 #define __FUNCTION__ __func__ |
87 #endif |
88 #endif |
88 |
89 |
89 // |
|
90 #if !defined(__clang__) && __GNUC__ > 3 |
90 #if !defined(__clang__) && __GNUC__ > 3 |
91 #pragma GCC diagnostic ignored "-Wclobbered" |
91 #pragma GCC diagnostic ignored "-Wclobbered" |
92 #endif |
92 #endif |
93 |
|
94 #ifndef UCX_COMMON_H |
|
95 /** |
|
96 * Function pointer compatible with fwrite-like functions. |
|
97 */ |
|
98 typedef size_t (*cx_write_func)( |
|
99 const void *, |
|
100 size_t, |
|
101 size_t, |
|
102 void * |
|
103 ); |
|
104 #endif // UCX_COMMON_H |
|
105 |
93 |
106 /** Type for the CxTestSuite. */ |
94 /** Type for the CxTestSuite. */ |
107 typedef struct CxTestSuite CxTestSuite; |
95 typedef struct CxTestSuite CxTestSuite; |
108 |
96 |
109 /** Pointer to a test function. */ |
97 /** Pointer to a test function. */ |
146 /** |
134 /** |
147 * Creates a new test suite. |
135 * Creates a new test suite. |
148 * @param name optional name of the suite |
136 * @param name optional name of the suite |
149 * @return a new test suite |
137 * @return a new test suite |
150 */ |
138 */ |
|
139 cx_attr_nonnull |
|
140 cx_attr_nodiscard |
|
141 cx_attr_cstr_arg(1) |
|
142 cx_attr_malloc |
151 static inline CxTestSuite* cx_test_suite_new(const char *name) { |
143 static inline CxTestSuite* cx_test_suite_new(const char *name) { |
152 CxTestSuite* suite = (CxTestSuite*) malloc(sizeof(CxTestSuite)); |
144 CxTestSuite* suite = (CxTestSuite*) malloc(sizeof(CxTestSuite)); |
153 if (suite != NULL) { |
145 if (suite != NULL) { |
154 suite->name = name; |
146 suite->name = name; |
155 suite->success = 0; |
147 suite->success = 0; |
177 /** |
171 /** |
178 * Registers a test function with the specified test suite. |
172 * Registers a test function with the specified test suite. |
179 * |
173 * |
180 * @param suite the suite, the test function shall be added to |
174 * @param suite the suite, the test function shall be added to |
181 * @param test the test function to register |
175 * @param test the test function to register |
182 * @return zero on success or non-zero on failure |
176 * @retval zero success |
183 */ |
177 * @retval non-zero failure |
|
178 */ |
|
179 cx_attr_nonnull |
184 static inline int cx_test_register(CxTestSuite* suite, CxTest test) { |
180 static inline int cx_test_register(CxTestSuite* suite, CxTest test) { |
185 CxTestSet *t = (CxTestSet*) malloc(sizeof(CxTestSet)); |
181 CxTestSet *t = (CxTestSet*) malloc(sizeof(CxTestSet)); |
186 if (t) { |
182 if (t) { |
187 t->test = test; |
183 t->test = test; |
188 t->next = NULL; |
184 t->next = NULL; |
203 |
199 |
204 /** |
200 /** |
205 * Runs a test suite and writes the test log to the specified stream. |
201 * Runs a test suite and writes the test log to the specified stream. |
206 * @param suite the test suite to run |
202 * @param suite the test suite to run |
207 * @param out_target the target buffer or file to write the output to |
203 * @param out_target the target buffer or file to write the output to |
208 * @param out_writer the write function writing to \p out_target |
204 * @param out_writer the write function writing to @p out_target |
209 */ |
205 */ |
|
206 cx_attr_nonnull |
210 static inline void cx_test_run(CxTestSuite *suite, |
207 static inline void cx_test_run(CxTestSuite *suite, |
211 void *out_target, cx_write_func out_writer) { |
208 void *out_target, cx_write_func out_writer) { |
212 if (suite->name == NULL) { |
209 if (suite->name == NULL) { |
213 out_writer("*** Test Suite ***\n", 1, 19, out_target); |
210 out_writer("*** Test Suite ***\n", 1, 19, out_target); |
214 } else { |
211 } else { |
231 out_writer(total, 1, len, out_target); |
228 out_writer(total, 1, len, out_target); |
232 } |
229 } |
233 |
230 |
234 /** |
231 /** |
235 * Runs a test suite and writes the test log to the specified FILE stream. |
232 * Runs a test suite and writes the test log to the specified FILE stream. |
236 * @param suite the test suite to run |
233 * @param suite (@c CxTestSuite*) the test suite to run |
237 * @param file the target file to write the output to |
234 * @param file (@c FILE*) the target file to write the output to |
238 */ |
235 */ |
239 #define cx_test_run_f(suite, file) cx_test_run(suite, (void*)file, (cx_write_func)fwrite) |
236 #define cx_test_run_f(suite, file) cx_test_run(suite, (void*)file, (cx_write_func)fwrite) |
240 |
237 |
241 /** |
238 /** |
242 * Runs a test suite and writes the test log to stdout. |
239 * Runs a test suite and writes the test log to stdout. |
243 * @param suite the test suite to run |
240 * @param suite (@c CxTestSuite*) the test suite to run |
244 */ |
241 */ |
245 #define cx_test_run_stdout(suite) cx_test_run_f(suite, stdout) |
242 #define cx_test_run_stdout(suite) cx_test_run_f(suite, stdout) |
246 |
243 |
247 /** |
244 /** |
248 * Macro for a #CxTest function header. |
245 * Macro for a #CxTest function header. |
253 */ |
250 */ |
254 #define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, cx_write_func _writefnc_) |
251 #define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, cx_write_func _writefnc_) |
255 |
252 |
256 /** |
253 /** |
257 * Defines the scope of a test. |
254 * Defines the scope of a test. |
|
255 * |
|
256 * @code |
|
257 * CX_TEST(my_test_name) { |
|
258 * // setup code |
|
259 * CX_TEST_DO { |
|
260 * // your tests go here |
|
261 * } |
|
262 * // tear down code |
|
263 * } |
|
264 * @endcode |
|
265 * |
258 * @attention Any CX_TEST_ASSERT() calls must be performed in scope of |
266 * @attention Any CX_TEST_ASSERT() calls must be performed in scope of |
259 * #CX_TEST_DO. |
267 * #CX_TEST_DO. |
260 */ |
268 */ |
261 #define CX_TEST_DO _writefnc_("Running ", 1, 8, _output_);\ |
269 #define CX_TEST_DO _writefnc_("Running ", 1, 8, _output_);\ |
262 _writefnc_(__FUNCTION__, 1, strlen(__FUNCTION__), _output_);\ |
270 _writefnc_(__FUNCTION__, 1, strlen(__FUNCTION__), _output_);\ |
270 /** |
278 /** |
271 * Checks a test assertion. |
279 * Checks a test assertion. |
272 * If the assertion is correct, the test carries on. If the assertion is not |
280 * If the assertion is correct, the test carries on. If the assertion is not |
273 * correct, the specified message (terminated by a dot and a line break) is |
281 * correct, the specified message (terminated by a dot and a line break) is |
274 * written to the test suites output stream. |
282 * written to the test suites output stream. |
275 * @param condition the condition to check |
283 * @param condition (@c bool) the condition to check |
276 * @param message the message that shall be printed out on failure |
284 * @param message (@c char*) the message that shall be printed out on failure |
277 */ |
285 */ |
278 #define CX_TEST_ASSERTM(condition,message) if (!(condition)) { \ |
286 #define CX_TEST_ASSERTM(condition,message) if (!(condition)) { \ |
279 const char *_assert_msg_ = message; \ |
287 const char *_assert_msg_ = message; \ |
280 _writefnc_(_assert_msg_, 1, strlen(_assert_msg_), _output_); \ |
288 _writefnc_(_assert_msg_, 1, strlen(_assert_msg_), _output_); \ |
281 _writefnc_(".\n", 1, 2, _output_); \ |
289 _writefnc_(".\n", 1, 2, _output_); \ |
286 /** |
294 /** |
287 * Checks a test assertion. |
295 * Checks a test assertion. |
288 * If the assertion is correct, the test carries on. If the assertion is not |
296 * If the assertion is correct, the test carries on. If the assertion is not |
289 * correct, the specified message (terminated by a dot and a line break) is |
297 * correct, the specified message (terminated by a dot and a line break) is |
290 * written to the test suites output stream. |
298 * written to the test suites output stream. |
291 * @param condition the condition to check |
299 * @param condition (@c bool) the condition to check |
292 */ |
300 */ |
293 #define CX_TEST_ASSERT(condition) CX_TEST_ASSERTM(condition, #condition " failed") |
301 #define CX_TEST_ASSERT(condition) CX_TEST_ASSERTM(condition, #condition " failed") |
294 |
302 |
295 /** |
303 /** |
296 * Macro for a test subroutine function header. |
304 * Macro for a test subroutine function header. |