Formatted test results across multiple lines in the same way as in Go. Also prettyprinted diffs in initmain.c.
This commit is contained in:
parent
4c097f93f7
commit
98093ed46e
|
@ -31,7 +31,8 @@ testingTestBefore(Init)
|
|||
if (ret != 0)
|
||||
testingTErrorf(t, "uiInit() with non-NULL options succeeded with return value %d; expected failure", err);
|
||||
if (strcmp(err.Message, errInvalidOptions) != 0)
|
||||
testingTErrorf(t, "uiInit() with non-NULL options returned bad error message: got %s, want %s", err.Message, errInvalidOptions);
|
||||
diff(t, "uiInit() with non-NULL options returned bad error message", "%s",
|
||||
err.Message, errInvalidOptions);
|
||||
|
||||
memset(&err, 0, sizeof (uiInitError));
|
||||
err.Size = sizeof (uiInitError);
|
||||
|
@ -45,7 +46,8 @@ testingTestBefore(Init)
|
|||
if (ret != 0)
|
||||
testingTErrorf(t, "uiInit() after a previous successful call succeeded with return value %d; expected failure", ret);
|
||||
if (strcmp(err.Message, errAlreadyInitialized) != 0)
|
||||
testingTErrorf(t, "uiInit() after a previous successful call returned bad error message: got %s, want %s", err.Message, errAlreadyInitialized);
|
||||
diff(t, "uiInit() after a previous successful call returned bad error message", "%s",
|
||||
err.Message, errAlreadyInitialized);
|
||||
}
|
||||
|
||||
struct testParams {
|
||||
|
@ -70,7 +72,8 @@ testingTest(QueueMain)
|
|||
uiQueueMain(queued, &p);
|
||||
timeout_uiMain(t, 5 * timerSecond);
|
||||
if (p.flag != 1)
|
||||
testingTErrorf(t, "uiQueueMain() didn't set flag properly: got %d, want 1", p.flag);
|
||||
diff(t, "uiQueueMain() didn't set flag properly", "%d",
|
||||
p.flag, 1);
|
||||
}
|
||||
|
||||
#define queueOp(name, expr) \
|
||||
|
@ -118,10 +121,14 @@ static void checkOrder(testingT *t, uint32_t flag)
|
|||
return;
|
||||
for (i = 1; i < 6; i++)
|
||||
if (flag == orders[i].result) {
|
||||
testingTErrorf(t, "got %" PRIu32 " (%s), want %" PRIu32 " (%s)", flag, orders[i].order, orders[0].result, orders[0].order);
|
||||
diff2(t, "wrong order", "%" PRIu32 " (%s)",
|
||||
flag, orders[i].order,
|
||||
orders[0].result, orders[0].order);
|
||||
return;
|
||||
}
|
||||
testingTErrorf(t, "got %" PRIu32 " (unknown order), want %" PRIu32 " (%s)", flag, orders[0].result, orders[0].order);
|
||||
diff2(t, "wrong result", "%" PRIu32 " (%s)",
|
||||
flag, "unknown order",
|
||||
orders[0].result, orders[0].order);
|
||||
}
|
||||
|
||||
testingTest(QueueMain_Sequence)
|
||||
|
@ -160,7 +167,8 @@ testingTest(QueueMain_DifferentThread)
|
|||
if (p.err != 0)
|
||||
testingTErrorf(t, "error sleeping in thread to ensure a high likelihood the uiQueueMain() is run after uiMain() starts: " timerSysErrorFmt, timerSysErrorFmtArg(p.err));
|
||||
if (p.flag != 1)
|
||||
testingTErrorf(t, "uiQueueMain() didn't set flag properly: got %d, want 1", p.flag);
|
||||
diff(t, "uiQueueMain() didn't set flag properly", "%d",
|
||||
p.flag, 1);
|
||||
}
|
||||
|
||||
static void queueOrderThread(void *data)
|
||||
|
|
|
@ -73,6 +73,7 @@ struct testingT {
|
|||
jmp_buf returnNowBuf;
|
||||
struct defer *defers;
|
||||
int defersRun;
|
||||
int indent;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -150,6 +151,63 @@ static void testsetSort(struct testset *set)
|
|||
qsort(set->tests, set->len, sizeof (testingT), testcmp);
|
||||
}
|
||||
|
||||
static void printIndent(int n)
|
||||
{
|
||||
for (; n != 0; n--)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void vprintfIndented(int indent, const char *format, va_list ap)
|
||||
{
|
||||
va_list ap2;
|
||||
char *buf;
|
||||
int n;
|
||||
char *lineStart, *lineEnd;
|
||||
int firstLine = 1;
|
||||
|
||||
va_copy(ap2, ap);
|
||||
n = vsnprintf(NULL, 0, format, ap2);
|
||||
// TODO handle n < 0 case
|
||||
va_end(ap2);
|
||||
buf = testingprivNewArray(char, n + 1);
|
||||
vsnprintf(buf, n + 1, format, ap);
|
||||
|
||||
// strip trailing blank lines
|
||||
while (buf[n - 1] == '\n')
|
||||
n--;
|
||||
buf[n] = '\0';
|
||||
|
||||
lineStart = buf;
|
||||
for (;;) {
|
||||
lineEnd = strchr(lineStart, '\n');
|
||||
if (lineEnd == NULL) // last line
|
||||
break;
|
||||
*lineEnd = '\0';
|
||||
printIndent(indent);
|
||||
printf("%s\n", lineStart);
|
||||
lineStart = lineEnd + 1;
|
||||
if (firstLine) {
|
||||
// subsequent lines are indented twice
|
||||
indent++;
|
||||
firstLine = 0;
|
||||
}
|
||||
}
|
||||
// print the last line
|
||||
printIndent(indent);
|
||||
printf("%s\n", lineStart);
|
||||
|
||||
testingprivFree(buf);
|
||||
}
|
||||
|
||||
static void printfIndented(int indent, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vprintfIndented(indent, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void runDefers(testingT *t)
|
||||
{
|
||||
struct defer *d;
|
||||
|
@ -161,7 +219,7 @@ static void runDefers(testingT *t)
|
|||
(*(d->f))(t, d->data);
|
||||
}
|
||||
|
||||
static void testsetRun(struct testset *set, int *anyFailed)
|
||||
static void testsetRun(struct testset *set, int indent, int *anyFailed)
|
||||
{
|
||||
size_t i;
|
||||
testingT *t;
|
||||
|
@ -171,7 +229,8 @@ static void testsetRun(struct testset *set, int *anyFailed)
|
|||
|
||||
t = set->tests;
|
||||
for (i = 0; i < set->len; i++) {
|
||||
printf("=== RUN %s\n", t->name);
|
||||
printfIndented(indent, "=== RUN %s\n", t->name);
|
||||
t->indent = indent + 1;
|
||||
start = timerMonotonicNow();
|
||||
if (setjmp(t->returnNowBuf) == 0)
|
||||
(*(t->f))(t);
|
||||
|
@ -186,7 +245,7 @@ static void testsetRun(struct testset *set, int *anyFailed)
|
|||
// note that failed overrides skipped
|
||||
status = "SKIP";
|
||||
timerDurationString(timerTimeSub(end, start), timerstr);
|
||||
printf("--- %s: %s (%s)\n", status, t->name, timerstr);
|
||||
printfIndented(indent, "--- %s: %s (%s)\n", status, t->name, timerstr);
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
@ -207,13 +266,13 @@ int testingMain(void)
|
|||
testsetSort(&testsAfter);
|
||||
|
||||
anyFailed = 0;
|
||||
testsetRun(&testsBefore, &anyFailed);
|
||||
testsetRun(&testsBefore, 0, &anyFailed);
|
||||
// TODO print a warning that we skip the next stages if a prior stage failed?
|
||||
if (!anyFailed)
|
||||
testsetRun(&tests, &anyFailed);
|
||||
testsetRun(&tests, 0, &anyFailed);
|
||||
// TODO should we unconditionally run these tests if before succeeded but the main tests failed?
|
||||
if (!anyFailed)
|
||||
testsetRun(&testsAfter, &anyFailed);
|
||||
testsetRun(&testsAfter, 0, &anyFailed);
|
||||
if (anyFailed) {
|
||||
printf("FAIL\n");
|
||||
return 1;
|
||||
|
@ -233,11 +292,22 @@ void testingprivTLogfFull(testingT *t, const char *file, long line, const char *
|
|||
|
||||
void testingprivTLogvfFull(testingT *t, const char *file, long line, const char *format, va_list ap)
|
||||
{
|
||||
va_list ap2;
|
||||
char *buf;
|
||||
int n, n2;
|
||||
|
||||
// TODO extract filename from file
|
||||
printf("\t%s:%ld: ", file, line);
|
||||
// TODO split into lines separated by \n\t\t and trimming trailing empty lines
|
||||
vprintf(format, ap);
|
||||
printf("\n");
|
||||
n = snprintf(NULL, 0, "%s:%ld: ", file, line);
|
||||
// TODO handle n < 0 case
|
||||
va_copy(ap2, ap);
|
||||
n2 = vsnprintf(NULL, 0, format, ap2);
|
||||
// TODO handle n2 < 0 case
|
||||
va_end(ap2);
|
||||
buf = testingprivNewArray(char, n + n2 + 1);
|
||||
snprintf(buf, n + 1, "%s:%ld: ", file, line);
|
||||
vsnprintf(buf + n, n2 + 1, format, ap);
|
||||
printfIndented(t->indent, "%s", buf);
|
||||
testingprivFree(buf);
|
||||
}
|
||||
|
||||
void testingTFail(testingT *t)
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
#include "lib/testing.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
#define diff(t, clause, fmt, got, want) testingTErrorf(t, "%s:\ngot " fmt "\nwant " fmt, clause, got, want)
|
||||
#define diff2(t, clause, fmts, got1, got2, want1, want2) testingTErrorf(t, "%s:\ngot " fmts "\nwant " fmts, clause, got1, got2, want1, want2)
|
||||
#define diffFatal(t, clause, fmt, got, want) testingTFatalf(t, "%s:\ngot " fmt "\nwant " fmt, clause, got, want)
|
||||
#define diff2Fatal(t, clause, fmts, got1, got2, want1, want2) testingTFatalf(t, "%s:\ngot " fmts "\nwant " fmts, clause, got1, got2, want1, want2)
|
||||
|
||||
// main.c
|
||||
extern void timeoutMain(void *data);
|
||||
#define timeout_uiMain(t, d) { \
|
||||
|
|
Loading…
Reference in New Issue