Added testingTDefer(). Now we can actually write the rest of these tests.

This commit is contained in:
Pietro Gagliardi 2018-03-03 16:24:10 -05:00
parent 70db51d23b
commit 6c29932efe
3 changed files with 54 additions and 14 deletions

View File

@ -19,25 +19,23 @@ typedef uiForEach (*uiOpenTypeFeaturesForEachFunc)(const uiOpenTypeFeatures *otf
#define uiprivFree free
#include "opentype.c"
static void freeOpenType(void *otf)
{
uiFreeOpenTypeFeatures((uiOpenTypeFeatures *) otf);
}
testingTest(OpenTypeFeaturesAddGet)
{
uiOpenTypeFeatures *otf;
char a, b, c, d;
uint32_t value;
otf = uiNewOpenTypeFeatures();
testingTDefer(t, freeOpenType, otf);
uiOpenTypeFeaturesAdd(otf, 'a', 'b', 'c', 'd', 12345);
if (!uiOpenTypeFeaturesGet(otf, 'a', 'b', 'c', 'd', &value)) {
testingTErrorf(t, "uiOpenTypeFeaturesGet() failed to get feature we added");
goto out;
}
if (value != 12345) {
testingTErrorf(t, "feature abcd: got %" PRIu32 ", want 12345", value);
goto out;
}
out:
uiFreeOpenTypeFeatures(otf);
if (!uiOpenTypeFeaturesGet(otf, 'a', 'b', 'c', 'd', &value))
testingTFatalf(t, "uiOpenTypeFeaturesGet() failed to get feature we added");
if (value != 12345)
testingTFatalf(t, "feature abcd: got %" PRIu32 ", want 12345", value);
}
int main(void)

View File

@ -94,6 +94,8 @@ extern void testingTFail(testingT *t);
#define testingTFailNow(t) (testingprivTDoFailNow(t))
#define testingTSkipNow(t) (testingprivTDoSkipNow(t))
#endif
// TODO should the defered function also have t passed to it?
extern void testingTDefer(testingT *t, void (*f)(void *data), void *data);
// TODO should __LINE__ arguments use intmax_t or uintmax_t instead of int?
extern void testingprivRegisterTest(const char *, void (*)(testingT *));

View File

@ -6,12 +6,20 @@
#define testingprivNew(T) ((T *) malloc(sizeof (T)))
struct defer {
void (*f)(void *);
void *data;
struct defer *next;
};
struct testingT {
const char *name;
void (*f)(testingT *);
int failed;
int skipped;
jmp_buf returnNowBuf;
struct defer *defers;
int defersRun;
testingT *next;
};
@ -26,10 +34,23 @@ void testingprivRegisterTest(const char *name, void (*f)(testingT *))
t->f = f;
t->failed = 0;
t->skipped = 0;
t->defers = NULL;
t->defersRun = 0;
t->next = tests;
tests = t;
}
static void runDefers(testingT *t)
{
struct defer *d;
if (t->defersRun)
return;
t->defersRun = 1;
for (d = t->defers; d != NULL; d = d->next)
(*(d->f))(d->data);
}
int testingMain(void)
{
testingT *t;
@ -48,6 +69,7 @@ int testingMain(void)
printf("=== RUN %s\n", t->name);
if (setjmp(t->returnNowBuf) == 0)
(*(t->f))(t);
runDefers(t);
status = "PASS";
if (t->failed) {
status = "FAIL";
@ -89,14 +111,32 @@ void testingTFail(testingT *t)
t->failed = 1;
}
static void returnNow(testingT *t)
{
// run defers before calling longjmp() just to be safe
runDefers(t);
longjmp(t->returnNowBuf, 1);
}
void testingprivTDoFailNow(testingT *t)
{
testingTFail(t);
longjmp(t->returnNowBuf, 1);
returnNow(t);
}
void testingprivTDoSkipNow(testingT *t)
{
t->skipped = 1;
longjmp(t->returnNowBuf, 1);
returnNow(t);
}
void testingTDefer(testingT *t, void (*f)(void *data), void *data)
{
struct defer *d;
d = testingprivNew(struct defer);
d->f = f;
d->data = data;
d->next = t->defers;
t->defers = d;
}