From ee9df0491febfe131c7f51c1fd199d48331f9974 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 9 Jun 2019 19:00:01 -0400 Subject: [PATCH] Simplified noinitwrongthread.c further. This will form the basis of a simplified general event handler. --- test/noinitwrongthread.c | 127 ++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/test/noinitwrongthread.c b/test/noinitwrongthread.c index e848de14..0457533a 100644 --- a/test/noinitwrongthread.c +++ b/test/noinitwrongthread.c @@ -2,6 +2,8 @@ #include "test.h" struct errorCase { + void (*f)(testingT *t, struct errorCase *c); + void (*g)(testingT *t, struct errorCase *c); bool caught; char *msgGot; const char *msgWant; @@ -24,22 +26,28 @@ static void deferResetProgrammerError(testingT *t, void *data) uiprivTestHookReportProgrammerError(NULL, NULL); } +static void doCase(testingT *t, void *data) +{ + struct errorCase *c = (struct errorCase *) data; + + c->caught = false; + c->msgGot = NULL; + uiprivTestHookReportProgrammerError(handleProgrammerError, c); + testingTDefer(t, deferResetProgrammerError, NULL); + (*(c->f))(t, c); + if (!c->caught) + testingTErrorf(t, "did not throw a programmer error; should have"); + if (c->msgGot != NULL) { + testingTErrorf(t, "message doesn't match expected string:" diff("%s"), + c->msgGot, c->msgWant); + testingUtilFreeStrdup(c->msgGot); + } +} + #define allcallsCase(f, ...) \ - static void beforeInitCase ## f ## Impl(testingT *t, void *data) \ + void doCase ## f(testingT *t, struct errorCase *c) \ { \ - struct errorCase *c = (struct errorCase *) data; \ - memset(c, 0, sizeof (struct errorCase)); \ - c->msgWant = "attempt to call " #f "() before uiInit()"; \ - uiprivTestHookReportProgrammerError(handleProgrammerError, c); \ - testingTDefer(t, deferResetProgrammerError, NULL); \ f(__VA_ARGS__); \ - if (!c->caught) \ - testingTErrorf(t, "did not throw a programmer error; should have"); \ - if (c->msgGot != NULL) { \ - testingTErrorf(t, "message doesn't match expected string:" diff("%s"), \ - c->msgGot, c->msgWant); \ - testingUtilFreeStrdup(c->msgGot); \ - } \ } allcallsCase(uiQueueMain, NULL, NULL) #include "allcalls.h" @@ -47,13 +55,18 @@ allcallsCase(uiQueueMain, NULL, NULL) static const struct { const char *name; - void (*f)(testingT *, void *); -} beforeInitCases[] = { -#define allcallsCase(f, ...) { #f, beforeInitCase ## f ## Impl }, -allcallsCase(uiQueueMain, NULL, NULL) + void (*f)(testingT *t, struct errorCase *c); + const char *beforeInitWant; + const char *wrongThreadWant; +} allCases[] = { +#define allcallsCase(f, ...) { #f, doCase ## f, \ + "attempt to call " #f "() before uiInit()", \ + "attempt to call " #f "() on a thread other than the GUI thread", \ +}, + { "uiQueueMain", doCaseuiQueueMain, "attempt to call uiQueueMain() before uiInit()", NULL }, #include "allcalls.h" #undef allcallsCase - { NULL, NULL }, + { NULL, NULL, NULL, NULL }, }; testingTestInSet(beforeTests, FunctionsFailBeforeInit) @@ -61,56 +74,48 @@ testingTestInSet(beforeTests, FunctionsFailBeforeInit) struct errorCase c; size_t i; - for (i = 0; beforeInitCases[i].name != NULL; i++) - testingTRun(t, beforeInitCases[i].name, beforeInitCases[i].f, &c); + memset(&c, 0, sizeof (struct errorCase)); + for (i = 0; allCases[i].name != NULL; i++) { + c.f = allCases[i].f; + c.msgWant = allCases[i].beforeInitWant; + if (c.msgWant == NULL) + continue; + testingTRun(t, allCases[i].name, doCase, &c); + } } -#define allcallsCase(f, ...) \ - static void wrongThreadCase ## f ## ThreadProc(void *data) \ - { \ - f(__VA_ARGS__); \ - } \ - static void wrongThreadCase ## f ## Impl(testingT *t, void *data) \ - { \ - struct errorCase *c = (struct errorCase *) data; \ - threadThread *thread; \ - threadSysError err; \ - memset(c, 0, sizeof (struct errorCase)); \ - c->msgWant = "attempt to call " #f "() on a thread other than the GUI thread"; \ - uiprivTestHookReportProgrammerError(handleProgrammerError, c); \ - testingTDefer(t, deferResetProgrammerError, NULL); \ - err = threadNewThread(wrongThreadCase ## f ## ThreadProc, NULL, &thread); \ - if (err != 0) \ - testingTFatalf(t, "error creating thread: " threadSysErrorFmt, threadSysErrorFmtArg(err)); \ - err = threadThreadWaitAndFree(thread); \ - if (err != 0) \ - testingTFatalf(t, "error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err)); \ - if (!c->caught) \ - testingTErrorf(t, "did not throw a programmer error; should have"); \ - if (c->msgGot != NULL) { \ - testingTErrorf(t, "message doesn't contain expected string:" diff("%s"), \ - c->msgGot, c->msgWant); \ - testingUtilFreeStrdup(c->msgGot); \ - } \ - } -#include "allcalls.h" -#undef allcallsCase +static void runInThreadThreadProc(void *data) +{ + struct errorCase *c = (struct errorCase *) data; -static const struct { - const char *name; - void (*f)(testingT *, void *); -} wrongThreadCases[] = { -#define allcallsCase(f, ...) { #f, wrongThreadCase ## f ## Impl }, -#include "allcalls.h" -#undef allcallsCase - { NULL, NULL }, -}; + (*(c->g))(NULL, NULL); +} + +static void runInThread(testingT *t, struct errorCase *c) +{ + threadThread *thread; + threadSysError err; + + err = threadNewThread(runInThreadThreadProc, c, &thread); + if (err != 0) + testingTFatalf(t, "error creating thread: " threadSysErrorFmt, threadSysErrorFmtArg(err)); + err = threadThreadWaitAndFree(thread); + if (err != 0) + testingTFatalf(t, "error waiting for thread to finish: " threadSysErrorFmt, threadSysErrorFmtArg(err)); +} testingTest(FunctionsFailOnWrongThread) { struct errorCase c; size_t i; - for (i = 0; wrongThreadCases[i].name != NULL; i++) - testingTRun(t, wrongThreadCases[i].name, wrongThreadCases[i].f, &c); + memset(&c, 0, sizeof (struct errorCase)); + c.f = runInThread; + for (i = 0; allCases[i].name != NULL; i++) { + c.g = allCases[i].f; + c.msgWant = allCases[i].wrongThreadWant; + if (c.msgWant == NULL) + continue; + testingTRun(t, allCases[i].name, doCase, &c); + } }