From: Michael D. Lowis Date: Sat, 2 Mar 2019 04:01:13 +0000 (-0500) Subject: updated property test for edit operations X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=10e4b922bc3b0f980fe2471575e3213990af5b12;p=projs%2Ftide.git updated property test for edit operations --- diff --git a/config.mk b/config.mk index f8994f2..d7a9e03 100644 --- a/config.mk +++ b/config.mk @@ -33,13 +33,13 @@ 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 #LDFLAGS += -pg # GCC/Clang Coverage -CFLAGS += -g -O0 --coverage -LDFLAGS += -g -O0 --coverage +#CFLAGS += -g -O0 --coverage +#LDFLAGS += -g -O0 --coverage diff --git a/inc/atf.h b/inc/atf.h index ca7b30a..467b802 100644 --- a/inc/atf.h +++ b/inc/atf.h @@ -56,6 +56,9 @@ int atf_print_results(void); #define EXPECT_EXIT \ if ((ExitExpected = true, 0 == setjmp(ExitPad))) +#define QCHECK(desc, prop, ...) \ + CHECK(qcheck(desc, prop, __VA_ARGS__)) + /* Function Definitions *****************************************************************************/ #ifdef INCLUDE_DEFS diff --git a/inc/qcheck.h b/inc/qcheck.h index 7aec0ce..605e3e8 100644 --- a/inc/qcheck.h +++ b/inc/qcheck.h @@ -41,7 +41,21 @@ typedef int (*QCProp)(int nvals, QCValue** vals); typedef QCValue* (*QCGenFn)(void); -#define VAL(v, type) ((type)((v)->data[0])) +#define PROPERTY(name) \ + int name (int nvals, QCValue** vals) + +#define VAL(i, type) \ + (type)&(qcgetval(nvals, vals, i)->data[0]) + +#define IVAL(i) \ + (qcgetval(nvals, vals, i)->data[0]) + +#define QASSERT(cond) \ + if (!(cond)) return 0 + +static inline QCValue* qcgetval(int nvals, QCValue** vals, int i) { + return vals[i < nvals ? i : nvals-1]; +} void qcinit(int seed); void qcntrials(int ntrials); @@ -53,11 +67,14 @@ void qcshow(int nvals, QCValue** vals); QCResult vqcheck(QCProp prop, int nvals, va_list vals); int qcheck(char* desc, QCProp prop, int nvals, ...); -void ShowLong(QCValue* val); -void ShowBool(QCValue* val); -void ShowChar(QCValue* val); +void show_long(QCValue* val); +void show_bool(QCValue* val); +void show_char(QCValue* val); +void show_byte(QCValue* val); +void show_string(QCValue* val); QCValue* MkLong(long val, void (*showfn)(QCValue* val)); +QCValue* MkArray(size_t nelems, size_t elemsz, void (*showfn)(QCValue* val)); QCValue* GenLongR(long from, long to); QCValue* GenLong(void); QCValue* GenU8(void); @@ -66,6 +83,7 @@ QCValue* GenU32(void); QCValue* GenBool(void); QCValue* GenByte(void); QCValue* GenAsciiChar(void); +QCValue* GenAsciiStringL(size_t len); QCValue* GenAsciiString(void); /* Function Definitions @@ -75,7 +93,7 @@ QCValue* GenAsciiString(void); #include #include -static int Seed = 0, NTrials = 1000; +static int Seed = 0, NTrials = 5000; void qcinit(int seed) { Seed = (seed ? seed : time(NULL)); @@ -148,31 +166,32 @@ int qcheck(char* desc, QCProp prop, int nvals, ...) { if (passed == NTrials) { 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); + printf("\nProperty: %s\nFalsifiable after %d tests (seed: %d)\n", desc, passed+1, Seed); qcshow(result.nvals, result.vals); qcfree(result.nvals, result.vals); + puts(""); return 0; } return 1; } -void ShowLong(QCValue* val) { +void show_long(QCValue* val) { printf("%ld\n", (val->data[0])); } -void ShowBool(QCValue* val) { +void show_bool(QCValue* val) { printf("%s\n", (val->data[0] ? "true" : "false")); } -void ShowChar(QCValue* val) { +void show_char(QCValue* val) { printf("'%c'\n", (char)(val->data[0])); } -void ShowByte(QCValue* val) { +void show_byte(QCValue* val) { printf("0x%02x\n", (char)(val->data[0])); } -void ShowString(QCValue* val) { +void show_string(QCValue* val) { printf("'%s'\n", (char*)(val->data)); } @@ -189,11 +208,11 @@ QCValue* MkArray(size_t nelems, size_t elemsz, void (*showfn)(QCValue* val)) { } QCValue* GenLongR(long from, long to) { - return MkLong(qcrandr(from, to), ShowLong); + return MkLong(qcrandr(from, to), show_long); } QCValue* GenLong(void) { - return MkLong(qcrand(), ShowLong); + return MkLong(qcrand(), show_long); } QCValue* GenU8(void) { @@ -209,26 +228,29 @@ QCValue* GenU32(void) { } QCValue* GenBool(void) { - return MkLong(qcrandr(0, 1), ShowBool); + return MkLong(qcrandr(0, 1), show_bool); } QCValue* GenByte(void) { - return MkLong(qcrandr(0, 255), ShowByte); + return MkLong(qcrandr(0, 255), show_byte); } QCValue* GenAsciiChar(void) { - return MkLong(qcrandr(32, 127), ShowChar); + return MkLong(qcrandr(32, 127), show_char); } -QCValue* GenAsciiString(void) { - size_t nelem = qcrandr(1, 1024); - QCValue* value = MkArray(nelem+1, 1, ShowString); +QCValue* GenAsciiStringL(size_t len) { + QCValue* value = MkArray(len+1, 1, show_string); + value->ndata = len+1; char* string = (char*)value->data; - for (size_t i = 0; i < nelem; i++) + for (size_t i = 0; i < len; i++) *(string++) = qcrandr(32,127); return value; } +QCValue* GenAsciiString(void) { + return GenAsciiStringL(qcrandr(1, 1024)); +} #endif #endif /* QCHECK_H */ diff --git a/tests/lib/buf.c b/tests/lib/buf.c index e05c87e..d529fa9 100644 --- a/tests/lib/buf.c +++ b/tests/lib/buf.c @@ -23,46 +23,49 @@ static int buffer_equals(char* str) { return (!strcmp(str, Output)); } - -#define QCHECK(desc, prop, ...) \ - CHECK(qcheck(desc, prop, __VA_ARGS__)) - -#define QASSERT(cond) \ - if (!(cond)) return 0 +static int selection_equals(char* str) { + free(Output), Output = NULL; + Output = buf_gets(&TestBuf); + return (!strcmp(str, Output)); +} void setup_buffer(void) { free(Output), Output = NULL; buf_init(&TestBuf); } -int getc_returns_putc(int nvals, QCValue** vals) { +PROPERTY(getc_returns_putc) { setup_buffer(); - buf_putc(&TestBuf, vals[0]->data[0]); + buf_putc(&TestBuf, IVAL(0)); TestBuf.selection.end = TestBuf.selection.beg = 0; - return (vals[0]->data[0] == buf_getc(&TestBuf)); + return (IVAL(0) == buf_getc(&TestBuf)); } -int gets_returns_puts(int nvals, QCValue** vals) { +PROPERTY(gets_returns_puts) { setup_buffer(); - char* input = (char*)(vals[0]->data); + char* input = VAL(0,char*); buf_puts(&TestBuf, input); QASSERT(buffer_equals(input)); return 1; } -int edit_operations_are_reversible(int nvals, QCValue** vals) { +PROPERTY(edit_operations_are_reversible) { setup_buffer(); - char* input = (char*)(vals[0]->data); + char* input = VAL(0,char*); buf_logstart(&TestBuf); buf_puts(&TestBuf, input); buf_logstop(&TestBuf); QASSERT(buffer_equals(input)); -// buf_putc(&TestBuf, 'A'); -// TestBuf.selection.end = buf_byrune(&TestBuf, TestBuf.selection.end, LEFT); -// /* selection equals 'A' */ -// buf_del(&TestBuf); // delete 'A' -// buf_undo(&TestBuf); -// QASSERT(buffer_equals(input)); + buf_logstart(&TestBuf); + buf_putc(&TestBuf, 'A'); + buf_logstop(&TestBuf); + buf_lastins(&TestBuf); + QASSERT(selection_equals("A")); + buf_del(&TestBuf); // delete 'A' + buf_undo(&TestBuf); + QASSERT(selection_equals("A")); + buf_undo(&TestBuf); + QASSERT(buffer_equals(input)); buf_undo(&TestBuf); QASSERT(buffer_equals("")); buf_redo(&TestBuf); @@ -70,10 +73,16 @@ int edit_operations_are_reversible(int nvals, QCValue** vals) { return 1; } +QCValue* GenCodepoint(void) { + return GenLongR(0, 0x10FFFF); +} + TEST_SUITE(BufferTests) { TEST(buf should adhere to specific properties) { QCHECK("getc should return the same printable ascii value inserted with putc", getc_returns_putc, 1, GenAsciiChar); +// QCHECK("getc should return the same printable unicode value inserted with putc", +// getc_returns_putc, 1, GenCodepoint); QCHECK("gets should return the same printable ascii string inserted with puts", gets_returns_puts, 1, GenAsciiString); QCHECK("edit operations should be reversible",