From: Michael D. Lowis Date: Thu, 28 Feb 2019 04:08:00 +0000 (-0500) Subject: reworked generator functions, started adding more useful tests X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=822a4efe7e0a85bc48770709e3bbfd7f0ffd71af;p=projs%2Ftide.git reworked generator functions, started adding more useful tests --- diff --git a/config.mk b/config.mk index f8b9eb2..d7a9e03 100644 --- a/config.mk +++ b/config.mk @@ -33,8 +33,8 @@ ARFLAGS = rcs #LDFLAGS += -g -fsanitize=address,undefined # GCC - Enable Sanitizers -CFLAGS += -g -fsanitize=address,undefined -LDFLAGS += -g -fsanitize=address,undefined -lasan +#CFLAGS += -g -fsanitize=address,undefined +#LDFLAGS += -g -fsanitize=address,undefined -lasan # GCC/Clang Profiling #CFLAGS += -pg diff --git a/src/tide.c b/src/tide.c index 46c7249..7a05bc3 100644 --- a/src/tide.c +++ b/src/tide.c @@ -318,8 +318,9 @@ void win_init(KeyBinding* bindings) { ); x11_init_gc(&X); x11_sel_init(&X); +#ifndef TEST x11_show(&X); - +#endif /* register event handlers */ X.eventfns[KeyPress] = xkeypress; X.eventfns[ButtonPress] = xbtnpress; diff --git a/tests/test_tide.c b/tests/test_tide.c index 96c2553..e3663ed 100644 --- a/tests/test_tide.c +++ b/tests/test_tide.c @@ -7,6 +7,7 @@ typedef struct QCValue QCValue; struct QCValue { void (*showfn)(QCValue* val); void (*freefn)(QCValue* val); + long ndata; long data[]; }; @@ -16,7 +17,7 @@ typedef struct { QCValue** vals; } QCResult; -typedef int (*QCProp)(QCValue** vals, int nvals); +typedef int (*QCProp)(int nvals, QCValue** vals); typedef QCValue* (*QCGenFn)(void); @@ -31,23 +32,21 @@ void qcntrials(int ntrials) { NTrials = ntrials; } -QCResult vqcheck(QCProp prop, int nvals, va_list vals) { - /* generate the input values */ - QCValue** values = NULL; - if (nvals) { - values = malloc(sizeof(QCValue*) * nvals); - for (int i = 0; i < nvals; i++) - values[i] = (va_arg(vals, QCGenFn))(); - } - /* run the test and get the result */ - QCResult result = { .status = 0 }; - result.status = prop(values, nvals); - result.nvals = nvals; - result.vals = values; - return result; +QCValue* qcalloc(size_t sz, void* data) { + QCValue* value = calloc(1, sizeof(QCValue) + sz); + memcpy(value->data, data, sz); + return value; +} + +long qcrandr(long from, long to) { + return ((random() % (to - from + 1)) + from); +} + +long qcrand(void) { + return qcrandr(0, RAND_MAX); } -void qcfree(QCValue** vals, int nvals) { +void qcfree(int nvals, QCValue** vals) { for (int i = 0; i < nvals; i++) { if (vals[i]->freefn) vals[i]->freefn(vals[i]); free(vals[i]); @@ -55,13 +54,29 @@ void qcfree(QCValue** vals, int nvals) { free(vals); } -void qcshow(QCValue** vals, int nvals) { +void qcshow(int nvals, QCValue** vals) { for (int i = 0; i < nvals; i++) { printf("Argument %d: ", i); vals[i]->showfn(vals[i]); } } +QCResult vqcheck(QCProp prop, int nvals, va_list vals) { + /* generate the input values */ + QCValue** values = NULL; + if (nvals) { + values = malloc(sizeof(QCValue*) * nvals); + for (int i = 0; i < nvals; i++) + values[i] = (va_arg(vals, QCGenFn))(); + } + /* run the test and get the result */ + QCResult result = { .status = 0 }; + result.status = prop(nvals, values); + result.nvals = nvals; + result.vals = values; + return result; +} + int qcheck(char* desc, QCProp prop, int nvals, ...) { int passed = 0; QCResult result; @@ -71,7 +86,7 @@ int qcheck(char* desc, QCProp prop, int nvals, ...) { result = vqcheck(prop, nvals, vals); va_end(vals); if (!result.status) break; - qcfree(result.vals, result.nvals); + qcfree(result.nvals, result.vals); passed++; } /* show 'em the results */ @@ -79,20 +94,14 @@ int qcheck(char* desc, QCProp prop, int nvals, ...) { printf("%d tests passed for property: %s\n", passed, desc); } else if (!result.status) { printf("Property: %s\nFalsifiable after %d tests (seed: %d)\n", desc, passed+1, Seed); - qcshow(result.vals, result.nvals); + qcshow(result.nvals, result.vals); /* should investigate shrinking input here as well */ - qcfree(result.vals, result.nvals); + qcfree(result.nvals, result.vals); return 0; } return 1; } -QCValue* qcalloc(size_t sz, void* data) { - QCValue* value = calloc(1, sizeof(QCValue) + sz); - memcpy(value->data, data, sz); - return value; -} - /************************************************/ void ShowLong(QCValue* val) { @@ -107,15 +116,18 @@ void ShowChar(QCValue* val) { printf("'%c'\n", (char)(val->data[0])); } -QCValue* GenLongR(long from, long to) { - long val = ((random() % (to - from + 1)) + from); +QCValue* MkLong(long val, void (*showfn)(QCValue* val)) { QCValue* value = qcalloc(sizeof(long), &val); - value->showfn = ShowLong; + value->showfn = showfn; return value; } +QCValue* GenLongR(long from, long to) { + return MkLong(qcrandr(from, to), ShowLong); +} + QCValue* GenLong(void) { - return GenLongR(0, RAND_MAX); + return MkLong(qcrand(), ShowLong); } QCValue* GenU8(void) { @@ -131,15 +143,11 @@ QCValue* GenU32(void) { } QCValue* GenBool(void) { - QCValue* val = GenLongR(0, 1); - val->showfn = ShowBool; - return val; + return MkLong(qcrandr(0, 1), ShowBool); } QCValue* GenChar(void) { - QCValue* val = GenU8(); - val->showfn = ShowChar; - return val; + return MkLong(qcrandr(0, 127), ShowChar); } /************************************************/ @@ -159,16 +167,40 @@ void tide_init(void) { /************************************************/ -int divisible_by_two(QCValue** vals, int nvals) { +int divisible_by_two(int nvals, QCValue** vals) { (void)nvals; return ((vals[0]->data[0] % 2) == 0); } +int resizing_should_not_crash(int nvals, QCValue** vals) { +// int pid = fork(); +// /* test the resize event */ +// if (pid == 0) { + XEvent e = {0}; + e.xconfigure.width = vals[0]->data[0]; + e.xconfigure.height = vals[1]->data[0]; + tide_init(); + (X.eventfns[ConfigureNotify])(&X, &e); + xupdate(NULL); +// } +// switch (fork()) { +// case 0: +// tide_init(); +// break; +// default: +// /* wait for pid to exit */ +// break; +// } + return ((void)vals, (void)nvals, 1); +} + int main(int argc, char** argv) { (void)argc, (void)argv, (void)usage; qcinit(0); qcheck("all numbers are divisible by 2", divisible_by_two, 1, GenLong); + qcheck("resizing should not crash the app", + resizing_should_not_crash, 2, GenU16, GenU16); return 0; }