Started adding more flexible test set functionality.
This commit is contained in:
parent
f97383f66c
commit
7f986ef073
|
@ -223,18 +223,21 @@ static void initTest(testingT *t, const char *name, void (*f)(testingT *), const
|
||||||
|
|
||||||
#define nGrow 32
|
#define nGrow 32
|
||||||
|
|
||||||
struct testset {
|
struct testingSet {
|
||||||
testingT *tests;
|
testingT *tests;
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t cap;
|
size_t cap;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct testset tests = { NULL, 0, 0 };
|
static testingSet mainTests = { NULL, 0, 0 };
|
||||||
static struct testset testsBefore = { NULL, 0, 0 };
|
|
||||||
static struct testset testsAfter = { 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) {
|
if (set->len == set->cap) {
|
||||||
size_t prevcap;
|
size_t prevcap;
|
||||||
|
|
||||||
|
@ -246,21 +249,6 @@ static void testsetAdd(struct testset *set, const char *name, void (*f)(testingT
|
||||||
set->len++;
|
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)
|
static int testcmp(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const testingT *ta = (const testingT *) a;
|
const testingT *ta = (const testingT *) a;
|
||||||
|
@ -277,11 +265,6 @@ static int testcmp(const void *a, const void *b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void testsetSort(struct testset *set)
|
|
||||||
{
|
|
||||||
qsort(set->tests, set->len, sizeof (testingT), testcmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void runDefers(testingT *t)
|
static void runDefers(testingT *t)
|
||||||
{
|
{
|
||||||
struct defer *d;
|
struct defer *d;
|
||||||
|
@ -297,7 +280,7 @@ static testingOptions opts = {
|
||||||
.Verbose = 0,
|
.Verbose = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void testsetRun(struct testset *set, int indent, int *anyFailed)
|
static int testsetprivRun(testingSet *set, int indent)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
testingT *t;
|
testingT *t;
|
||||||
|
@ -305,7 +288,9 @@ static void testsetRun(struct testset *set, int indent, int *anyFailed)
|
||||||
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);
|
||||||
t = set->tests;
|
t = set->tests;
|
||||||
for (i = 0; i < set->len; i++) {
|
for (i = 0; i < set->len; i++) {
|
||||||
if (opts.Verbose)
|
if (opts.Verbose)
|
||||||
|
@ -323,7 +308,7 @@ static void testsetRun(struct testset *set, int indent, int *anyFailed)
|
||||||
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";
|
||||||
|
@ -334,28 +319,25 @@ static void testsetRun(struct testset *set, int indent, int *anyFailed)
|
||||||
}
|
}
|
||||||
t++;
|
t++;
|
||||||
}
|
}
|
||||||
|
return anyFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int testingMain(const struct testingOptions *options)
|
int testingMain(testingSet *set, const struct testingOptions *options)
|
||||||
{
|
{
|
||||||
int anyFailed;
|
int anyFailed;
|
||||||
|
|
||||||
if (options != NULL)
|
if (set == NULL)
|
||||||
opts = *options;
|
set = &mainTests;
|
||||||
|
|
||||||
// TODO see if this should run if all tests are skipped
|
// TODO see if this should run if all tests are skipped
|
||||||
if ((testsBefore.len + tests.len + testsAfter.len) == 0) {
|
if (set->len == 0) {
|
||||||
fprintf(stderr, "warning: no tests to run\n");
|
$$TODOTODO fprintf(stderr, "warning: no tests to run\n");
|
||||||
// imitate Go here (TODO confirm this)
|
// imitate Go here (TODO confirm this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
testsetSort(&testsBefore);
|
return testingprivRun(set, 0);
|
||||||
testsetSort(&tests);
|
}$$TODOTODO{
|
||||||
testsetSort(&testsAfter);
|
|
||||||
|
|
||||||
anyFailed = 0;
|
|
||||||
testsetRun(&testsBefore, 0, &anyFailed);
|
|
||||||
// TODO print a warning that we skip the next stages if a prior stage failed?
|
// TODO print a warning that we skip the next stages if a prior stage failed?
|
||||||
if (!anyFailed)
|
if (!anyFailed)
|
||||||
testsetRun(&tests, 0, &anyFailed);
|
testsetRun(&tests, 0, &anyFailed);
|
||||||
|
|
|
@ -16,37 +16,36 @@
|
||||||
#define testingprivCtorName(basename) testingprivCtor ## basename
|
#define testingprivCtorName(basename) testingprivCtor ## basename
|
||||||
#define testingprivCtorPtrName(basename) testingprivCtorPtr ## basename
|
#define testingprivCtorPtrName(basename) testingprivCtorPtr ## basename
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#define testingprivMkCtor(basename, regfunc) \
|
#define testingprivMkCtor(basename, pset) \
|
||||||
__attribute__((constructor)) static void testingprivCtorName(basename)(void) { regfunc(#basename, testingprivScaffoldName(basename), __FILE__, __LINE__); }
|
__attribute__((constructor)) static void testingprivCtorName(basename)(void) { testingprivSetRegisterTest(pset, #basename, testingprivScaffoldName(basename), __FILE__, __LINE__); }
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#define testingprivMkCtor(basename, regfunc) \
|
#define testingprivMkCtor(basename, pset) \
|
||||||
static int testingprivCtorName(basename)(void) { regfunc(#basename, testingprivScaffoldName(basename), __FILE__, __LINE__); return 0; } \
|
static int testingprivCtorName(basename)(void) { testingprivSetRegisterTest(pset, #basename, testingprivScaffoldName(basename), __FILE__, __LINE__); return 0; } \
|
||||||
__pragma(section(".CRT$XCU",read)) \
|
__pragma(section(".CRT$XCU",read)) \
|
||||||
__declspec(allocate(".CRT$XCU")) static int (*testingprivCtorPtrName(basename))(void) = testingprivCtorName(basename);
|
__declspec(allocate(".CRT$XCU")) static int (*testingprivCtorPtrName(basename))(void) = testingprivCtorName(basename);
|
||||||
#else
|
#else
|
||||||
#error unknown compiler for making constructors in C; cannot continue
|
#error unknown compiler for making constructors in C; cannot continue
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define testingprivMk(basename, argtype, argname, regfunc) \
|
#define testingprivMk(basename, argtype, argname, pset) \
|
||||||
void testingprivImplName(basename)(argtype *argname); \
|
void testingprivImplName(basename)(argtype *argname); \
|
||||||
testingprivMkScaffold(basename, argtype, argname) \
|
testingprivMkScaffold(basename, argtype, argname) \
|
||||||
testingprivMkCtor(basename, regfunc) \
|
testingprivMkCtor(basename, pset) \
|
||||||
void testingprivImplName(basename)(argtype *argname)
|
void testingprivImplName(basename)(argtype *argname)
|
||||||
|
|
||||||
#define testingTest(Name) \
|
#define testingTest(Name) \
|
||||||
testingprivMk(Test ## Name, testingT, t, testingprivRegisterTest)
|
testingprivMk(Test ## Name, testingT, t, NULL)
|
||||||
#define testingTestBefore(Name) \
|
#define testingTestInSet(Set, Name) \
|
||||||
testingprivMk(Test ## Name, testingT, t, testingprivRegisterTestBefore)
|
testingprivMk(Test ## Name, testingT, t, &Set)
|
||||||
#define testingTestAfter(Name) \
|
|
||||||
testingprivMk(Test ## Name, testingT, t, testingprivRegisterTestAfter)
|
|
||||||
|
|
||||||
|
typedef struct testingSet testingSet;
|
||||||
typedef struct testingOptions testingOptions;
|
typedef struct testingOptions testingOptions;
|
||||||
|
|
||||||
struct testingOptions {
|
struct testingOptions {
|
||||||
int Verbose;
|
int Verbose;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int testingMain(const struct testingOptions *options);
|
extern int testingSetRun(testingSet *set, const struct testingOptions *options);
|
||||||
|
|
||||||
typedef struct testingT testingT;
|
typedef struct testingT testingT;
|
||||||
#define testingTLogf(t, ...) \
|
#define testingTLogf(t, ...) \
|
||||||
|
@ -70,9 +69,7 @@ extern void testingTFailNow(testingT *t);
|
||||||
extern void testingTSkipNow(testingT *t);
|
extern void testingTSkipNow(testingT *t);
|
||||||
extern void testingTDefer(testingT *t, void (*f)(testingT *t, void *data), void *data);
|
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 testingprivSetRegisterTest(testingSet **pset, 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);
|
|
||||||
// see https://stackoverflow.com/questions/32399191/va-args-expansion-using-msvc
|
// see https://stackoverflow.com/questions/32399191/va-args-expansion-using-msvc
|
||||||
#define testingprivExpand(x) x
|
#define testingprivExpand(x) x
|
||||||
#define testingprivTLogfThen(then, t, ...) ((testingprivTLogfFull(t, __FILE__, __LINE__, __VA_ARGS__)), (then(t)))
|
#define testingprivTLogfThen(then, t, ...) ((testingprivTLogfFull(t, __FILE__, __LINE__, __VA_ARGS__)), (then(t)))
|
||||||
|
|
Loading…
Reference in New Issue