From 7f986ef0736200054d94a57092f84bcd56123401 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Thu, 9 May 2019 22:54:14 -0400 Subject: [PATCH] Started adding more flexible test set functionality. --- test/lib/testing.c | 58 ++++++++++++++++------------------------------ test/lib/testing.h | 27 ++++++++++----------- 2 files changed, 32 insertions(+), 53 deletions(-) diff --git a/test/lib/testing.c b/test/lib/testing.c index a4ecdcb2..bcdb5d3b 100644 --- a/test/lib/testing.c +++ b/test/lib/testing.c @@ -223,18 +223,21 @@ static void initTest(testingT *t, const char *name, void (*f)(testingT *), const #define nGrow 32 -struct testset { +struct testingSet { testingT *tests; size_t len; size_t cap; }; -static struct testset tests = { NULL, 0, 0 }; -static struct testset testsBefore = { NULL, 0, 0 }; -static struct testset testsAfter = { NULL, 0, 0 }; +static testingSet mainTests = { NULL, 0, 0 }; -static void testsetAdd(struct testset *set, const char *name, void (*f)(testingT *), const char *file, long line) +void testingprivSetRegisterTest(testingSet **pset, const char *name, void (*f)(testingT *), const char *file, long line) { + testingSet *set; + + set = &mainTests; + if (pset != NULL) + set = *pset; if (set->len == set->cap) { size_t prevcap; @@ -246,21 +249,6 @@ static void testsetAdd(struct testset *set, const char *name, void (*f)(testingT set->len++; } -void testingprivRegisterTest(const char *name, void (*f)(testingT *), const char *file, long line) -{ - testsetAdd(&tests, name, f, file, line); -} - -void testingprivRegisterTestBefore(const char *name, void (*f)(testingT *), const char *file, long line) -{ - testsetAdd(&testsBefore, name, f, file, line); -} - -void testingprivRegisterTestAfter(const char *name, void (*f)(testingT *), const char *file, long line) -{ - testsetAdd(&testsAfter, name, f, file, line); -} - static int testcmp(const void *a, const void *b) { const testingT *ta = (const testingT *) a; @@ -277,11 +265,6 @@ static int testcmp(const void *a, const void *b) return 0; } -static void testsetSort(struct testset *set) -{ - qsort(set->tests, set->len, sizeof (testingT), testcmp); -} - static void runDefers(testingT *t) { struct defer *d; @@ -297,7 +280,7 @@ static testingOptions opts = { .Verbose = 0, }; -static void testsetRun(struct testset *set, int indent, int *anyFailed) +static int testsetprivRun(testingSet *set, int indent) { size_t i; testingT *t; @@ -305,7 +288,9 @@ static void testsetRun(struct testset *set, int indent, int *anyFailed) 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) @@ -323,7 +308,7 @@ static void testsetRun(struct testset *set, int indent, int *anyFailed) 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"; @@ -334,28 +319,25 @@ static void testsetRun(struct testset *set, int indent, int *anyFailed) } t++; } + return anyFailed; } -int testingMain(const struct testingOptions *options) +int testingMain(testingSet *set, const struct testingOptions *options) { int anyFailed; - if (options != NULL) - opts = *options; + if (set == NULL) + set = &mainTests; // TODO see if this should run if all tests are skipped - if ((testsBefore.len + tests.len + testsAfter.len) == 0) { - fprintf(stderr, "warning: no tests to run\n"); + if (set->len == 0) { +$$TODOTODO fprintf(stderr, "warning: no tests to run\n"); // imitate Go here (TODO confirm this) return 0; } - testsetSort(&testsBefore); - testsetSort(&tests); - testsetSort(&testsAfter); - - anyFailed = 0; - testsetRun(&testsBefore, 0, &anyFailed); + 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); diff --git a/test/lib/testing.h b/test/lib/testing.h index 151d5f14..106d6039 100644 --- a/test/lib/testing.h +++ b/test/lib/testing.h @@ -16,37 +16,36 @@ #define testingprivCtorName(basename) testingprivCtor ## basename #define testingprivCtorPtrName(basename) testingprivCtorPtr ## basename #if defined(__GNUC__) -#define testingprivMkCtor(basename, regfunc) \ - __attribute__((constructor)) static void testingprivCtorName(basename)(void) { regfunc(#basename, testingprivScaffoldName(basename), __FILE__, __LINE__); } +#define testingprivMkCtor(basename, pset) \ + __attribute__((constructor)) static void testingprivCtorName(basename)(void) { testingprivSetRegisterTest(pset, #basename, testingprivScaffoldName(basename), __FILE__, __LINE__); } #elif defined(_MSC_VER) -#define testingprivMkCtor(basename, regfunc) \ - static int testingprivCtorName(basename)(void) { regfunc(#basename, testingprivScaffoldName(basename), __FILE__, __LINE__); return 0; } \ +#define testingprivMkCtor(basename, pset) \ + static int testingprivCtorName(basename)(void) { testingprivSetRegisterTest(pset, #basename, testingprivScaffoldName(basename), __FILE__, __LINE__); return 0; } \ __pragma(section(".CRT$XCU",read)) \ __declspec(allocate(".CRT$XCU")) static int (*testingprivCtorPtrName(basename))(void) = testingprivCtorName(basename); #else #error unknown compiler for making constructors in C; cannot continue #endif -#define testingprivMk(basename, argtype, argname, regfunc) \ +#define testingprivMk(basename, argtype, argname, pset) \ void testingprivImplName(basename)(argtype *argname); \ testingprivMkScaffold(basename, argtype, argname) \ - testingprivMkCtor(basename, regfunc) \ + testingprivMkCtor(basename, pset) \ void testingprivImplName(basename)(argtype *argname) #define testingTest(Name) \ - testingprivMk(Test ## Name, testingT, t, testingprivRegisterTest) -#define testingTestBefore(Name) \ - testingprivMk(Test ## Name, testingT, t, testingprivRegisterTestBefore) -#define testingTestAfter(Name) \ - testingprivMk(Test ## Name, testingT, t, testingprivRegisterTestAfter) + testingprivMk(Test ## Name, testingT, t, NULL) +#define testingTestInSet(Set, Name) \ + testingprivMk(Test ## Name, testingT, t, &Set) +typedef struct testingSet testingSet; typedef struct testingOptions testingOptions; struct testingOptions { int Verbose; }; -extern int testingMain(const struct testingOptions *options); +extern int testingSetRun(testingSet *set, const struct testingOptions *options); typedef struct testingT testingT; #define testingTLogf(t, ...) \ @@ -70,9 +69,7 @@ extern void testingTFailNow(testingT *t); extern void testingTSkipNow(testingT *t); extern void testingTDefer(testingT *t, void (*f)(testingT *t, void *data), void *data); -extern void testingprivRegisterTest(const char *, void (*)(testingT *), const char *, long); -extern void testingprivRegisterTestBefore(const char *, void (*)(testingT *), const char *, long); -extern void testingprivRegisterTestAfter(const char *, void (*)(testingT *), const char *, long); +extern void testingprivSetRegisterTest(testingSet **pset, const char *, void (*)(testingT *), const char *, long); // see https://stackoverflow.com/questions/32399191/va-args-expansion-using-msvc #define testingprivExpand(x) x #define testingprivTLogfThen(then, t, ...) ((testingprivTLogfFull(t, __FILE__, __LINE__, __VA_ARGS__)), (then(t)))