From 6eaf69323f54796ed90a6dd4e033820224836f06 Mon Sep 17 00:00:00 2001 From: "Pascal J. Bourguignon" Date: Fri, 28 Apr 2023 11:47:33 +0200 Subject: [PATCH 1/2] Ignore backup files *~. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 211683a8..6da0ca6a 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ Makefile CMakeFiles CMakeCache.txt !unityConfig.cmake +*~ From 60b64fb6fb43ad737e65514306dc23a044eb3779 Mon Sep 17 00:00:00 2001 From: "Pascal J. Bourguignon" Date: Tue, 2 May 2023 11:40:03 +0200 Subject: [PATCH 2/2] Added macros to support noreturn functions Added TEST_PROTECT_NORETURN(), TEST_DO_NOT_RETURN(), and TEST_NOT_RETURNING(call) to test for non-returning functions. Mock functions that are declared noreturn shall use TEST_DO_NOT_RETURN() instead of return. --- docs/UnityAssertionsReference.md | 44 ++++++++++++++++++++++++++++++++ src/unity_internals.h | 23 +++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/docs/UnityAssertionsReference.md b/docs/UnityAssertionsReference.md index 0a0e51b6..767fc66b 100644 --- a/docs/UnityAssertionsReference.md +++ b/docs/UnityAssertionsReference.md @@ -222,6 +222,50 @@ This can be useful for outputting `INFO` messages into the Unity output stream without actually ending the test. Like pass and fail messages, it will be output with the filename and line number. +#### `TEST_PROTECT_NORETURN()` + +This macro prepares an environment to test a function that is declared `noreturn`. + +``` + if(TEST_PROTECT_NORETURN()){ + } +``` + +The function `mock_go_elsewhere()` would use `TEST_DO_NOT_RETURN()` +instead of returning. + +#### `TEST_NOT_RETURNING(call)` + +Calls a function, and the test fails if the function returns. +Instead, the called function should use `TEST_DO_NOT_RETURN()`. + +``` + /* prepare the test here */ + TEST_NOT_RETURNING(go_elsewhere(42)); +``` + +Note: this can be used to call a mock function (that uses +`TEST_NOT_RETURNING()` instead of returning), or an actual function +that effectively does not return. In the later case, the control +won't resume to the caller test (unless there's a failure), so the +test should expect that and have set up things accordingly. + +This cannot be used if `UNITY_EXCLUDE_SETJMP_H` is defined. + +#### `TEST_DO_NOT_RETURN()` + +Aborts the execution, and resume after the current +`TEST_NOT_RETURNING()`, successfully. + +This should be used in mock functions declared `noreturn` instead of +returning (explicitely or implicitely). + +Note: actual functions that don't return will go wherever they shoud +go and it's assumed this is handled in the test. These macros are +intended to be used by mock functions. + +This cannot be used if `UNITY_EXCLUDE_SETJMP_H` is defined. + ### Boolean #### `TEST_ASSERT (condition)` diff --git a/src/unity_internals.h b/src/unity_internals.h index 65938ff7..093e23da 100644 --- a/src/unity_internals.h +++ b/src/unity_internals.h @@ -518,6 +518,7 @@ struct UNITY_STORAGE_T #endif #ifndef UNITY_EXCLUDE_SETJMP_H jmp_buf AbortFrame; + jmp_buf NoReturnFrame; #endif }; @@ -788,6 +789,28 @@ extern const char UnityStrErrShorthand[]; #endif #endif +#ifndef UNITY_EXCLUDE_SETJMP_H +#define TEST_PROTECT_NORETURN() (setjmp(Unity.NoReturnFrame) == 0) +#define TEST_DO_NOT_RETURN() longjmp(Unity.NoReturnFrame, 1) + +/* +TEST_NOT_RETURNING(call) +This macro uses TEST_PROTECT_NORETURN to protect the call. +If the call returns, then the test fails. +*/ +#define TEST_NOT_RETURNING(call) \ + if (TEST_PROTECT_NORETURN()) \ + { \ + call; \ + UnityFail("Call Was Expected Not To Return: " #call, __LINE__); \ + } + +#else +#define TEST_PROTECT_NORETURN() _Static_assert(false, "TEST_PROTECT_NORETURN() cannot be used when UNITY_EXCLUDE_SETJMP_H is defined" +#define TEST_DO_NOT_RETURN() _Static_assert(false, "TEST_DO_NOT_RETURN() cannot be used when UNITY_EXCLUDE_SETJMP_H is defined" +#define TEST_NOT_RETURNING(call) _Static_assert(false, "TEST_NOT_RETURNING(call) cannot be used when UNITY_EXCLUDE_SETJMP_H is defined" +#endif + /* Automatically enable variadic macros support, if it not enabled before */ #ifndef UNITY_SUPPORT_VARIADIC_MACROS #ifdef __STDC_VERSION__