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
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
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