diff --git a/test/errors.h b/test/errors.h new file mode 100644 index 00000000..8737a376 --- /dev/null +++ b/test/errors.h @@ -0,0 +1,66 @@ +// 12 june 2019 +#include "test.h" + +// Usage: +// struct checkErrorParams { +// // ... +// }; +// #define checkErrorHeader "header.h" +// #include "errors.h" +// testingTest(TestName) +// { +// struct checkErrorParams p = ...; +// checkErrors(t, checkErrorCases, &p); +// } +// Feel free to redefine checkErrorParams and checkErrorCases as necessary. + +#define checkErrorCat(a, b) a ## b +#define checkErrorCase(call, msgWant) checkErrorCaseFull(__LINE__, call, msgWant) + +#define checkErrorCaseFull(line, call, msgWant) \ + static void checkErrorCat(doCheck, line)(void *data) \ + { \ + struct checkErrorParams *p = (struct checkErrorParams *) data; \ + (void) p; /* in the event call does not use this */ \ + call; \ + } +#include checkErrorHeader +#undef checkErrorCaseFull + +static const struct checkErrorCase checkErrorCases[] = { +#define checkErrorCaseFull(line, callstr, msgWant) { callstr, checkErrorCat(doCheck, line), msgWant }, +#include checkErrorHeader +#undef checkErrorCaseFull + { NULL, NULL, NULL, }, +}; + +testingTest(EventErrors) +{ + struct checkErrorParams p; + uiEventOptions opts; + size_t i; + + memset(&p, 0, sizeof (struct checkErrorParams)); + p.eventOptionsBadSize.Size = 1; + memset(&opts, 0, sizeof (uiEventOptions)); + opts.Size = sizeof (uiEventOptions); + opts.Global = true; + p.globalEvent = uiNewEvent(&opts); + testingTDefer(t, deferEventFree, p.globalEvent); + opts.Global = false; + p.nonglobalEvent = uiNewEvent(&opts); + testingTDefer(t, deferEventFree, p.nonglobalEvent); + p.eventPlaceholder = p.globalEvent; + p.handlerPlaceholder = dummyHandler; + p.nonNullSender = &p; + p.firingEvent = p.globalEvent; + p.eventWithHandlers = uiNewEvent(&opts); + // TODO properly free this + uiEventAddHandler(p.eventWithHandlers, dummyHandler, &p, &p); + + for (i = 0; checkErrorCases[i].name != NULL; i++) + checkProgrammerError(t, checkErrorCases[i].name, checkErrorCases[i].f, &p, checkErrorCases[i].msgWant); +} + +#undef checkErrorCase +#undef checkErrorCat diff --git a/test/events_errors.c b/test/events_errors.c index 9aa0d206..d494750b 100644 --- a/test/events_errors.c +++ b/test/events_errors.c @@ -22,16 +22,6 @@ struct checkErrorParams { uiEvent *eventWithHandlers; }; -// TODO clean up these macros -#define checkCat(a, b) a ## b -#define checkErrorCaseFull(line, call, msgWant) \ - static void checkCat(doCheck, line)(void *data) \ - { \ - struct checkErrorParams *p = (struct checkErrorParams *) data; \ - (void) p; /* in the event call does not use this */ \ - call; \ - } -#define checkErrorCase(call, msgWant) checkErrorCaseFull(__LINE__, call, msgWant) #define checkErrorCaseWhileFiringFull(line, call, msgWant) \ static void checkCat(eventHandler, line)(void *sender, void *args, void *data) \ { \ @@ -39,36 +29,18 @@ struct checkErrorParams { (void) p; /* in the event call does not use this */ \ call; \ } \ - static void checkCat(doCheck, line)(void *data) \ + static void checkCat(runEventCheck, line)(struct checkErrorParams *p) \ { \ - struct checkErrorParams *p = (struct checkErrorParams *) data; \ int id; \ id = uiEventAddHandler(p->firingEvent, checkCat(eventHandler, line), NULL, p); \ uiEventFire(p->firingEvent, NULL, NULL); \ uiEventDeleteHandler(p->firingEvent, id); \ - } + } \ + checkErrorCaseFull(line, checkCat(runEventCheck, line)(p), msgWant) #define checkErrorCaseWhileFiring(call, msgWant) checkErrorCaseWhileFiringFull(__LINE__, call, msgWant) #include "events_errors.h" #undef checkErrorCaseWhileFiringFull #undef checkErrorCaseWhileFiring -#undef checkErrorCaseFull -#undef checkErrorCase - -static const struct { - const char *name; - void (*f)(void *data); - const char *msgWant; -} checkErrorCases[] = { -#define checkErrorCaseFull(line, callstr, msgWant) { callstr, checkCat(doCheck, line), msgWant }, -#define checkErrorCase(call, msgWant) checkErrorCaseFull(__LINE__, #call, msgWant) -#define checkErrorCaseWhileFiring(call, msgWant) checkErrorCaseFull(__LINE__, #call, msgWant) -#include "events_errors.h" -#undef checkErrorCaseWhileFiring -#undef checkErrorCase -#undef checkErrorCaseFull -#undef checkCat - { NULL, NULL, NULL, }, -}; testingTest(EventErrors) { diff --git a/test/test.h b/test/test.h index f203714e..b91a1345 100644 --- a/test/test.h +++ b/test/test.h @@ -39,6 +39,11 @@ extern testingSet *beforeTests; 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) +struct checkErrorCase { + const char *name; + void (*f)(void *data); + const char *msgWant; +}; // controls.c extern uiControlVtable *allocVtableFull(testingT *t, const char *file, long line);