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:
parent
7f986ef073
commit
07dc3ee025
|
@ -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);
|
||||||
|
|
|
@ -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, ...)
|
||||||
|
|
|
@ -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, ...) \
|
||||||
|
|
35
test/main.c
35
test/main.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue