Started restructuring things slightly so as to allow the new test functions to be safely called from subroutines.

This commit is contained in:
Pietro Gagliardi 2020-01-23 10:52:41 -05:00
parent cd2d64c228
commit 042da74cc9
2 changed files with 45 additions and 30 deletions

View File

@ -5,14 +5,14 @@
struct test {
const char *name;
int (*f)(void);
void (*f)(void);
};
static struct test *tests = NULL;
static size_t lenTests = 0;
static size_t capTests = 0;
void testingprivRegisterTest(const char *name, int (*f)(void))
void testingprivRegisterTest(const char *name, void (*f)(void))
{
if (lenTests == capTests) {
struct test *newtests;
@ -38,6 +38,24 @@ static int testcmp(const void *aa, const void *bb)
return strcmp(a->name, b->name);
}
static int testingprivRet = 0;
void TestFail(void)
{
testingprivRet = 1;
}
void TestFailNow(void)
{
exit(1);
}
void TestSkipNow(void)
{
// see https://mesonbuild.com/Unit-tests.html#skipped-tests-and-hard-errors
exit(77);
}
static const char *basename(const char *file)
{
const char *p;
@ -51,7 +69,7 @@ static const char *basename(const char *file)
return file;
}
void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt, ...)
void testingprivLogfFullThen(FILE *f, void (*then)(void), const char *filename, long line, const char *fmt, ...)
{
va_list ap;
@ -60,6 +78,8 @@ void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt,
vfprintf(f, fmt, ap);
fprintf(f, "\n");
va_end(ap);
if (then != NULL)
(*then)();
}
int main(int argc, char *argv[])
@ -78,5 +98,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "%s: no such test\n", argv[1]);
return 1;
}
return (*(t->f))();
testingprivRet = 0;
(*(t->f))();
return testingprivRet;
}

View File

@ -41,56 +41,49 @@ extern "C" {
#endif
#define Test(Name) \
void testingprivImplName(Test ## Name)(int *testingprivRet); \
static int testingprivScaffoldName(Test ## Name)(void) \
void testingprivImplName(Test ## Name)(void); \
static void testingprivScaffoldName(Test ## Name)(void) \
{ \
int ret = 0; \
uiInitError err; \
memset(&err, 0, sizeof (uiInitError)); \
err.Size = sizeof (uiInitError); \
if (!uiInit(NULL, &err)) { \
fprintf(stderr, "error initializing libui for Test" #Name ": %s\n", err.Message); \
return 1; \
TestFailNow(); \
} \
testingprivImplName(Test ## Name)(&ret); \
return ret; \
testingprivImplName(Test ## Name)(); \
} \
testingprivMkCtor(Test ## Name) \
void testingprivImplName(Test ## Name)(int *testingprivRet)
void testingprivImplName(Test ## Name)(void)
#define TestNoInit(Name) \
void testingprivImplName(Test ## Name)(int *testingprivRet); \
static int testingprivScaffoldName(Test ## Name)(void) \
void testingprivImplName(Test ## Name)(void); \
static void testingprivScaffoldName(Test ## Name)(void) \
{ \
int ret = 0; \
testingprivImplName(Test ## Name)(&ret); \
return ret; \
testingprivImplName(Test ## Name)(); \
} \
testingprivMkCtor(Test ## Name) \
void testingprivImplName(Test ## Name)(int *testingprivRet)
void testingprivImplName(Test ## Name)(void)
// These can only be called directly from the Test functions.
// TODO make it otherwise
#define TestFail() (*testingprivRet = 1)
#define TestFailNow() {TestFail(); return;}
// see https://mesonbuild.com/Unit-tests.html#skipped-tests-and-hard-errors
#define TestSkipNow() {*testingprivRet = 77; return;}
extern void TestFail(void);
extern void TestFailNow(void);
extern void TestSkipNow(void);
#define TestLogf(...) \
(testingprivLogf(stdout, __FILE__, __LINE__, __VA_ARGS__))
(testingprivLogfFullThen(stdout, NULL, __FILE__, __LINE__, __VA_ARGS__))
#define TestErrorf(...) \
{testingprivLogf(stderr, __FILE__, __LINE__, __VA_ARGS__); TestFail();}
(testingprivLogfFullThen(stderr, TestFail, __FILE__, __LINE__, __VA_ARGS__))
#define TestFatalf(...) \
{testingprivLogf(stderr, __FILE__, __LINE__, __VA_ARGS__); TestFailNow();}
(testingprivLogfFullThen(stderr, TestFailNow, __FILE__, __LINE__, __VA_ARGS__))
// TODO remember if this needs to go to stdout or to stderr
#define TestSkipf(...) \
{testingprivLogf(stderr, __FILE__, __LINE__, __VA_ARGS__); TestSkipNow();}
(testingprivLogfFullThen(stderr, TestSkipNow, __FILE__, __LINE__, __VA_ARGS__))
extern void testingprivRegisterTest(const char *name, int (*f)(void));
extern void testingprivRegisterTest(const char *name, void (*f)(void));
#include "../sharedbits/printfwarn_header.h"
sharedbitsPrintfFunc(
extern void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt, ...),
4, 5);
extern void testingprivLogfFullThen(FILE *f, void (*then)(void), const char *filename, long line, const char *fmt, ...),
5, 6);
#undef sharedbitsPrintfFunc
// end of test framework definitions