diff --git a/include/criterion/parameterized.h b/include/criterion/parameterized.h index a3c199f..135fbe4 100644 --- a/include/criterion/parameterized.h +++ b/include/criterion/parameterized.h @@ -38,11 +38,11 @@ static struct criterion_test_params IDENTIFIER_(Category, Name, param)(void) # ifdef __cplusplus -# define cr_make_param_array(Type, Array, Length) \ - criterion_test_params(sizeof (Type), (Array), (Length)) +# define cr_make_param_array(Type, Array, ...) \ + criterion_test_params(sizeof (Type), (Array), __VA_ARGS__) # else -# define cr_make_param_array(Type, Array, Length) \ - (struct criterion_test_params) { sizeof (Type), (void*)(Array), (Length) } +# define cr_make_param_array(Type, Array, ...) \ + (struct criterion_test_params) { sizeof (Type), (void*)(Array), __VA_ARGS__ } # endif #endif /* !CRITERION_PARAMETERIZED_H_ */ diff --git a/include/criterion/types.h b/include/criterion/types.h index bbb11aa..93a54c9 100644 --- a/include/criterion/types.h +++ b/include/criterion/types.h @@ -42,6 +42,7 @@ struct criterion_test_params { size_t size; void *params; size_t length; + void (*cleanup)(struct criterion_test_params *); # ifdef __cplusplus constexpr criterion_test_params(size_t size, void *params, size_t length) @@ -49,6 +50,14 @@ struct criterion_test_params { , params(params) , length(length) {} + + constexpr criterion_test_params(size_t size, void *params, size_t length, + void (*cleanup)(struct criterion_test_params *)) + : size(size) + , params(params) + , length(length) + , cleanup(cleanup) + {} # endif }; diff --git a/samples/parameterized.c b/samples/parameterized.c index 0d9ab2e..9c6c863 100644 --- a/samples/parameterized.c +++ b/samples/parameterized.c @@ -1,4 +1,7 @@ #include +#include + +// Basic usage ParameterizedTestParameters(params, str) { static const char *strings[] = { @@ -9,5 +12,63 @@ ParameterizedTestParameters(params, str) { } ParameterizedTest(const char **str, params, str) { - cr_assert(0, "Parameter: %s", *str); + cr_assert_fail("Parameter: %s", *str); +} + +// Multiple parameters must be coalesced in a single parameter + +struct parameter_tuple { + int i; + double d; +}; + +ParameterizedTestParameters(params, multiple) { + static struct parameter_tuple params[] = { + {1, 2}, + {3, 4}, + {5, 6}, + }; + + return cr_make_param_array(struct parameter_tuple, params, sizeof (params) / sizeof (struct parameter_tuple)); +} + +ParameterizedTest(struct parameter_tuple *tup, params, multiple) { + cr_assert_fail("Parameters: (%d, %f)", tup->i, tup->d); +} + +// Cleaning up dynamically generated parameters + +// Note: Do **NOT** embed dynamically allocated pointers inside of structures +// or this will fail on windows + +void free_params(struct criterion_test_params *crp) { + struct parameter_tuple_dyn *tuples = crp->params; + for (size_t i = 0; i < crp->length; ++i) { + struct parameter_tuple_dyn *tup = &tuples[i]; + free(tup->d); + } + free(crp->params); +} + +double *gen_double(double d) { + double *ptr = malloc(sizeof(double)); + printf("%p\n", ptr); + fflush(NULL); + *ptr = d; + return ptr; +} + +ParameterizedTestParameters(params, cleanup) { + const size_t nb_tuples = 3; + + struct parameter_tuple_dyn *params = malloc(sizeof(struct parameter_tuple_dyn) * nb_tuples); + params[0] = (struct parameter_tuple_dyn) { 1, gen_double(2) }; + params[1] = (struct parameter_tuple_dyn) { 3, gen_double(4) }; + params[2] = (struct parameter_tuple_dyn) { 5, gen_double(6) }; + + return cr_make_param_array(struct parameter_tuple_dyn, params, nb_tuples, free_params); +} + +ParameterizedTest(struct parameter_tuple_dyn *tup, params, cleanup) { + cr_assert_fail("Parameters: (%d, %p)", tup->i, tup->d); } diff --git a/src/core/runner.c b/src/core/runner.c index cd3f13b..a998843 100644 --- a/src/core/runner.c +++ b/src/core/runner.c @@ -396,6 +396,9 @@ static void run_test_param(struct criterion_global_stats *stats, if (!is_runner()) break; } + + if (params.cleanup) + params.cleanup(¶ms); } static void run_test_switch(struct criterion_global_stats *stats,