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 {
|
struct test {
|
||||||
const char *name;
|
const char *name;
|
||||||
int (*f)(void);
|
void (*f)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct test *tests = NULL;
|
static struct test *tests = NULL;
|
||||||
static size_t lenTests = 0;
|
static size_t lenTests = 0;
|
||||||
static size_t capTests = 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) {
|
if (lenTests == capTests) {
|
||||||
struct test *newtests;
|
struct test *newtests;
|
||||||
|
@ -38,6 +38,24 @@ static int testcmp(const void *aa, const void *bb)
|
||||||
return strcmp(a->name, b->name);
|
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)
|
static const char *basename(const char *file)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
@ -51,7 +69,7 @@ static const char *basename(const char *file)
|
||||||
return 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;
|
va_list ap;
|
||||||
|
|
||||||
|
@ -60,6 +78,8 @@ void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt,
|
||||||
vfprintf(f, fmt, ap);
|
vfprintf(f, fmt, ap);
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
if (then != NULL)
|
||||||
|
(*then)();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
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]);
|
fprintf(stderr, "%s: no such test\n", argv[1]);
|
||||||
return 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
|
#endif
|
||||||
|
|
||||||
#define Test(Name) \
|
#define Test(Name) \
|
||||||
void testingprivImplName(Test ## Name)(int *testingprivRet); \
|
void testingprivImplName(Test ## Name)(void); \
|
||||||
static int testingprivScaffoldName(Test ## Name)(void) \
|
static void testingprivScaffoldName(Test ## Name)(void) \
|
||||||
{ \
|
{ \
|
||||||
int ret = 0; \
|
|
||||||
uiInitError err; \
|
uiInitError err; \
|
||||||
memset(&err, 0, sizeof (uiInitError)); \
|
memset(&err, 0, sizeof (uiInitError)); \
|
||||||
err.Size = sizeof (uiInitError); \
|
err.Size = sizeof (uiInitError); \
|
||||||
if (!uiInit(NULL, &err)) { \
|
if (!uiInit(NULL, &err)) { \
|
||||||
fprintf(stderr, "error initializing libui for Test" #Name ": %s\n", err.Message); \
|
fprintf(stderr, "error initializing libui for Test" #Name ": %s\n", err.Message); \
|
||||||
return 1; \
|
TestFailNow(); \
|
||||||
} \
|
} \
|
||||||
testingprivImplName(Test ## Name)(&ret); \
|
testingprivImplName(Test ## Name)(); \
|
||||||
return ret; \
|
|
||||||
} \
|
} \
|
||||||
testingprivMkCtor(Test ## Name) \
|
testingprivMkCtor(Test ## Name) \
|
||||||
void testingprivImplName(Test ## Name)(int *testingprivRet)
|
void testingprivImplName(Test ## Name)(void)
|
||||||
|
|
||||||
#define TestNoInit(Name) \
|
#define TestNoInit(Name) \
|
||||||
void testingprivImplName(Test ## Name)(int *testingprivRet); \
|
void testingprivImplName(Test ## Name)(void); \
|
||||||
static int testingprivScaffoldName(Test ## Name)(void) \
|
static void testingprivScaffoldName(Test ## Name)(void) \
|
||||||
{ \
|
{ \
|
||||||
int ret = 0; \
|
testingprivImplName(Test ## Name)(); \
|
||||||
testingprivImplName(Test ## Name)(&ret); \
|
|
||||||
return ret; \
|
|
||||||
} \
|
} \
|
||||||
testingprivMkCtor(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.
|
extern void TestFail(void);
|
||||||
// TODO make it otherwise
|
extern void TestFailNow(void);
|
||||||
#define TestFail() (*testingprivRet = 1)
|
extern void TestSkipNow(void);
|
||||||
#define TestFailNow() {TestFail(); return;}
|
|
||||||
// see https://mesonbuild.com/Unit-tests.html#skipped-tests-and-hard-errors
|
|
||||||
#define TestSkipNow() {*testingprivRet = 77; return;}
|
|
||||||
|
|
||||||
#define TestLogf(...) \
|
#define TestLogf(...) \
|
||||||
(testingprivLogf(stdout, __FILE__, __LINE__, __VA_ARGS__))
|
(testingprivLogfFullThen(stdout, NULL, __FILE__, __LINE__, __VA_ARGS__))
|
||||||
#define TestErrorf(...) \
|
#define TestErrorf(...) \
|
||||||
{testingprivLogf(stderr, __FILE__, __LINE__, __VA_ARGS__); TestFail();}
|
(testingprivLogfFullThen(stderr, TestFail, __FILE__, __LINE__, __VA_ARGS__))
|
||||||
#define TestFatalf(...) \
|
#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
|
// TODO remember if this needs to go to stdout or to stderr
|
||||||
#define TestSkipf(...) \
|
#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"
|
#include "../sharedbits/printfwarn_header.h"
|
||||||
sharedbitsPrintfFunc(
|
sharedbitsPrintfFunc(
|
||||||
extern void testingprivLogf(FILE *f, const char *filename, long line, const char *fmt, ...),
|
extern void testingprivLogfFullThen(FILE *f, void (*then)(void), const char *filename, long line, const char *fmt, ...),
|
||||||
4, 5);
|
5, 6);
|
||||||
#undef sharedbitsPrintfFunc
|
#undef sharedbitsPrintfFunc
|
||||||
|
|
||||||
// end of test framework definitions
|
// end of test framework definitions
|
||||||
|
|
Loading…
Reference in New Issue