[453] | 1 | // Copyright (c) Microsoft. All rights reserved.
|
---|
| 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
---|
| 3 |
|
---|
| 4 | #include "azure_macro_utils/macro_utils.h"
|
---|
| 5 |
|
---|
| 6 | #undef MOCKABLE_FUNCTION
|
---|
| 7 | #undef MOCKABLE_FUNCTION_WITH_RETURNS
|
---|
| 8 | #undef MOCKABLE_FUNCTION_WITH_CODE
|
---|
| 9 | #undef MOCKABLE_FUNCTION_WITH_CODE_END
|
---|
| 10 | #undef IMPLEMENT_MOCKABLE_FUNCTION
|
---|
| 11 | #undef MOCKABLE_INTERFACE
|
---|
| 12 |
|
---|
| 13 | /* This header is meant to be included by production code headers, so that the MOCKABLE_FUNCTION gets enabled. */
|
---|
| 14 | /*
|
---|
| 15 | If you are porting to a new platform and do not want to build the tests, but only the production code,
|
---|
| 16 | simply make sure that this file is in the include path (either by copying it to your inc folder or
|
---|
| 17 | by adjusting the include paths).
|
---|
| 18 | */
|
---|
| 19 |
|
---|
| 20 | #define DO_NOTHING_WITH_RETURN_VALUES(success_return_value, failure_return_value) \
|
---|
| 21 |
|
---|
| 22 | /* These 2 macros are used to check if a type is "void" or not */
|
---|
| 23 | #define UMOCK_C_PROD_TEST_void 0
|
---|
| 24 | #define UMOCK_C_PROD_IS_NOT_VOID(x) \
|
---|
| 25 | MU_IF(MU_C2(UMOCK_C_PROD_TEST_,x), 1, 0)
|
---|
| 26 |
|
---|
| 27 | #ifdef ENABLE_MOCKS
|
---|
| 28 |
|
---|
| 29 | #ifdef ENABLE_MOCK_FILTERING
|
---|
| 30 | #define ENABLE_MOCK_FILTERING_SWITCH 1
|
---|
| 31 | #else
|
---|
| 32 | #define ENABLE_MOCK_FILTERING_SWITCH 0
|
---|
| 33 | #endif
|
---|
| 34 |
|
---|
| 35 | #define UMOCK_C_PROD_ARG_IN_SIGNATURE(count, arg_type, arg_name) arg_type arg_name MU_IFCOMMA(count)
|
---|
| 36 |
|
---|
| 37 | #define MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, ...) \
|
---|
| 38 | result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__),,void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__))
|
---|
| 39 |
|
---|
| 40 | #define MOCKABLE_FUNCTION_DISABLED(do_returns, modifiers, result, function, ...) \
|
---|
| 41 | result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__), , void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__)); \
|
---|
| 42 | MU_IF(do_returns, MU_IF(UMOCK_C_PROD_IS_NOT_VOID(result), DO_NOTHING_WITH_RETURN_VALUES,), )
|
---|
| 43 |
|
---|
| 44 | /* Codes_SRS_UMOCK_C_LIB_01_001: [MOCKABLE_FUNCTION shall be used to wrap function definition allowing the user to declare a function that can be mocked.]*/
|
---|
| 45 | #define MOCKABLE_FUNCTION(modifiers, result, function, ...) \
|
---|
| 46 | MU_IF(ENABLE_MOCK_FILTERING_SWITCH,MU_IF(MU_C2(please_mock_, function),MOCKABLE_FUNCTION_DISABLED,MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK), MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK) (0, modifiers, result, function, __VA_ARGS__)
|
---|
| 47 |
|
---|
| 48 | /* Codes_SRS_UMOCK_C_LIB_01_212: [ MOCKABLE_FUNCTION_WITH_RETURNS shall be used to wrap function definitions, allowing the user to declare a function that can be mocked and aditionally declares the values that are to be returned in case of success and failure. ]*/
|
---|
| 49 | #define MOCKABLE_FUNCTION_WITH_RETURNS(modifiers, result, function, ...) \
|
---|
| 50 | MU_IF(ENABLE_MOCK_FILTERING_SWITCH,MU_IF(MU_C2(please_mock_, function),MOCKABLE_FUNCTION_DISABLED,MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK), MOCKABLE_FUNCTION_UMOCK_INTERNAL_WITH_MOCK) (1, modifiers, result, function, __VA_ARGS__)
|
---|
| 51 |
|
---|
| 52 | // The below MOCKABLE_FUNCTION_WITH_CODE macros are a temporary solution and should not be used for long term
|
---|
| 53 | // They will be removed once the real support is in umock_c
|
---|
| 54 | #define MOCKABLE_FUNCTION_WITH_CODE(modifiers, result, function, ...) \
|
---|
| 55 | MOCKABLE_FUNCTION_INTERNAL_WITH_CODE(modifiers, result, function, __VA_ARGS__)
|
---|
| 56 |
|
---|
| 57 | #define MOCKABLE_FUNCTION_WITH_CODE_END(...) \
|
---|
| 58 | MOCKABLE_FUNCTION_END(__VA_ARGS__)
|
---|
| 59 |
|
---|
| 60 | /* Codes_SRS_UMOCK_C_LIB_01_217: [ In the presence of the ENABLE_MOCKS define, IMPLEMENT_MOCKABLE_FUNCTION shall expand to the signature of the function, but the name shall be changed to be prefix with real_. ]*/
|
---|
| 61 | #define IMPLEMENT_MOCKABLE_FUNCTION(modifiers, result, function, ...) \
|
---|
| 62 | MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, MU_C2(real_, function), __VA_ARGS__)
|
---|
| 63 |
|
---|
| 64 | #define EXPAND_ENTRY(A) \
|
---|
| 65 | MOCKABLE_##A
|
---|
| 66 |
|
---|
| 67 | #define REGISTER_GLOBAL_MOCK_REAL_FUNCTION(modifiers, result, function, ...) \
|
---|
| 68 | REGISTER_GLOBAL_MOCK_HOOK(function, MU_C2(real_, function));
|
---|
| 69 |
|
---|
| 70 | #define REGISTER_GLOBAL_MOCK_REAL(A) \
|
---|
| 71 | REGISTER_GLOBAL_MOCK_REAL_##A
|
---|
| 72 |
|
---|
| 73 | /* Codes_SRS_UMOCK_C_LIB_01_215: [ Each item in ... shall be an entry for one mockable function. ]*/
|
---|
| 74 | /* Codes_SRS_UMOCK_C_LIB_01_216: [ Each item in ... shall be defined using a macro called FUNCTION, which shall be an alias for MOCKABLE_FUNCTION. ]*/
|
---|
| 75 | #define MOCKABLE_INTERFACE(interface_name, ...) \
|
---|
| 76 | MU_FOR_EACH_1(EXPAND_ENTRY, __VA_ARGS__) \
|
---|
| 77 | static void MU_C2(register_reals_, interface_name)(void) \
|
---|
| 78 | { \
|
---|
| 79 | MU_FOR_EACH_1(REGISTER_GLOBAL_MOCK_REAL, __VA_ARGS__); \
|
---|
| 80 | } \
|
---|
| 81 |
|
---|
| 82 | #include "umock_c/umock_c.h"
|
---|
| 83 |
|
---|
| 84 | #else
|
---|
| 85 |
|
---|
| 86 | #define UMOCK_C_PROD_ARG_IN_SIGNATURE(count, arg_type, arg_name) arg_type arg_name MU_IFCOMMA(count)
|
---|
| 87 |
|
---|
| 88 | #define MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, ...) \
|
---|
| 89 | result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__),,void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__))
|
---|
| 90 |
|
---|
| 91 | /* Codes_SRS_UMOCK_C_LIB_01_002: [The macro shall generate a function signature in case ENABLE_MOCKS is not defined.] */
|
---|
| 92 | /* Codes_SRS_UMOCK_C_LIB_01_005: [If ENABLE_MOCKS is not defined, MOCKABLE_FUNCTION shall only generate a declaration for the function.] */
|
---|
| 93 | /* Codes_SRS_UMOCK_C_LIB_01_001: [MOCKABLE_FUNCTION shall be used to wrap function definition allowing the user to declare a function that can be mocked.]*/
|
---|
| 94 | #define MOCKABLE_FUNCTION(modifiers, result, function, ...) \
|
---|
| 95 | MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, __VA_ARGS__);
|
---|
| 96 |
|
---|
| 97 | /* Codes_SRS_UMOCK_C_LIB_01_213: [ The macro shall generate a function signature in case ENABLE_MOCKS is not defined. ]*/
|
---|
| 98 | /* Codes_SRS_UMOCK_C_LIB_01_212: [ MOCKABLE_FUNCTION_WITH_RETURNS shall be used to wrap function definitions, allowing the user to declare a function that can be mocked and aditionally declares the values that are to be returned in case of success and failure. ]*/
|
---|
| 99 | #define MOCKABLE_FUNCTION_WITH_RETURNS(modifiers, result, function, ...) \
|
---|
| 100 | result modifiers function(MU_IF(MU_COUNT_ARG(__VA_ARGS__),,void) MU_FOR_EACH_2_COUNTED(UMOCK_C_PROD_ARG_IN_SIGNATURE, __VA_ARGS__)); \
|
---|
| 101 | MU_IF(UMOCK_C_PROD_IS_NOT_VOID(result), DO_NOTHING_WITH_RETURN_VALUES,)
|
---|
| 102 |
|
---|
| 103 | #define UMOCK_C_PROD_ARG_IN_SIGNATURE_2(count, arg_type, arg_name)
|
---|
| 104 |
|
---|
| 105 | // The below MOCKABLE_FUNCTION_WITH_CODE macros are a temporary solution and should not be used for long term
|
---|
| 106 | // They will be removed once the real support is in umock_c
|
---|
| 107 | #define MOCKABLE_FUNCTION_WITH_CODE(modifiers, result, function, ...) \
|
---|
| 108 | MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, __VA_ARGS__)
|
---|
| 109 |
|
---|
| 110 | /* Codes_SRS_UMOCK_C_LIB_01_218: [ If ENABLE_MOCKS is not defined, IMPLEMENT_MOCKABLE_FUNCTION shall expand to the signature of the function. ]*/
|
---|
| 111 | #define IMPLEMENT_MOCKABLE_FUNCTION(modifiers, result, function, ...) \
|
---|
| 112 | MOCKABLE_FUNCTION_SIGNATURE(modifiers, result, function, __VA_ARGS__)
|
---|
| 113 |
|
---|
| 114 | #define EXPAND_PROD_ENTRY(A) MOCKABLE_##A
|
---|
| 115 |
|
---|
| 116 | /* Codes_SRS_UMOCK_C_LIB_01_215: [ Each item in ... shall be an entry for one mockable function. ]*/
|
---|
| 117 | /* Codes_SRS_UMOCK_C_LIB_01_216: [ Each item in ... shall be defined using a macro called FUNCTION, which shall be an alias for MOCKABLE_FUNCTION. ]*/
|
---|
| 118 | #define MOCKABLE_INTERFACE(interface_name, ...) \
|
---|
| 119 | MU_FOR_EACH_1(EXPAND_PROD_ENTRY, __VA_ARGS__)
|
---|
| 120 |
|
---|
| 121 | #define MOCKABLE_FUNCTION_WITH_CODE_END(...) \
|
---|
| 122 |
|
---|
| 123 | #endif
|
---|