Skip to content

Commit

Permalink
Added macros to support noreturn functions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
informatimago committed May 2, 2023
1 parent b4ac04a commit 6b180d6
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
44 changes: 44 additions & 0 deletions docs/UnityAssertionsReference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)`
Expand Down
20 changes: 20 additions & 0 deletions src/unity_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ struct UNITY_STORAGE_T
#endif
#ifndef UNITY_EXCLUDE_SETJMP_H
jmp_buf AbortFrame;
jmp_buf NoReturnFrame;
#endif
};

Expand Down Expand Up @@ -762,9 +763,28 @@ extern const char UnityStrErrShorthand[];
#ifndef UNITY_EXCLUDE_SETJMP_H
#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0)
#define TEST_ABORT() longjmp(Unity.AbortFrame, 1)

#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() 1
#define TEST_ABORT() return
#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 */
Expand Down

0 comments on commit 6b180d6

Please sign in to comment.