diff --git a/src/lib-test/test-common.c b/src/lib-test/test-common.c index 5807b0bc98..fd84686c90 100644 --- a/src/lib-test/test-common.c +++ b/src/lib-test/test-common.c @@ -365,6 +365,16 @@ static void test_run_funcs(void (*test_functions[])(void)) } T_END; } } +static void test_run_named_funcs(struct named_test tests[], const char *match) +{ + unsigned int i; + + for (i = 0; tests[i].func != NULL; i++) { + if (strstr(tests[i].name, match) != NULL) T_BEGIN { + tests[i].func(); + } T_END; + } +} static void run_one_fatal(enum fatal_test_state (*fatal_function)(int)) { @@ -407,6 +417,16 @@ static void test_run_fatals(enum fatal_test_state (*fatal_functions[])(int index } T_END; } } +static void test_run_named_fatals(const struct named_fatal fatals[], const char *match) +{ + unsigned int i; + + for (i = 0; fatals[i].func != NULL; i++) { + if (strstr(fatals[i].name, match) != NULL) T_BEGIN { + run_one_fatal(fatals[i].func); + } T_END; + } +} int test_run(void (*test_functions[])(void)) { @@ -414,6 +434,12 @@ int test_run(void (*test_functions[])(void)) test_run_funcs(test_functions); return test_deinit(); } +int test_run_named(struct named_test tests[], const char *match) +{ + test_init(); + test_run_named_funcs(tests, match); + return test_deinit(); +} int test_run_with_fatals(void (*test_functions[])(void), enum fatal_test_state (*fatal_functions[])(int)) { @@ -423,3 +449,12 @@ int test_run_with_fatals(void (*test_functions[])(void), test_run_fatals(fatal_functions); return test_deinit(); } +int test_run_named_with_fatals(const char *match, struct named_test tests[], + struct named_fatal fatals[]) +{ + test_init(); + test_run_named_funcs(tests, match); + i_set_fatal_handler(test_fatal_handler); + test_run_named_fatals(fatals, match); + return test_deinit(); +} diff --git a/src/lib-test/test-common.h b/src/lib-test/test-common.h index 027c3c1a2f..b956e7d78a 100644 --- a/src/lib-test/test-common.h +++ b/src/lib-test/test-common.h @@ -45,13 +45,32 @@ void test_out_reason(const char *name, bool success, const char *reason) ATTR_NULL(3); int test_run(void (*test_functions[])(void)); +struct named_test { + const char *name; + void (*func)(void); +}; +int test_run_named(struct named_test tests[], const char *match); + +#define TEST_DECL(x) void x(void); +#define TEST_NAMELESS(x) x, /* Were you to want to use the X trick but not name the tests */ +#define TEST_NAMED(x) { .name = #x , .func = x }, enum fatal_test_state { FATAL_TEST_FINISHED, /* no more test stages, don't call again */ FATAL_TEST_FAILURE, /* single stage has failed, continue */ FATAL_TEST_ABORT, /* something's gone horrifically wrong */ }; +struct named_fatal { + const char *name; + enum fatal_test_state (*func)(int); +}; int test_run_with_fatals(void (*test_functions[])(void), enum fatal_test_state (*fatal_functions[])(int)); +int test_run_named_with_fatals(const char *match, struct named_test tests[], + struct named_fatal fatals[]); + +#define FATAL_DECL(x) enum fatal_test_state x(int); +#define FATAL_NAMELESS(x) x, /* Were you to want to use the X trick but not name the tests */ +#define FATAL_NAMED(x) { .name = #x , .func = x }, #endif