Finished the test set implementation, moving the tester itself to use it. This also moves uiInit() into main(); in TestInit, we'll hook into uiInit() to avoid actually doing the initialization.

This commit is contained in:
Pietro Gagliardi 2019-05-10 21:16:29 -04:00
parent 7f986ef073
commit 07dc3ee025
5 changed files with 66 additions and 41 deletions

View File

@ -4,10 +4,12 @@
#include "lib/thread.h" #include "lib/thread.h"
#include "test.h" #include "test.h"
testingSet *beforeTests = NULL;
#define errInvalidOptions "options parameter to uiInit() must be NULL" #define errInvalidOptions "options parameter to uiInit() must be NULL"
#define errAlreadyInitialized "libui already initialized" #define errAlreadyInitialized "libui already initialized"
testingTestBefore(Init) testingTestInSet(beforeTests, Init)
{ {
uiInitError err; uiInitError err;
int ret; int ret;
@ -31,12 +33,12 @@ testingTestBefore(Init)
if (strcmp(err.Message, errInvalidOptions) != 0) if (strcmp(err.Message, errInvalidOptions) != 0)
diff(t, "uiInit() with non-NULL options returned bad error message", "%s", diff(t, "uiInit() with non-NULL options returned bad error message", "%s",
err.Message, errInvalidOptions); err.Message, errInvalidOptions);
}
memset(&err, 0, sizeof (uiInitError)); testingTest(InitAfterInitialized)
err.Size = sizeof (uiInitError); {
ret = uiInit(NULL, &err); uiInitError err;
if (ret == 0) int ret;
testingTErrorf(t, "uiInit() failed: %s", err.Message);
memset(&err, 0, sizeof (uiInitError)); memset(&err, 0, sizeof (uiInitError));
err.Size = sizeof (uiInitError); err.Size = sizeof (uiInitError);

View File

@ -236,8 +236,13 @@ void testingprivSetRegisterTest(testingSet **pset, const char *name, void (*f)(t
testingSet *set; testingSet *set;
set = &mainTests; set = &mainTests;
if (pset != NULL) if (pset != NULL) {
set = *pset; set = *pset;
if (set == NULL) {
set = new(testingSet);
*pset = set;
}
}
if (set->len == set->cap) { if (set->len == set->cap) {
size_t prevcap; size_t prevcap;
@ -276,11 +281,11 @@ static void runDefers(testingT *t)
(*(d->f))(t, d->data); (*(d->f))(t, d->data);
} }
static testingOptions opts = { static const testingOptions defaultOptions = {
.Verbose = 0, .Verbose = 0,
}; };
static int testsetprivRun(testingSet *set, int indent) static void testingprivSetRun(testingSet *set, const testingOptions *options, int indent, int *anyFailed)
{ {
size_t i; size_t i;
testingT *t; testingT *t;
@ -288,15 +293,14 @@ static int testsetprivRun(testingSet *set, int indent)
timerTime start, end; timerTime start, end;
char timerstr[timerDurationStringLen]; char timerstr[timerDurationStringLen];
int printStatus; int printStatus;
int anyFailed = 0;
qsort(set->tests, set->len, sizeof (testingT), testcmp); qsort(set->tests, set->len, sizeof (testingT), testcmp);
t = set->tests; t = set->tests;
for (i = 0; i < set->len; i++) { for (i = 0; i < set->len; i++) {
if (opts.Verbose) if (options->Verbose)
outbufPrintf(NULL, indent, "=== RUN %s", t->name); outbufPrintf(NULL, indent, "=== RUN %s", t->name);
t->indent = indent + 1; t->indent = indent + 1;
t->verbose = opts.Verbose; t->verbose = options->Verbose;
start = timerMonotonicNow(); start = timerMonotonicNow();
if (setjmp(t->returnNowBuf) == 0) if (setjmp(t->returnNowBuf) == 0)
(*(t->f))(t); (*(t->f))(t);
@ -308,7 +312,7 @@ static int testsetprivRun(testingSet *set, int indent)
if (t->failed) { if (t->failed) {
status = "FAIL"; status = "FAIL";
printStatus = 1; // always print status on failure printStatus = 1; // always print status on failure
anyFailed = 1; *anyFailed = 1;
} else if (t->skipped) } else if (t->skipped)
// note that failed overrides skipped // note that failed overrides skipped
status = "SKIP"; status = "SKIP";
@ -319,37 +323,20 @@ static int testsetprivRun(testingSet *set, int indent)
} }
t++; 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) if (set == NULL)
set = &mainTests; set = &mainTests;
if (options == NULL)
// TODO see if this should run if all tests are skipped options = &defaultOptions;
if (set->len == 0) { if (set->len == 0)
$$TODOTODO fprintf(stderr, "warning: no tests to run\n"); return;
// imitate Go here (TODO confirm this) testingprivSetRun(set, options, 0, anyFailed);
return 0; *anyRun = 1;
}
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;
} }
void testingprivTLogfFull(testingT *t, const char *file, long line, const char *format, ...) void testingprivTLogfFull(testingT *t, const char *file, long line, const char *format, ...)

View File

@ -45,7 +45,7 @@ struct testingOptions {
int Verbose; 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; typedef struct testingT testingT;
#define testingTLogf(t, ...) \ #define testingTLogf(t, ...) \

View File

@ -8,9 +8,23 @@ void timeoutMain(void *data)
uiMain(); 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[]) int main(int argc, char *argv[])
{ {
testingOptions opts; testingOptions opts;
int anyRun = 0, anyFailed = 0;
uiInitError err;
int ret;
memset(&opts, 0, sizeof (testingOptions)); memset(&opts, 0, sizeof (testingOptions));
if (argc == 2 && strcmp(argv[1], "-v") == 0) 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]); fprintf(stderr, "usage: %s [-v]\n", argv[0]);
return 1; 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;
} }

View File

@ -22,3 +22,6 @@ extern void timeoutMain(void *data);
testingTErrorf(t, "uiMain() timed out (%s)", timeoutstr); \ testingTErrorf(t, "uiMain() timed out (%s)", timeoutstr); \
} \ } \
} }
// init.c
extern testingSet *beforeTests;