2022-01-02 15:00:54 +01:00
# ifndef XTEST_XTEST_H
# define XTEST_XTEST_H
# if defined(XTEST_XASSERT) && !defined(XTEST_SOURCE)
# error "do not include xtest.h and xassert.h at the same time. xassert.h should only be included from your source files and xtest.h should only be included from your test files."
# endif
# include <stdio.h>
# include <string.h>
# include <assert.h>
# ifndef XTEST_INDENT
# define XTEST_INDENT 2
# endif
typedef void ( * xtest_test_fn ) ( void * , void * * ) ;
typedef void ( * xtest_setup_fn ) ( void * * ) ;
typedef void ( * xtest_teardown_fn ) ( void * ) ;
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_fail_assert ( const char * expression , const char * file , int line , void * expected ,
void * actual , int invert , enum xtest_type type ) ;
void
xtest_assert_float ( double expected , double actual , int precision , int 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 ( ) ;
# 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, \
2022-01-03 15:20:44 +01:00
__typeof__ ( b ) : ( void * ) 0 \
2022-01-02 15:00:54 +01:00
)
# define xtest_assert_(expr, s, actual, expected, invert) do { \
force_types_equal ( expected , actual ) ; \
int _xtest_res = ( expr ) ; \
if ( ! ( _xtest_res ) ) { \
2022-01-03 15:20:44 +01:00
__typeof__ ( actual ) _xtest_a = actual ; \
__typeof__ ( expected ) _xtest_e = expected ; \
2022-01-02 15:00:54 +01:00
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_(memcmp(actual, expected, len) == 0, #actual " is " #expected " (" #len " bytes)", NULL, NULL, 0)
# define xtest_assert_mem_is_not(actual, expected, len) xtest_assert_(memcmp(actual, expected, len) != 0, #actual " is not " #expected " (" #len " bytes)", NULL, NULL, 1)
# endif //XTEST_XTEST_H