Back to home page

Enduro/X

 
 

    


0001 #ifndef UNIT_IMPLEMENTATION_HEADER
0002 #define UNIT_IMPLEMENTATION_HEADER
0003 
0004 typedef struct {
0005     const char* name;
0006     const char* filename;
0007     void (*setup)(void);
0008     void (*teardown)(void);
0009 } CgreenContext;
0010 
0011 typedef struct {
0012     CgreenContext* context;
0013     const char* name;
0014     void(*run)(void);
0015     const char* filename;
0016     int line;
0017 } CgreenTest;
0018 
0019 #define CGREEN_SPEC_PREFIX "CgreenSpec"
0020 #define CGREEN_SEPARATOR "__"
0021 #define spec_name(contextName, testName) CgreenSpec__##contextName##__##testName##__
0022 
0023 /*This gives better error messages at the cost of duplication*/
0024 #define ENSURE_VA_NUM_ARGS(...) ENSURE_VA_NUM_ARGS_IMPL_((__VA_ARGS__, _CALLED_WITH_TOO_MANY_ARGUMENTS,  WithContextAndSpecificationName,  WithSpecificationName))
0025 #define ENSURE_VA_NUM_ARGS_IMPL_(tuple) ENSURE_VA_NUM_ARGS_IMPL tuple
0026 
0027 #define ENSURE_VA_NUM_ARGS_IMPL(_1, _2, _3, N, ...) N
0028 
0029 #define ENSURE_macro_dispatcher(func, ...)   ENSURE_macro_dispatcher_(func, ENSURE_VA_NUM_ARGS(__VA_ARGS__))
0030 
0031 /* these levels of indirecton are a work-around for variadic macro deficiencies in Visual C++ 2012 and prior */
0032 #define ENSURE_macro_dispatcher_(func, nargs)           ENSURE_macro_dispatcher__(func, nargs)
0033 #define ENSURE_macro_dispatcher__(func, nargs)           ENSURE_macro_dispatcher___(func, nargs)
0034 #define ENSURE_macro_dispatcher___(func, nargs)          func ## nargs
0035 
0036 #define Ensure_NARG(...) ENSURE_macro_dispatcher(Ensure, __VA_ARGS__)
0037 
0038 #define EnsureWithContextAndSpecificationName(contextName, spec, ...) \
0039     static void contextName##__##spec (void);\
0040     CgreenTest spec_name(contextName, spec) = { &contextFor##contextName, #spec, &contextName##__##spec, __FILE__, __LINE__ };\
0041     static void contextName##__##spec (void)
0042 
0043 extern CgreenContext defaultContext;
0044 
0045 #define EnsureWithSpecificationName(spec, ...) \
0046     static void spec (void);\
0047     CgreenTest spec_name(default, spec) = { &defaultContext, #spec, &spec, __FILE__, __LINE__ };\
0048     static void spec (void)
0049 
0050 #define DescribeImplementation(subject) \
0051         static void setup(void);                \
0052         static void teardown(void);                                     \
0053         static CgreenContext contextFor##subject = { #subject, __FILE__, &setup, &teardown }; \
0054         extern void(*BeforeEach_For_##subject)(void);                   \
0055         extern void(*AfterEach_For_##subject)(void);                    \
0056         static void setup(void) {                                       \
0057             if (BeforeEach_For_##subject != NULL) BeforeEach_For_##subject(); \
0058         }                                                               \
0059         static void teardown(void) {                                    \
0060             if (AfterEach_For_##subject != NULL) AfterEach_For_##subject(); \
0061         }
0062 
0063 #define BeforeEachImplementation(subject) \
0064         void BeforeEach_For_##subject##_Function(void);                 \
0065         void(*BeforeEach_For_##subject)(void) = &BeforeEach_For_##subject##_Function; \
0066         void BeforeEach_For_##subject##_Function(void)
0067 
0068 #define AfterEachImplementation(subject) \
0069         static void AfterEach_For_##subject##_Function(void);           \
0070         void(*AfterEach_For_##subject)(void) = &AfterEach_For_##subject##_Function; \
0071         static void AfterEach_For_##subject##_Function(void)
0072 
0073 #endif