Started restructuring things slightly so as to allow the new test functions to be safely called from subroutines.
This commit is contained in:
parent
cd2d64c228
commit
042da74cc9
30
test/main.c
30
test/main.c
|
@ -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;
|
||||
}
|
||||
|
|
45
test/test.h
45
test/test.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue