Allowed deferred functions to access the testingT. If they call FailNow, we act as if nothing happens and the defers keep running.

This commit is contained in:
Pietro Gagliardi 2019-04-10 14:27:21 -04:00
parent 0149639edc
commit 759d6d1e46
2 changed files with 13 additions and 7 deletions

View File

@ -7,7 +7,7 @@
#define testingprivNew(T) ((T *) malloc(sizeof (T))) #define testingprivNew(T) ((T *) malloc(sizeof (T)))
struct defer { struct defer {
void (*f)(void *); void (*f)(testingT *, void *);
void *data; void *data;
struct defer *next; struct defer *next;
}; };
@ -17,6 +17,7 @@ struct testingT {
void (*f)(testingT *); void (*f)(testingT *);
int failed; int failed;
int skipped; int skipped;
int returned;
jmp_buf returnNowBuf; jmp_buf returnNowBuf;
struct defer *defers; struct defer *defers;
int defersRun; int defersRun;
@ -35,6 +36,7 @@ static void testingprivNewTest(const char *name, void (*f)(testingT *), testingT
t->f = f; t->f = f;
t->failed = 0; t->failed = 0;
t->skipped = 0; t->skipped = 0;
t->returned = 0;
t->defers = NULL; t->defers = NULL;
t->defersRun = 0; t->defersRun = 0;
t->next = testsTail; t->next = testsTail;
@ -59,7 +61,7 @@ static void runDefers(testingT *t)
return; return;
t->defersRun = 1; t->defersRun = 1;
for (d = t->defers; d != NULL; d = d->next) for (d = t->defers; d != NULL; d = d->next)
(*(d->f))(d->data); (*(d->f))(t, d->data);
} }
static void runTestSet(testingT *t, int *anyFailed) static void runTestSet(testingT *t, int *anyFailed)
@ -70,6 +72,7 @@ static void runTestSet(testingT *t, int *anyFailed)
printf("=== RUN %s\n", t->name); printf("=== RUN %s\n", t->name);
if (setjmp(t->returnNowBuf) == 0) if (setjmp(t->returnNowBuf) == 0)
(*(t->f))(t); (*(t->f))(t);
t->returned = 1;
runDefers(t); runDefers(t);
status = "PASS"; status = "PASS";
if (t->failed) { if (t->failed) {
@ -129,10 +132,14 @@ void testingTFail(testingT *t)
static void returnNow(testingT *t) static void returnNow(testingT *t)
{ {
if (!t->returned) {
// set this now so a FailNow inside a Defer doesn't longjmp twice
t->returned = 1;
// run defers before calling longjmp() just to be safe // run defers before calling longjmp() just to be safe
runDefers(t); runDefers(t);
longjmp(t->returnNowBuf, 1); longjmp(t->returnNowBuf, 1);
} }
}
void testingprivTFailNow(testingT *t) void testingprivTFailNow(testingT *t)
{ {

View File

@ -61,8 +61,7 @@ typedef struct testingT testingT;
extern void testingTFail(testingT *t); extern void testingTFail(testingT *t);
extern void testingTFailNow(testingT *t); extern void testingTFailNow(testingT *t);
extern void testingTSkipNow(testingT *t); extern void testingTSkipNow(testingT *t);
// TODO should the defered function also have t passed to it? extern void testingTDefer(testingT *t, void (*f)(testingT *t, void *data), void *data);
extern void testingTDefer(testingT *t, void (*f)(void *data), void *data);
extern void testingprivRegisterTest(const char *, void (*)(testingT *)); extern void testingprivRegisterTest(const char *, void (*)(testingT *));
extern void testingprivRegisterManualTest(const char *, void (*)(testingT *)); extern void testingprivRegisterManualTest(const char *, void (*)(testingT *));