Filled in the rest of test(ing).h and main.c for the new test system.
This commit is contained in:
parent
c95cefaa1c
commit
f4218af3f5
55
test/main.c
55
test/main.c
|
@ -1,17 +1,56 @@
|
|||
// 19 january 2020
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "test.h"
|
||||
|
||||
struct test {
|
||||
const char *name;
|
||||
int (*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))
|
||||
{
|
||||
if (lenTests == capTests) {
|
||||
struct test *newtests;
|
||||
|
||||
capTests += 32;
|
||||
newtests = (struct test *) realloc(tests, capTests * sizeof (struct test));
|
||||
if (newtests == NULL) {
|
||||
fprintf(stderr, "memory exhausted registering test %s\n", name);
|
||||
exit(1);
|
||||
}
|
||||
tests = newtests;
|
||||
}
|
||||
tests[lenTests].name = name;
|
||||
tests[lenTests].f = f;
|
||||
lenTests++;
|
||||
}
|
||||
|
||||
static int testcmp(const void *aa, const void *bb)
|
||||
{
|
||||
const struct test *a = (const struct test *) aa;
|
||||
const struct test *b = (const struct test *) bb;
|
||||
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct test *t;
|
||||
struct test want;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s [-list|TestName]\n", argv[0]);
|
||||
fprintf(stderr, "usage: %s TestName\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(argv[1], "-list") == 0) {
|
||||
// TODO
|
||||
return 0;
|
||||
qsort(tests, lenTests, sizeof (struct test), testcmp);
|
||||
want.name = argv[1];
|
||||
t = (struct test *) bsearch(&want, tests, lenTests, sizeof (struct test), testcmp);
|
||||
if (t == NULL) {
|
||||
fprintf(stderr, "%s: no such test\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
// TODO
|
||||
return 0;
|
||||
return (*(t->f))();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// 27 february 2018
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../ui.h"
|
||||
#ifdef testingprivOSHeader
|
||||
#include testingprivOSHeader
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define testingprivImplName(basename) testingprivImpl ## basename
|
||||
|
||||
// references:
|
||||
// - https://gitlab.gnome.org/GNOME/glib/blob/master/glib/gconstructor.h
|
||||
// - https://gitlab.gnome.org/GNOME/glib/blob/master/gio/glib-compile-resources.c
|
||||
// - https://msdn.microsoft.com/en-us/library/bb918180.aspx
|
||||
#define testingprivCtorName(basename) testingprivCtor ## basename
|
||||
#define testingprivCtorPtrName(basename) testingprivCtorPtr ## basename
|
||||
#if defined(__GNUC__)
|
||||
#define testingprivMkCtor(basename) \
|
||||
__attribute__((constructor)) static void testingprivCtorName(basename)(void) { testingprivRegisterTest(#basename, testingprivImplName(basename)); }
|
||||
#elif defined(_MSC_VER)
|
||||
#define testingprivMkCtor(basename) \
|
||||
static int testingprivCtorName(basename)(void) { testingprivRegisterTest(#basename, testingprivImplName(basename)); return 0; } \
|
||||
__pragma(section(".CRT$XCU",read)) \
|
||||
__declspec(allocate(".CRT$XCU")) static int (*testingprivCtorPtrName(basename))(void) = testingprivCtorName(basename);
|
||||
#elif defined(__SUNPRO_C)
|
||||
#define testingprivMkCtor(basename) \
|
||||
static void testingprivCtorName(basename)(void) { testingprivRegisterTest(#basename, testingprivImplName(basename)); } \
|
||||
_Pragma(init(testingprivCtorName(basename)))
|
||||
#else
|
||||
#error unknown compiler for making constructors in C; cannot continue
|
||||
#endif
|
||||
|
||||
#define Test(basename) \
|
||||
int testingprivImplName(basename)(void); \
|
||||
testingprivMkCtor(basename) \
|
||||
int testingprivImplName(basename)(void)
|
||||
|
||||
#define Test(Name) \
|
||||
testingprivMk(Test ## Name)
|
||||
|
||||
// These can only be called directly from the Test functions.
|
||||
// TODO make it otherwise
|
||||
#define TestFailNow() return 1
|
||||
// see https://mesonbuild.com/Unit-tests.html#skipped-tests-and-hard-errors
|
||||
#define TestSkipNow() return 77
|
||||
|
||||
extern void testingprivRegisterTest(const char *name, int (*f)(void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
111
test/testing.h
111
test/testing.h
|
@ -1,111 +0,0 @@
|
|||
// 27 february 2018
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define testingprivImplName(basename) testingprivImpl ## basename
|
||||
|
||||
// references:
|
||||
// - https://gitlab.gnome.org/GNOME/glib/blob/master/glib/gconstructor.h
|
||||
// - https://gitlab.gnome.org/GNOME/glib/blob/master/gio/glib-compile-resources.c
|
||||
// - https://msdn.microsoft.com/en-us/library/bb918180.aspx
|
||||
#define testingprivCtorName(basename) testingprivCtor ## basename
|
||||
#define testingprivCtorPtrName(basename) testingprivCtorPtr ## basename
|
||||
#if defined(__GNUC__)
|
||||
#define testingprivMkCtor(basename) \
|
||||
__attribute__((constructor)) static void testingprivCtorName(basename)(void) { testingprivRegisterTest(#basename, testingprivImplName(basename), __FILE__, __LINE__); }
|
||||
#elif defined(_MSC_VER)
|
||||
#define testingprivMkCtor(basename) \
|
||||
static int testingprivCtorName(basename)(void) { testingprivRegisterTest(#basename, testingprivImplName(basename), __FILE__, __LINE__); return 0; } \
|
||||
__pragma(section(".CRT$XCU",read)) \
|
||||
__declspec(allocate(".CRT$XCU")) static int (*testingprivCtorPtrName(basename))(void) = testingprivCtorName(basename);
|
||||
#elif defined(__SUNPRO_C)
|
||||
#define testingprivMkCtor(basename) \
|
||||
static void testingprivCtorName(basename)(void) { testingprivRegisterTest(#basename, testingprivImplName(basename), __FILE__, __LINE__); } \
|
||||
_Pragma(init(testingprivCtorName(basename)))
|
||||
#else
|
||||
#error unknown compiler for making constructors in C; cannot continue
|
||||
#endif
|
||||
|
||||
#define testingprivMk(basename, argtype, argname) \
|
||||
void testingprivImplName(basename)(argtype *argname); \
|
||||
testingprivMkCtor(basename) \
|
||||
void testingprivImplName(basename)(argtype *argname)
|
||||
|
||||
#define Test(Name) \
|
||||
testingprivMk(Test ## Name, testingT, t)
|
||||
|
||||
typedef struct testingSet testingSet;
|
||||
typedef struct testingOptions testingOptions;
|
||||
|
||||
struct testingOptions {
|
||||
bool Verbose;
|
||||
};
|
||||
|
||||
extern void testingSetRun(testingSet *set, const struct testingOptions *options, bool *anyRun, bool *anyFailed);
|
||||
|
||||
typedef struct testingT testingT;
|
||||
|
||||
#define testingTLogf(t, ...) \
|
||||
testingprivTLogfFullThen(t, NULL, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define testingTLogvf(t, format, ap) \
|
||||
testingprivTLogvfFullThen(t, NULL, __FILE__, __LINE__, format, ap)
|
||||
#define testingTLogfFull(t, file, line, ...) \
|
||||
testingprivTLogfFullThen(t, NULL, file, line, __VA_ARGS__)
|
||||
#define testingTLogvfFull(t, file, line, format, ap) \
|
||||
testingprivTLogvfFullThen(t, NULL, file, line, format, ap)
|
||||
|
||||
#define testingTErrorf(t, ...) \
|
||||
testingprivTLogfFullThen(t, testingTFail, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define testingTErrorvf(t, format, ap) \
|
||||
testingprivTLogvfFullThen(t, testingTFail, __FILE__, __LINE__, format, ap)
|
||||
#define testingTErrorfFull(t, file, line, ...) \
|
||||
testingprivTLogfFullThen(t, testingTFail, file, line, __VA_ARGS__)
|
||||
#define testingTErrorvfFull(t, file, line, format, ap) \
|
||||
testingprivTLogvfFullThen(t, testingTFail, file, line, format, ap)
|
||||
|
||||
#define testingTFatalf(t, ...) \
|
||||
testingprivTLogfFullThen(t, testingTFailNow, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define testingTFatalvf(t, format, ap) \
|
||||
testingprivTLogvfFullThen(t, testingTFailNow, __FILE__, __LINE__, format, ap)
|
||||
#define testingTFatalfFull(t, file, line, ...) \
|
||||
testingprivTLogfFullThen(t, testingTFailNow, file, line, __VA_ARGS__)
|
||||
#define testingTFatalvfFull(t, file, line, format, ap) \
|
||||
testingprivTLogvfFullThen(t, testingTFailNow, file, line, format, ap)
|
||||
|
||||
#define testingTSkipf(t, ...) \
|
||||
testingprivTLogfFullThen(t, testingTSkipNow, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define testingTSkipvf(t, format, ap) \
|
||||
testingprivTLogvfFullThen(t, testingTSkipNow, __FILE__, __LINE__, format, ap)
|
||||
#define testingTSkipfFull(t, file, line, ...) \
|
||||
testingprivTLogfFullThen(t, testingTSkipNow, file, line, __VA_ARGS__)
|
||||
#define testingTSkipvfFull(t, file, line, format, ap) \
|
||||
testingprivTLogvfFullThen(t, testingTSkipNow, file, line, format, ap)
|
||||
|
||||
extern void testingTFail(testingT *t);
|
||||
extern void testingTFailNow(testingT *t);
|
||||
extern void testingTSkipNow(testingT *t);
|
||||
|
||||
extern void testingTDefer(testingT *t, void (*f)(testingT *t, void *data), void *data);
|
||||
extern void testingTRun(testingT *t, const char *subname, void (*subfunc)(testingT *t, void *data), void *data);
|
||||
|
||||
extern void testingprivSetRegisterTest(testingSet **pset, const char *, void (*)(testingT *, void *), void *, const char *, long);
|
||||
#include "../../sharedbits/printfwarn_header.h"
|
||||
sharedbitsPrintfFunc(
|
||||
extern void testingprivTLogfFullThen(testingT *, void (*)(testingT *), const char *, long, const char *, ...),
|
||||
5, 6);
|
||||
#undef sharedbitsPrintfFunc
|
||||
extern void testingprivTLogvfFullThen(testingT *, void (*)(testingT *), const char *, long, const char *, va_list);
|
||||
|
||||
// Utility functions, provided here to avoid mucking up the sharedbits functions.
|
||||
extern char *testingUtilStrdup(const char *s);
|
||||
extern void testingUtilFreeStrdup(char *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue