1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
/* Convenience macros to reduce munit boiler plate. */
#ifndef TEST_RUNNER_H_
#define TEST_RUNNER_H_
#include "munit.h"
/* Top-level suites array declaration.
*
* These top-level suites hold all module-level child suites and must be defined
* and then set as child suites of a root suite created at runtime by the test
* runner's main(). This can be done using the TEST_RUNNER macro. */
extern MunitSuite _main_suites[];
extern int _main_suites_n;
/* Maximum number of test cases for each suite */
#define SUITE__CAP 128
/* Define the top-level suites array and the main() function of the test. */
#define RUNNER(NAME) \
MunitSuite _main_suites[SUITE__CAP]; \
int _main_suites_n = 0; \
\
int main(int argc, char *argv[MUNIT_ARRAY_PARAM(argc)]) \
{ \
MunitSuite suite = {(char *)"", NULL, _main_suites, 1, 0}; \
return munit_suite_main(&suite, (void *)NAME, argc, argv); \
}
/* Declare and register a new test suite #S belonging to the file's test module.
*
* A test suite is a pair of static variables:
*
* static MunitTest _##S##_suites[SUITE__CAP]
* static MunitTest _##S##_tests[SUITE__CAP]
*
* The tests and suites attributes of the next available MunitSuite slot in the
* _module_suites array will be set to the suite's tests and suites arrays, and
* the prefix attribute of the slot will be set to /S. */
#define SUITE(S) \
SUITE__DECLARE(S) \
SUITE__ADD_CHILD(main, #S, S)
/* Declare and register a new test. */
#define TEST(S, C, SETUP, TEAR_DOWN, OPTIONS, PARAMS) \
static MunitResult test_##S##_##C(const MunitParameter params[], \
void *data); \
TEST__ADD_TO_SUITE(S, C, SETUP, TEAR_DOWN, OPTIONS, PARAMS) \
static MunitResult test_##S##_##C( \
MUNIT_UNUSED const MunitParameter params[], MUNIT_UNUSED void *data)
#define SKIP_IF_NO_FIXTURE \
if (f == NULL) { \
return MUNIT_SKIP; \
}
/* Declare the MunitSuite[] and the MunitTest[] arrays that compose the test
* suite identified by S. */
#define SUITE__DECLARE(S) \
static MunitSuite _##S##_suites[SUITE__CAP]; \
static MunitTest _##S##_tests[SUITE__CAP]; \
static MunitTestSetup _##S##_setup = NULL; \
static MunitTestTearDown _##S##_tear_down = NULL; \
static int _##S##_suites_n = 0; \
static int _##S##_tests_n = 0; \
__attribute__((constructor(101))) static void _##S##_init(void) \
{ \
memset(_##S##_suites, 0, sizeof(_##S##_suites)); \
memset(_##S##_tests, 0, sizeof(_##S##_tests)); \
(void)_##S##_suites_n; \
(void)_##S##_tests_n; \
(void)_##S##_setup; \
(void)_##S##_tear_down; \
}
/* Set the tests and suites attributes of the next available slot of the
* MunitSuite[] array of S1 to the MunitTest[] and MunitSuite[] arrays of S2,
* using the given PREFIX. */
#define SUITE__ADD_CHILD(S1, PREFIX, S2) \
__attribute__((constructor(102))) static void _##S1##_##S2##_init(void) \
{ \
int n = _##S1##_suites_n; \
_##S1##_suites[n].prefix = PREFIX; \
_##S1##_suites[n].tests = _##S2##_tests; \
_##S1##_suites[n].suites = _##S2##_suites; \
_##S1##_suites[n].iterations = 0; \
_##S1##_suites[n].options = 0; \
_##S1##_suites_n = n + 1; \
}
/* Add a test case to the MunitTest[] array of suite S. */
#define TEST__ADD_TO_SUITE(S, C, SETUP, TEAR_DOWN, OPTIONS, PARAMS) \
__attribute__((constructor(103))) static void _##S##_tests_##C##_init( \
void) \
{ \
MunitTest *tests = _##S##_tests; \
int n = _##S##_tests_n; \
TEST__SET_IN_ARRAY(tests, n, "/" #C, test_##S##_##C, SETUP, TEAR_DOWN, \
OPTIONS, PARAMS); \
_##S##_tests_n = n + 1; \
}
/* Set the values of the I'th test case slot in the given test array */
#define TEST__SET_IN_ARRAY(TESTS, I, NAME, FUNC, SETUP, TEAR_DOWN, OPTIONS, \
PARAMS) \
TESTS[I].name = NAME; \
TESTS[I].test = FUNC; \
TESTS[I].setup = SETUP; \
TESTS[I].tear_down = TEAR_DOWN; \
TESTS[I].options = OPTIONS; \
TESTS[I].parameters = PARAMS
#endif /* TEST_RUNNER_H_ */
|