Refactored the default main to allow dynamic test registration

This commit is contained in:
Snaipe 2015-09-07 15:55:36 +02:00
parent aca092b9d6
commit d7466dc0e5
5 changed files with 72 additions and 39 deletions

View file

@ -10,6 +10,13 @@ can define your own main function.
Configuring the test runner
~~~~~~~~~~~~~~~~~~~~~~~~~~~
First and foremost, you need to generate the test set; this is done by calling
``criterion_initialize()``. The function returns a ``struct criterion_test_set *``,
that you need to pass to ``criterion_run_all_tests`` later on.
At the very end of your main, you also need to call ``criterion_finalize`` with
the test set as parameter to free any ressources initialized by criterion earlier.
You'd usually want to configure the test runner before calling it.
Configuration is done by setting fields in a global variable named
``criterion_options`` (include criterion/options.h).
@ -35,7 +42,7 @@ pattern const char * The pattern of the tests
=================== ================================== ==============================================================
if you want criterion to provide its own default CLI parameters and environment
variables handling, you can also call ``criterion_initialize(int argc, char *argv[], bool handle_unknown_arg)``
variables handling, you can also call ``criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg)``
with the proper ``argc/argv``. ``handle_unknown_arg``, if set to true, is here
to tell criterion to print its usage when an unknown CLI parameter is encountered.
If you want to add your own parameters, you should set it to false.
@ -57,10 +64,15 @@ Example main
#include <criterion/criterion.h>
int main(int argc, char *argv[]) {
if (!criterion_initialize(argc, argv, true))
struct criterion_test_set *tests = criterion_initialize();
if (!criterion_handle_args(argc, argv, true))
return 0;
return !criterion_run_all_tests();
int result = !criterion_run_all_tests(set);
criterion_finalize(set);
return result;
}
Implementing your own output provider

View file

@ -78,8 +78,12 @@
CR_BEGIN_C_API
CR_API int criterion_run_all_tests(void);
CR_API int criterion_initialize(int argc, char *argv[], bool handle_unknown_arg);
CR_API struct criterion_test_set *criterion_initialize(void);
CR_API void criterion_finalize(struct criterion_test_set *tests);
CR_API int criterion_run_all_tests(struct criterion_test_set *tests);
CR_API int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg);
CR_API void criterion_register_test(struct criterion_test_set *tests,
struct criterion_test *test);
CR_END_C_API

View file

@ -1,8 +1,14 @@
#include "criterion/criterion.h"
CR_API int main(int argc, char *argv[]) {
if (!criterion_initialize(argc, argv, true))
struct criterion_test_set *tests = criterion_initialize();
if (!criterion_handle_args(argc, argv, true))
return 0;
return !criterion_run_all_tests();
int result = !criterion_run_all_tests(tests);
criterion_finalize(tests);
return result;
}

View file

@ -120,7 +120,7 @@ int list_tests(bool unicode) {
return 0;
}
CR_API int criterion_initialize(int argc, char *argv[], bool handle_unknown_arg) {
int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg) {
static struct option opts[] = {
{"verbose", optional_argument, 0, 'b'},
{"version", no_argument, 0, 'v'},

View file

@ -80,6 +80,20 @@ static void dtor_test_set(void *ptr, UNUSED void *meta) {
sfree(t->suites);
}
void criterion_register_test(struct criterion_test_set *set,
struct criterion_test *test) {
struct criterion_suite_set css = {
.suite = { .name = test->category },
};
struct criterion_suite_set *s = insert_ordered_set(set->suites, &css, sizeof (css));
if (!s->tests)
s->tests = new_ordered_set(cmp_test, NULL);
insert_ordered_set(s->tests, test, sizeof(*test));
++set->tests;
}
struct criterion_test_set *criterion_init(void) {
struct criterion_ordered_set *suites = new_ordered_set(cmp_suite, dtor_suite_set);
@ -93,25 +107,6 @@ struct criterion_test_set *criterion_init(void) {
insert_ordered_set(suites, &css, sizeof (css));
}
size_t nb_tests = 0;
FOREACH_TEST_SEC(test) {
if (!test->category)
break;
if (!*test->category)
continue;
struct criterion_suite_set css = {
.suite = { .name = test->category },
};
struct criterion_suite_set *s = insert_ordered_set(suites, &css, sizeof (css));
if (!s->tests)
s->tests = new_ordered_set(cmp_test, NULL);
insert_ordered_set(s->tests, test, sizeof(*test));
++nb_tests;
}
struct criterion_test_set *set = smalloc(
.size = sizeof (struct criterion_test_set),
.dtor = dtor_test_set
@ -119,9 +114,19 @@ struct criterion_test_set *criterion_init(void) {
*set = (struct criterion_test_set) {
suites,
nb_tests,
0,
};
FOREACH_TEST_SEC(test) {
if (!test->category)
break;
if (!*test->category)
continue;
criterion_register_test(set, test);
}
return set;
}
@ -341,16 +346,27 @@ void disable_unmatching(struct criterion_test_set *set) {
}
#endif
static int criterion_run_all_tests_impl(void) {
struct criterion_test_set *criterion_initialize(void) {
init_i18n();
if (resume_child()) // (windows only) resume from the fork
return -1;
exit(0);
struct criterion_test_set *set = criterion_init();
#ifdef HAVE_PCRE
#ifdef HAVE_PCRE
if (criterion_options.pattern)
disable_unmatching(set);
#endif
#endif
return set;
}
void criterion_finalize(struct criterion_test_set *set) {
sfree(set);
}
static int criterion_run_all_tests_impl(struct criterion_test_set *set) {
report(PRE_ALL, set);
log(pre_all, set);
@ -368,19 +384,14 @@ static int criterion_run_all_tests_impl(void) {
log(post_all, stats);
cleanup:
sfree(set);
sfree(stats);
return result;
}
int criterion_run_all_tests(void) {
init_i18n();
int criterion_run_all_tests(struct criterion_test_set *set) {
set_runner_process();
int res = criterion_run_all_tests_impl();
int res = criterion_run_all_tests_impl(set);
unset_runner_process();
if (res == -1) // if this is the test worker terminating
exit(0);
return criterion_options.always_succeed || res;
}