diff --git a/test/main.c b/test/main.c index f9697b5b..be94f951 100644 --- a/test/main.c +++ b/test/main.c @@ -5,14 +5,14 @@ struct test { const char *name; - int (*f)(void); + void (*f)(void); }; static struct test *tests = NULL; static size_t lenTests = 0; static size_t capTests = 0; -void testingprivRegisterTest(const char *name, int (*f)(void)) +void testingprivRegisterTest(const char *name, void (*f)(void)) { if (lenTests == capTests) { struct test *newtests; @@ -38,6 +38,24 @@ static int testcmp(const void *aa, const void *bb) return strcmp(a->name, b->name); } +static int testingprivRet = 0; + +void TestFail(void) +{ + testingprivRet = 1; +} + +void TestFailNow(void) +{ + exit(1); +} + +void TestSkipNow(void) +{ + // see https://mesonbuild.com/Unit-tests.html#skipped-tests-and-hard-errors + exit(77); +} + static const char *basename(const char *file) { const char *p; @@ -51,7 +69,7 @@ static const char *basename(const char *file) return file; } -void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt, ...) +void testingprivLogfFullThen(FILE *f, void (*then)(void), const char *filename, long line, const char *fmt, ...) { va_list ap; @@ -60,6 +78,8 @@ void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt, vfprintf(f, fmt, ap); fprintf(f, "\n"); va_end(ap); + if (then != NULL) + (*then)(); } int main(int argc, char *argv[]) @@ -78,5 +98,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "%s: no such test\n", argv[1]); return 1; } - return (*(t->f))(); + testingprivRet = 0; + (*(t->f))(); + return testingprivRet; } diff --git a/test/test.h b/test/test.h index d44b0bc8..e1e95db2 100644 --- a/test/test.h +++ b/test/test.h @@ -41,56 +41,49 @@ extern "C" { #endif #define Test(Name) \ - void testingprivImplName(Test ## Name)(int *testingprivRet); \ - static int testingprivScaffoldName(Test ## Name)(void) \ + void testingprivImplName(Test ## Name)(void); \ + static void testingprivScaffoldName(Test ## Name)(void) \ { \ - int ret = 0; \ uiInitError err; \ memset(&err, 0, sizeof (uiInitError)); \ err.Size = sizeof (uiInitError); \ if (!uiInit(NULL, &err)) { \ fprintf(stderr, "error initializing libui for Test" #Name ": %s\n", err.Message); \ - return 1; \ + TestFailNow(); \ } \ - testingprivImplName(Test ## Name)(&ret); \ - return ret; \ + testingprivImplName(Test ## Name)(); \ } \ testingprivMkCtor(Test ## Name) \ - void testingprivImplName(Test ## Name)(int *testingprivRet) + void testingprivImplName(Test ## Name)(void) #define TestNoInit(Name) \ - void testingprivImplName(Test ## Name)(int *testingprivRet); \ - static int testingprivScaffoldName(Test ## Name)(void) \ + void testingprivImplName(Test ## Name)(void); \ + static void testingprivScaffoldName(Test ## Name)(void) \ { \ - int ret = 0; \ - testingprivImplName(Test ## Name)(&ret); \ - return ret; \ + testingprivImplName(Test ## Name)(); \ } \ testingprivMkCtor(Test ## Name) \ - void testingprivImplName(Test ## Name)(int *testingprivRet) + void testingprivImplName(Test ## Name)(void) -// These can only be called directly from the Test functions. -// TODO make it otherwise -#define TestFail() (*testingprivRet = 1) -#define TestFailNow() {TestFail(); return;} -// see https://mesonbuild.com/Unit-tests.html#skipped-tests-and-hard-errors -#define TestSkipNow() {*testingprivRet = 77; return;} +extern void TestFail(void); +extern void TestFailNow(void); +extern void TestSkipNow(void); #define TestLogf(...) \ - (testingprivLogf(stdout, __FILE__, __LINE__, __VA_ARGS__)) + (testingprivLogfFullThen(stdout, NULL, __FILE__, __LINE__, __VA_ARGS__)) #define TestErrorf(...) \ - {testingprivLogf(stderr, __FILE__, __LINE__, __VA_ARGS__); TestFail();} + (testingprivLogfFullThen(stderr, TestFail, __FILE__, __LINE__, __VA_ARGS__)) #define TestFatalf(...) \ - {testingprivLogf(stderr, __FILE__, __LINE__, __VA_ARGS__); TestFailNow();} + (testingprivLogfFullThen(stderr, TestFailNow, __FILE__, __LINE__, __VA_ARGS__)) // TODO remember if this needs to go to stdout or to stderr #define TestSkipf(...) \ - {testingprivLogf(stderr, __FILE__, __LINE__, __VA_ARGS__); TestSkipNow();} + (testingprivLogfFullThen(stderr, TestSkipNow, __FILE__, __LINE__, __VA_ARGS__)) -extern void testingprivRegisterTest(const char *name, int (*f)(void)); +extern void testingprivRegisterTest(const char *name, void (*f)(void)); #include "../sharedbits/printfwarn_header.h" sharedbitsPrintfFunc( - extern void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt, ...), - 4, 5); + extern void testingprivLogfFullThen(FILE *f, void (*then)(void), const char *filename, long line, const char *fmt, ...), + 5, 6); #undef sharedbitsPrintfFunc // end of test framework definitions