mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-20 05:40:05 +01:00
util: add support for parametrized tests
munit supports test parameters (char* only) but the setup is a big
awkward/impossible in C to define statically. So lets simply pass the
parameters as one NULL-terminated string list and require names to be
prefixed with an @. During the test setup we can split that list up into
multiple parameters and pass those to the munit setup where they're
accessible via another wrapper macro:
MUNIT_TEST_WITH_PARAMS(test_foo, "@x", "1", "2", "@y", "100", "200") {
const char *x = MUNIT_TEST_PARAM("@x");
const char *y = MUNIT_TEST_PARAM("@y");
}
Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/365>
This commit is contained in:
parent
d55da9466c
commit
2996a66b37
2 changed files with 64 additions and 1 deletions
|
|
@ -56,10 +56,42 @@ munit_tests_run(int argc, char **argv)
|
|||
_cleanup_free_ MunitTest *tests = calloc(count, sizeof(*tests));
|
||||
size_t idx = 0;
|
||||
foreach_test(t) {
|
||||
size_t nparams = 0;
|
||||
MunitParameterEnum *parameters = calloc(MUNIT_TEST_MAX_PARAMS, sizeof(*parameters));
|
||||
|
||||
const char *name = NULL;
|
||||
char **values = NULL;
|
||||
for (size_t i = 0; t->params[i]; i++) {
|
||||
if (t->params[i][0] == '@') {
|
||||
if (name != NULL) {
|
||||
assert(nparams < MUNIT_TEST_MAX_PARAMS);
|
||||
assert(strv_len(values) > 0);
|
||||
/* Not stripping the @! */
|
||||
parameters[nparams].name = xstrdup(name);
|
||||
parameters[nparams].values = steal(&values);
|
||||
++nparams;
|
||||
}
|
||||
name = t->params[i];
|
||||
} else {
|
||||
assert(i > 0); /* First one must be a name */
|
||||
values = strv_append_strdup(values, t->params[i]);
|
||||
}
|
||||
}
|
||||
if (name != NULL) {
|
||||
assert(nparams < MUNIT_TEST_MAX_PARAMS);
|
||||
assert(strv_len(values) > 0);
|
||||
/* Not stripping the @! */
|
||||
parameters[nparams].name = xstrdup(name);
|
||||
parameters[nparams].values = steal(&values);
|
||||
++nparams;
|
||||
}
|
||||
|
||||
MunitTest test = {
|
||||
.name = xaprintf("%s", t->name),
|
||||
.test = t->func,
|
||||
.parameters = parameters,
|
||||
};
|
||||
|
||||
tests[idx++] = test;
|
||||
}
|
||||
|
||||
|
|
@ -91,8 +123,10 @@ munit_tests_run(int argc, char **argv)
|
|||
|
||||
int rc = munit_suite_main(&suite, setup.userdata, setup.argc, setup.argv);
|
||||
|
||||
for (idx = 0; idx < count; idx++)
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
free(tests[idx].name);
|
||||
free(tests[idx].parameters);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@
|
|||
|
||||
#include <munit.h>
|
||||
|
||||
/* Random number, bumb if need be */
|
||||
#define MUNIT_TEST_MAX_PARAMS 64
|
||||
|
||||
/**
|
||||
* Put at the top of the file somewhere, declares the start/stop for the test section we need.
|
||||
*/
|
||||
|
|
@ -61,6 +64,7 @@ struct test_function {
|
|||
const char *name; /* function name */
|
||||
const char *file; /* file name */
|
||||
munit_test_func_t func; /* test function */
|
||||
const char *params[MUNIT_TEST_MAX_PARAMS];
|
||||
} __attribute__((aligned(16)));
|
||||
|
||||
/**
|
||||
|
|
@ -104,9 +108,34 @@ __attribute__((section("test_functions_section"))) = { \
|
|||
.name = #_func, \
|
||||
.func = _func, \
|
||||
.file = __FILE__, \
|
||||
.params = { NULL }, \
|
||||
}; \
|
||||
static MunitResult _func(const MunitParameter params[], void *user_data)
|
||||
|
||||
/**
|
||||
* Same as MUNIT test but takes a list of strings that define parameters
|
||||
* and their values. Parameter names must be prefixed with @, for example:
|
||||
* MUNIT_TEST_WITH_PARAMS(test_foo, "@x", "1", "2", "@y", "100", "200") {
|
||||
* const char *x = MUNIT_TEST_PARAM("@x");
|
||||
* const char *y = MUNIT_TEST_PARAM("@y");
|
||||
* }
|
||||
*/
|
||||
#define MUNIT_TEST_WITH_PARAMS(_func, ...) \
|
||||
static MunitResult _func(const MunitParameter params[], void *user_data); \
|
||||
static const struct test_function _test_##_func \
|
||||
__attribute__((used)) \
|
||||
__attribute__((section("test_functions_section"))) = { \
|
||||
.name = #_func, \
|
||||
.func = _func, \
|
||||
.file = __FILE__, \
|
||||
.params = { __VA_ARGS__, NULL }, \
|
||||
}; \
|
||||
static MunitResult _func(const MunitParameter params[], void *user_data)
|
||||
|
||||
/* Retrieve the test parameter with the given name */
|
||||
#define MUNIT_TEST_PARAM(name_) \
|
||||
munit_parameters_get(params, name_)
|
||||
|
||||
/**
|
||||
* Defines a struct global_setup_function in a custom ELF section that we can
|
||||
* then find in munit_tests_run() to do setup based on argv and/or pass userdata
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue