diff --git a/test/initmain.c b/test/initmain.c index 8f80a651..209a46a2 100644 --- a/test/initmain.c +++ b/test/initmain.c @@ -4,10 +4,12 @@ #include "lib/thread.h" #include "test.h" +testingSet *beforeTests = NULL; + #define errInvalidOptions "options parameter to uiInit() must be NULL" #define errAlreadyInitialized "libui already initialized" -testingTestBefore(Init) +testingTestInSet(beforeTests, Init) { uiInitError err; int ret; @@ -31,12 +33,12 @@ testingTestBefore(Init) if (strcmp(err.Message, errInvalidOptions) != 0) diff(t, "uiInit() with non-NULL options returned bad error message", "%s", err.Message, errInvalidOptions); +} - memset(&err, 0, sizeof (uiInitError)); - err.Size = sizeof (uiInitError); - ret = uiInit(NULL, &err); - if (ret == 0) - testingTErrorf(t, "uiInit() failed: %s", err.Message); +testingTest(InitAfterInitialized) +{ + uiInitError err; + int ret; memset(&err, 0, sizeof (uiInitError)); err.Size = sizeof (uiInitError); diff --git a/test/lib/testing.c b/test/lib/testing.c index bcdb5d3b..e791fd2b 100644 --- a/test/lib/testing.c +++ b/test/lib/testing.c @@ -236,8 +236,13 @@ void testingprivSetRegisterTest(testingSet **pset, const char *name, void (*f)(t testingSet *set; set = &mainTests; - if (pset != NULL) + if (pset != NULL) { set = *pset; + if (set == NULL) { + set = new(testingSet); + *pset = set; + } + } if (set->len == set->cap) { size_t prevcap; @@ -276,11 +281,11 @@ static void runDefers(testingT *t) (*(d->f))(t, d->data); } -static testingOptions opts = { +static const testingOptions defaultOptions = { .Verbose = 0, }; -static int testsetprivRun(testingSet *set, int indent) +static void testingprivSetRun(testingSet *set, const testingOptions *options, int indent, int *anyFailed) { size_t i; testingT *t; @@ -288,15 +293,14 @@ static int testsetprivRun(testingSet *set, int indent) timerTime start, end; char timerstr[timerDurationStringLen]; int printStatus; - int anyFailed = 0; qsort(set->tests, set->len, sizeof (testingT), testcmp); t = set->tests; for (i = 0; i < set->len; i++) { - if (opts.Verbose) + if (options->Verbose) outbufPrintf(NULL, indent, "=== RUN %s", t->name); t->indent = indent + 1; - t->verbose = opts.Verbose; + t->verbose = options->Verbose; start = timerMonotonicNow(); if (setjmp(t->returnNowBuf) == 0) (*(t->f))(t); @@ -308,7 +312,7 @@ static int testsetprivRun(testingSet *set, int indent) if (t->failed) { status = "FAIL"; printStatus = 1; // always print status on failure - anyFailed = 1; + *anyFailed = 1; } else if (t->skipped) // note that failed overrides skipped status = "SKIP"; @@ -319,37 +323,20 @@ static int testsetprivRun(testingSet *set, int indent) } t++; } - return anyFailed; } -int testingMain(testingSet *set, const struct testingOptions *options) +void testingSetRun(testingSet *set, const struct testingOptions *options, int *anyRun, int *anyFailed) { - int anyFailed; - + *anyRun = 0; + *anyFailed = 0; if (set == NULL) set = &mainTests; - - // TODO see if this should run if all tests are skipped - if (set->len == 0) { -$$TODOTODO fprintf(stderr, "warning: no tests to run\n"); - // imitate Go here (TODO confirm this) - return 0; - } - - return testingprivRun(set, 0); -}$$TODOTODO{ - // TODO print a warning that we skip the next stages if a prior stage failed? - if (!anyFailed) - testsetRun(&tests, 0, &anyFailed); - // TODO should we unconditionally run these tests if before succeeded but the main tests failed? - if (!anyFailed) - testsetRun(&testsAfter, 0, &anyFailed); - if (anyFailed) { - printf("FAIL\n"); - return 1; - } - printf("PASS\n"); - return 0; + if (options == NULL) + options = &defaultOptions; + if (set->len == 0) + return; + testingprivSetRun(set, options, 0, anyFailed); + *anyRun = 1; } void testingprivTLogfFull(testingT *t, const char *file, long line, const char *format, ...) diff --git a/test/lib/testing.h b/test/lib/testing.h index 106d6039..55198588 100644 --- a/test/lib/testing.h +++ b/test/lib/testing.h @@ -45,7 +45,7 @@ struct testingOptions { int Verbose; }; -extern int testingSetRun(testingSet *set, const struct testingOptions *options); +extern void testingSetRun(testingSet *set, const struct testingOptions *options, int *anyRun, int *anyFailed); typedef struct testingT testingT; #define testingTLogf(t, ...) \ diff --git a/test/main.c b/test/main.c index d0245652..4ffaf24b 100644 --- a/test/main.c +++ b/test/main.c @@ -8,9 +8,23 @@ void timeoutMain(void *data) uiMain(); } +static void runSetORingResults(testingSet *set, const struct testingOptions *options, int *anyRun, int *anyFailed) +{ + int ar, af; + + testingSetRun(set, options, &ar, &af); + if (ar) + *anyRun = 1; + if (af) + *anyFailed = 1; +} + int main(int argc, char *argv[]) { testingOptions opts; + int anyRun = 0, anyFailed = 0; + uiInitError err; + int ret; memset(&opts, 0, sizeof (testingOptions)); if (argc == 2 && strcmp(argv[1], "-v") == 0) @@ -19,5 +33,24 @@ int main(int argc, char *argv[]) fprintf(stderr, "usage: %s [-v]\n", argv[0]); return 1; } - return testingMain(&opts); + + runSetORingResults(beforeTests, &opts, &anyRun, &anyFailed); + memset(&err, 0, sizeof (uiInitError)); + err.Size = sizeof (uiInitError); + ret = uiInit(NULL, &err); + if (ret == 0) { + fprintf(stderr, "uiInit() failed: %s; can't continue", err.Message); + printf("FAIL\n"); + return 1; + } + runSetORingResults(NULL, &opts, &anyRun, &anyFailed); + + if (!anyRun) + fprintf(stderr, "warning: no tests to run\n"); + if (anyFailed) { + printf("FAIL\n"); + return 1; + } + printf("PASS\n"); + return 0; } diff --git a/test/test.h b/test/test.h index 9723c3f8..c71d44aa 100644 --- a/test/test.h +++ b/test/test.h @@ -22,3 +22,6 @@ extern void timeoutMain(void *data); testingTErrorf(t, "uiMain() timed out (%s)", timeoutstr); \ } \ } + +// init.c +extern testingSet *beforeTests;