164 lines
6.2 KiB
C
164 lines
6.2 KiB
C
#ifndef XTEST_XTEST_H
|
|
#define XTEST_XTEST_H
|
|
|
|
#if defined(XTEST_XASSERT)
|
|
#error "do not include xtest.h before assert.h. If your tests make use of standard library assertions, include first xtest.h and then assert.h"
|
|
#endif
|
|
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
#define XTEST_UNUSED __attribute__((unused))
|
|
#else
|
|
#define XTEST_UNUSED
|
|
#endif
|
|
|
|
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
|
|
typedef void (*xtest_test_fn)(void * fixture, void ** params);
|
|
typedef void (*xtest_setup_fn)(void ** fixture);
|
|
typedef void (*xtest_teardown_fn)(void * fixture);
|
|
|
|
typedef struct xtest_param_s xtest_param;
|
|
|
|
typedef void *xtest_param_values[];
|
|
|
|
|
|
struct xtest_param_s {
|
|
const char *name;
|
|
xtest_param_values *values;
|
|
};
|
|
|
|
enum xtest_type {
|
|
xtest_type_bool,
|
|
xtest_type_char,
|
|
xtest_type_short,
|
|
xtest_type_unsigned_short,
|
|
xtest_type_int,
|
|
xtest_type_unsigned_int,
|
|
xtest_type_long,
|
|
xtest_type_unsigned_long,
|
|
xtest_type_long_long,
|
|
xtest_type_unsigned_long_long,
|
|
xtest_type_float,
|
|
xtest_type_double,
|
|
xtest_type_long_double,
|
|
xtest_type_string,
|
|
xtest_type_void_pointer,
|
|
xtest_type_other,
|
|
};
|
|
|
|
void xtest_init(int argc, char**argv);
|
|
|
|
void xtest_fail_assert(const char *expression, const char *file, int line, void *expected,
|
|
void *actual, _Bool invert, enum xtest_type type);
|
|
void
|
|
xtest_assert_float(double expected, double actual, int precision, _Bool invert, const char *expression, const char *file,
|
|
int line);
|
|
|
|
void xtest_assert_mem(const char *expected, const char *actual, size_t length, _Bool invert, const char *expression, const char *file,
|
|
int line);
|
|
|
|
void xtest_internal_run(xtest_test_fn fn, const char *name, xtest_param *params, xtest_setup_fn setup,
|
|
xtest_teardown_fn teardown);
|
|
|
|
void xtest_internal_start_group(const char *name);
|
|
void xtest_internal_end_group();
|
|
|
|
void xtest_skip(const char *reason);
|
|
void xtest_expect_assertion_failure();
|
|
int xtest_complete();
|
|
|
|
#ifdef XTEST_PRNG
|
|
void xtest_rand_fill(char* buf, size_t len);
|
|
double xtest_rand_double();
|
|
double xtest_rand_double_range(double min, double max);
|
|
int xtest_rand_int();
|
|
int xtest_rand_int_range(int min, int max);
|
|
uint8_t xtest_rand_8();
|
|
uint16_t xtest_rand_16();
|
|
uint32_t xtest_rand_32();
|
|
uint64_t xtest_rand_64();
|
|
#endif
|
|
|
|
|
|
#define xtest_run(fn) xtest_internal_run(fn, #fn, (void*)0, (void*)0, (void*)0)
|
|
#define xtest_run_parameterized(fn, params) xtest_internal_run(fn, #fn, params, (void*)0, (void*)0)
|
|
#define xtest_run_with_fixture(fn, setup, teardown) xtest_internal_run(fn, #fn, (void*)0, setup, teardown)
|
|
#define xtest_run_parameterized_with_fixture(fn, params, setup, teardown) xtest_internal_run(fn, #fn, params, setup, teardown)
|
|
|
|
#define xtest_group(name) xtest_internal_start_group(#name)
|
|
#define xtest_end_group() xtest_internal_end_group()
|
|
|
|
#define xtest_run_group(fn) do { \
|
|
xtest_group(fn); \
|
|
fn(); \
|
|
xtest_end_group(); \
|
|
} while (0)
|
|
|
|
#define xtest_get_param(type, idx, params) *((type*)(params)[idx])
|
|
#define xtest_get_param_ptr(type, idx, params) (type)(params)[idx]
|
|
|
|
|
|
#define xtest_get_type(val) _Generic(val, \
|
|
_Bool: xtest_type_bool, \
|
|
char: xtest_type_char, \
|
|
signed char: xtest_type_char, \
|
|
unsigned char: xtest_type_char, \
|
|
short: xtest_type_short, \
|
|
unsigned short: xtest_type_unsigned_short,\
|
|
int: xtest_type_int,\
|
|
unsigned int: xtest_type_unsigned_int,\
|
|
long: xtest_type_long,\
|
|
unsigned long: xtest_type_unsigned_long,\
|
|
long long: xtest_type_long_long,\
|
|
unsigned long long: xtest_type_unsigned_long_long,\
|
|
float: xtest_type_float,\
|
|
double: xtest_type_double,\
|
|
long double: xtest_type_long_double,\
|
|
const char *: xtest_type_string,\
|
|
void*:xtest_type_void_pointer,\
|
|
default: xtest_type_other)
|
|
|
|
|
|
#define force_types_equal(a, b) (void) _Generic(a, \
|
|
__typeof__(b): (void*)0 \
|
|
)
|
|
|
|
|
|
#define xtest_assert_(expr, s, actual, expected, invert) do { \
|
|
force_types_equal(expected, actual); \
|
|
int _xtest_res = (expr); \
|
|
if (!(_xtest_res)) { \
|
|
__typeof__(actual) _xtest_a = actual; \
|
|
__typeof__(expected) _xtest_e = expected; \
|
|
enum xtest_type _xtest_type = xtest_get_type(actual); \
|
|
xtest_fail_assert(s, __FILE__, __LINE__, &_xtest_e, &_xtest_a, invert, _xtest_type); \
|
|
} \
|
|
} while(0)
|
|
|
|
#define xtest_assert(e) xtest_assert_(!!(e), #e, (_Bool)(e), (_Bool)1, 0)
|
|
#define xtest_assert_is(actual, expected) xtest_assert_((actual) == (expected), #actual " is " #expected, actual, expected, 0)
|
|
#define xtest_assert_is_not(actual, expected) xtest_assert_((actual) != (expected), #actual " is not " #expected, actual, expected, 1)
|
|
#define xtest_assert_float_is(actual, expected, precision) xtest_assert_float(expected, actual, precision, 0, #actual " is " #expected, __FILE__, __LINE__)
|
|
#define xtest_assert_float_is_not(actual, expected, precision) xtest_assert_float(expected, actual, precision, 1, #actual " is not " #expected, __FILE__, __LINE__)
|
|
#define xtest_assert_str_is(actual, expected) xtest_assert_(strcmp(actual, expected) == 0, #actual " is " #expected, (const char*)(actual), (const char*)(expected), 0)
|
|
#define xtest_assert_str_is_not(actual, expected) xtest_assert_(strcmp(actual, expected) != 0, #actual " is not " #expected, (const char*)(actual), (const char*)(expected), 1)
|
|
#define xtest_assert_mem_is(actual, expected, len) xtest_assert_mem(expected, actual, len, 0, #actual " is " #expected " (" #len " bytes)", __FILE__, __LINE__)
|
|
#define xtest_assert_mem_is_not(actual, expected, len) xtest_assert_mem(expected, actual, len, 1, #actual " is not " #expected " (" #len " bytes)", __FILE__, __LINE__)
|
|
|
|
|
|
#define XTEST_RUN_MAIN(fn) int main(int argc, char ** argv) { \
|
|
xtest_init(argc, argv); \
|
|
fn(); \
|
|
return xtest_complete(); \
|
|
}
|
|
|
|
|
|
#define XTEST_MAIN void __xtest_main(); \
|
|
XTEST_RUN_MAIN(__xtest_main) \
|
|
void __xtest_main()
|
|
|
|
|
|
#endif //XTEST_XTEST_H
|