diff --git a/src/compat/pipe.c b/src/compat/pipe.c index 30a3ef1..1c05a20 100644 --- a/src/compat/pipe.c +++ b/src/compat/pipe.c @@ -318,3 +318,25 @@ static s_pipe_handle stdin_redir_; s_pipe_handle *stdout_redir = &stdout_redir_; s_pipe_handle *stderr_redir = &stderr_redir_; s_pipe_handle *stdin_redir = &stdin_redir_; + +s_pipe_file_handle *pipe_file_open(const char *path) { + s_pipe_file_handle *h = smalloc( + .size = sizeof (s_pipe_file_handle), + .dtor = close_pipe_file_handle); +#ifdef VANILLA_WIN32 + if (!path) + path = "nul"; + h->fh = CreateFile(path, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); +#else + if (!path) + path = "/dev/null"; + h->fd = open(path, O_RDWR); +#endif + return h; +} diff --git a/src/compat/pipe.h b/src/compat/pipe.h index d0e162d..6799982 100644 --- a/src/compat/pipe.h +++ b/src/compat/pipe.h @@ -79,4 +79,6 @@ extern s_pipe_handle *stdout_redir; extern s_pipe_handle *stderr_redir; extern s_pipe_handle *stdin_redir; +s_pipe_file_handle *pipe_file_open(const char *path); + #endif /* !PIPE_H_ */ diff --git a/src/core/runner.c b/src/core/runner.c index d5c6a00..79dedb3 100644 --- a/src/core/runner.c +++ b/src/core/runner.c @@ -488,3 +488,24 @@ int criterion_run_all_tests(struct criterion_test_set *set) { return criterion_options.always_succeed || res; } + +void run_single_test_by_name(const char *testname) { + struct criterion_test_set *set = criterion_init(); + + g_event_pipe = pipe_file_open(NULL); + + FOREACH_SET(struct criterion_suite_set *s, set->suites) { + size_t tests = s->tests ? s->tests->size : 0; + if (!tests) + continue; + + FOREACH_SET(struct criterion_test *t, s->tests) { + char name[1024]; + snprintf(name, sizeof (name), "%s::%s", s->suite.name, t->name); + if (!strncmp(name, testname, 1024)) + run_test_child(t, &s->suite); + } + } + + sfree(set); +} diff --git a/src/core/runner.h b/src/core/runner.h index 0eafbb7..49039bf 100644 --- a/src/core/runner.h +++ b/src/core/runner.h @@ -43,4 +43,6 @@ void run_test_child(struct criterion_test *test, struct criterion_suite *suite); Suite < (struct criterion_suite**) GET_SECTION_END(cr_sts); \ ++Suite) +void run_single_test_by_name(const char *testname); + #endif /* !CRITERION_RUNNER_H_ */ diff --git a/src/entry/params.c b/src/entry/params.c index 5d71a68..a6dc8a0 100644 --- a/src/entry/params.c +++ b/src/entry/params.c @@ -149,6 +149,7 @@ int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg) { {"jobs", required_argument, 0, 'j'}, {"fail-fast", no_argument, 0, 'f'}, {"short-filename", no_argument, 0, 'S'}, + {"single", required_argument, 0, 's'}, #ifdef HAVE_PCRE {"pattern", required_argument, 0, 'p'}, #endif @@ -245,6 +246,7 @@ int criterion_handle_args(int argc, char *argv[], bool handle_unknown_arg) { case 'j': criterion_options.jobs = atou(optarg); break; case 'f': criterion_options.fail_fast = true; break; case 'S': criterion_options.short_filename = true; break; + case 's': run_single_test_by_name(optarg); return 0; #ifdef HAVE_PCRE case 'p': criterion_options.pattern = optarg; break; #endif