diff --git a/test/errors.c b/test/errors.c new file mode 100644 index 00000000..fc6be3bb --- /dev/null +++ b/test/errors.c @@ -0,0 +1,75 @@ +// 28 may 2019 +#include "test.h" + +struct checkProgrammerErrorParams { + const char *file; + long line; + void (*f)(void *data); + void *data; + bool inThread; + bool caught; + char *msgGot; + const char *msgWant; +}; + +static void handleProgrammerError(const char *msg, void *data) +{ + struct checkProgrammerErrorParams *p = (struct checkProgrammerErrorParams *) data; + + p->caught = true; + if (strcmp(msg, p->msgWant) != 0) + p->msgGot = testingUtilStrdup(msg); +} + +static void deferResetProgrammerError(testingT *t, void *data) +{ + uiprivTestHookReportProgrammerError(NULL, NULL); +} + +static void checkProgrammerErrorThreadProc(void *data) +{ + struct checkProgrammerErrorParams *p = (struct checkProgrammerErrorParams *) data; + + (*(p->f))(p->data); +} + +static void checkProgrammerErrorSubtestImpl(testingT *t, void *data) +{ + struct checkProgrammerErrorParams *p = (struct checkProgrammerErrorParams *) data; + + uiprivTestHookReportProgrammerError(handleProgrammerError, p); + testingTDefer(t, deferResetProgrammerError, NULL); + if (p->inThread) { + threadThread *thread; + threadSysError err; + + err = threadNewThread(checkProgrammerErrorThreadProc, p, &thread); + if (err != 0) + testingTFatalfFull(t, p->file, p->line, "error creating thread: " threadSysErrorFmt, threadSysErrorFmtArg(err)); + err = threadThreadWaitAndFree(thread); + if (err != 0) + testingTFatalfFull(t, p->file, p->line, "error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err)); + } else + (*(p->f))(p->data); + if (!p->caught) + testingTErrorfFull(t, p->file, p->line, "did not throw a programmer error; should have"); + if (p->msgGot != NULL) { + testingTErrorfFull(t, p->file, p->line, "message doesn't match expected string:" diff("%s"), + p->msgGot, p->msgWant); + testingUtilFreeStrdup(p->msgGot); + } +} + +void checkProgrammerErrorFull(testingT *t, const char *file, long line, const char *name, void (*f)(void *data), void *data, const char *msgWant, bool inThread) +{ + struct checkProgrammerErrorParams p; + + memset(&p, 0, sizeof (struct checkProgrammerErrorParams)); + p.file = file; + p.line = line; + p.f = f; + p.data = data; + p.inThread = inThread; + p.msgWant = msgWant; + testingTRun(t, name, checkProgrammerErrorSubtestImpl, &p); +} diff --git a/test/events.c b/test/events.c index c5d30f3c..21ea89bf 100644 --- a/test/events.c +++ b/test/events.c @@ -916,8 +916,9 @@ testingTest(EventInvalidateSender) runArgsSubtests(t, &p); } +#if 0 +TODOTODO // TODO table-ize these -// TODO deduplicate this from the one in noinitwrongthread.c? static void testWhileFiring(void *sender, void *args, void *data) { @@ -1054,3 +1055,5 @@ testingTest(EventErrors) "uiEventFree(): can't free event that still has handlers registered"); uiEventFire(firingEvent, NULL, firingEvent); } + +#endif diff --git a/test/main.c b/test/main.c index cbbea083..f369f4df 100644 --- a/test/main.c +++ b/test/main.c @@ -6,16 +6,6 @@ void timeoutMain(void *data) uiMain(); } -void catchProgrammerError(const char *msg, void *data) -{ - struct errorParams *errorParams = (struct errorParams *) data; - - errorParams->caught = true; - if (strcmp(msg, errorParams->msgWant) != 0) - testingTErrorfFull(errorParams->t, errorParams->file, errorParams->line, "%s: message doesn't match expected string:" diff("%s"), - errorParams->exprstr, msg, errorParams->msgWant); -} - static void runSetORingResults(testingSet *set, const struct testingOptions *options, bool *anyRun, bool *anyFailed) { bool ar, af; diff --git a/test/meson.build b/test/meson.build index d54c818d..0b9e0b50 100644 --- a/test/meson.build +++ b/test/meson.build @@ -2,6 +2,7 @@ libui_test_sources = [ 'controls.c', + 'errors.c', 'events.c', 'initmain.c', 'main.c', diff --git a/test/noinitwrongthread.c b/test/noinitwrongthread.c index c13a8441..61113177 100644 --- a/test/noinitwrongthread.c +++ b/test/noinitwrongthread.c @@ -1,82 +1,6 @@ // 28 may 2019 #include "test.h" -struct checkProgrammerErrorParams { - const char *file; - long line; - void (*f)(void *data); - void *data; - bool inThread; - bool caught; - char *msgGot; - const char *msgWant; -}; - -static void handleProgrammerError(const char *msg, void *data) -{ - struct checkProgrammerErrorParams *p = (struct checkProgrammerErrorParams *) data; - - p->caught = true; - if (strcmp(msg, p->msgWant) != 0) - p->msgGot = testingUtilStrdup(msg); -} - -static void deferResetProgrammerError(testingT *t, void *data) -{ - uiprivTestHookReportProgrammerError(NULL, NULL); -} - -static void checkProgrammerErrorThreadProc(void *data) -{ - struct checkProgrammerErrorParams *p = (struct checkProgrammerErrorParams *) data; - - (*(p->f))(p->data); -} - -static void checkProgrammerErrorSubtestImpl(testingT *t, void *data) -{ - struct checkProgrammerErrorParams *p = (struct checkProgrammerErrorParams *) data; - - uiprivTestHookReportProgrammerError(handleProgrammerError, p); - testingTDefer(t, deferResetProgrammerError, NULL); - if (p->inThread) { - threadThread *thread; - threadSysError err; - - err = threadNewThread(checkProgrammerErrorThreadProc, p, &thread); - if (err != 0) - testingTFatalfFull(t, p->file, p->line, "error creating thread: " threadSysErrorFmt, threadSysErrorFmtArg(err)); - err = threadThreadWaitAndFree(thread); - if (err != 0) - testingTFatalfFull(t, p->file, p->line, "error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err)); - } else - (*(p->f))(p->data); - if (!p->caught) - testingTErrorfFull(t, p->file, p->line, "did not throw a programmer error; should have"); - if (p->msgGot != NULL) { - testingTErrorfFull(t, p->file, p->line, "message doesn't match expected string:" diff("%s"), - p->msgGot, p->msgWant); - testingUtilFreeStrdup(p->msgGot); - } -} - -void checkProgrammerErrorFull(testingT *t, const char *file, long line, const char *name, void (*f)(void *data), void *data, const char *msgWant, bool inThread) -{ - struct checkProgrammerErrorParams p; - - memset(&p, 0, sizeof (struct checkProgrammerErrorParams)); - p.file = file; - p.line = line; - p.f = f; - p.data = data; - p.inThread = inThread; - p.msgWant = msgWant; - testingTRun(t, name, checkProgrammerErrorSubtestImpl, &p); -} - -#define checkProgrammerError(t, name, f, data, msgWant) checkProgrammerErrorFull(t, __FILE__, __LINE__, name, f, data, msgWant, false) -#define checkProgrammerErrorInThread(t, name, f, data, msgWant) checkProgrammerErrorFull(t, __FILE__, __LINE__, name, f, data, msgWant, true) - #define allcallsCase(f, ...) \ void doCase ## f(void *data) \ { \ diff --git a/test/test.h b/test/test.h index 8e613405..ee421ffd 100644 --- a/test/test.h +++ b/test/test.h @@ -34,22 +34,11 @@ struct errorParams { const char *msgWant; bool caught; }; -extern void catchProgrammerError(const char *msg, void *data); -#define testProgrammerError(tt, expr, mw) { \ - struct errorParams errorParams; \ - testingTLogf(t, "*** %s", #expr); \ - uiprivTestHookReportProgrammerError(catchProgrammerError, &errorParams); \ - errorParams.t = tt; \ - errorParams.file = __FILE__; \ - errorParams.line = __LINE__; \ - errorParams.exprstr = #expr; \ - errorParams.msgWant = mw; \ - errorParams.caught = false; \ - expr; \ - if (!errorParams.caught) \ - testingTErrorfFull(t, errorParams.file, errorParams.line, "%s did not throw a programmer error; should have", #expr); \ - uiprivTestHookReportProgrammerError(NULL, NULL); \ -} // init.c extern testingSet *beforeTests; + +// errors.c +extern void checkProgrammerErrorFull(testingT *t, const char *file, long line, const char *name, void (*f)(void *data), void *data, const char *msgWant, bool inThread); +#define checkProgrammerError(t, name, f, data, msgWant) checkProgrammerErrorFull(t, __FILE__, __LINE__, name, f, data, msgWant, false) +#define checkProgrammerErrorInThread(t, name, f, data, msgWant) checkProgrammerErrorFull(t, __FILE__, __LINE__, name, f, data, msgWant, true)