diff -r e59b76889f00 -r d31f4d4075dc src/cx/test.h --- a/src/cx/test.h Wed Dec 20 16:46:14 2023 +0100 +++ b/src/cx/test.h Wed Dec 20 17:57:18 2023 +0100 @@ -48,16 +48,13 @@ * * CX_TEST(function_name) { * // memory allocation and other stuff here - * #CX_TEST_BEGIN - * // tests with CX_TEST_ASSERT() and/or - * // calls with CX_TEST_CALL_SUBROUTINE() here - * #CX_TEST_END + * #CX_TEST_DO { + * // tests with CX_TEST_ASSERT() and/or + * // calls with CX_TEST_CALL_SUBROUTINE() here + * } * // cleanup of memory here * } * - * - * @remark if a test fails, execution continues at the - * #CX_TEST_END macro! So make sure every necessary cleanup happens afterwards. * * @attention Do not call own functions within a test, that use * CX_TEST_ASSERT() macros and are not defined by using CX_TEST_SUBROUTINE(). @@ -252,17 +249,18 @@ #define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, cx_write_func _writefnc_) /** - * Marks the begin of a test. - * Note: Any CX_TEST_ASSERT() calls must be performed after - * #CX_TEST_BEGIN. - * - * @see #CX_TEST_END + * Defines the scope of a test. + * @attention Any CX_TEST_ASSERT() calls must be performed in scope of + * #CX_TEST_DO. */ -#define CX_TEST_BEGIN _writefnc_("Running ", 1, 8, _output_);\ +#define CX_TEST_DO _writefnc_("Running ", 1, 8, _output_);\ _writefnc_(__FUNCTION__, 1, strlen(__FUNCTION__), _output_);\ _writefnc_("... ", 1, 4, _output_);\ - jmp_buf _env_; \ - if (!setjmp(_env_)) { + jmp_buf _env_;\ + for (unsigned int _cx_test_loop_ = 0 ;\ + _cx_test_loop_ == 0 && !setjmp(_env_);\ + _writefnc_("success.\n", 1, 9, _output_),\ + _suite_->success++, _cx_test_loop_++) /** * Checks a test assertion. @@ -272,11 +270,22 @@ * @param condition the condition to check * @param message the message that shall be printed out on failure */ -#define CX_TEST_ASSERT(condition,message) if (!(condition)) { \ - _writefnc_(message".\n", 1, 2+strlen(message), _output_); \ +#define CX_TEST_ASSERTM(condition,message) if (!(condition)) { \ + char const* _assert_msg_ = message; \ + _writefnc_(_assert_msg_, 1, strlen(_assert_msg_), _output_); \ + _writefnc_(".\n", 1, 2, _output_); \ _suite_->failure++; \ longjmp(_env_, 1);\ - } + } (void) 0 + +/** + * Checks a test assertion. + * If the assertion is correct, the test carries on. If the assertion is not + * correct, the specified message (terminated by a dot and a line break) is + * written to the test suites output stream. + * @param condition the condition to check + */ +#define CX_TEST_ASSERT(condition) CX_TEST_ASSERTM(condition, #condition " failed") /** * Macro for a test subroutine function header. @@ -298,8 +307,7 @@ * Subroutines declared with CX_TEST_SUBROUTINE() can be called by using this * macro. * - * Note: You may only call subroutines within a #CX_TEST_BEGIN- - * #CX_TEST_END-block. + * @remark You may only call subroutines within a #CX_TEST_DO block. * * @param name the name of the subroutine * @param ... the argument list @@ -309,15 +317,6 @@ #define CX_TEST_CALL_SUBROUTINE(name,...) \ name(_suite_,_output_,_writefnc_,_env_,__VA_ARGS__); -/** - * Marks the end of a test. - * Note: Any CX_TEST_ASSERT() calls must be performed before - * #CX_TEST_END. - * - * @see #CX_TEST_BEGIN - */ -#define CX_TEST_END _writefnc_("success.\n", 1, 9, _output_); _suite_->success++;} - #ifdef __cplusplus } #endif