From db0de783202729ef2422c0b23998eeccac93bf56 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Sun, 22 Mar 2015 21:23:14 +0100 Subject: [PATCH 1/4] Added --list command-line switch --- include/criterion/options.h | 1 + src/main.c | 65 +++++++++++++++++++++++++++++++++++-- src/runner.c | 2 +- src/runner.h | 2 ++ 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/include/criterion/options.h b/include/criterion/options.h index d04db21..94829cf 100644 --- a/include/criterion/options.h +++ b/include/criterion/options.h @@ -32,6 +32,7 @@ struct criterion_options { bool enable_tap_format; bool no_early_exit; bool always_succeed; + bool use_ascii; }; extern struct criterion_options criterion_options; diff --git a/src/main.c b/src/main.c index ab362ea..3911cd7 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,11 @@ #define _GNU_SOURCE #include #include +#include #include #include +#include +#include "runner.h" # define VERSION "v1.0.0" # define VERSION_MSG "Tests compiled with Criterion " VERSION "\n" @@ -14,6 +17,9 @@ " -h or --help: prints this message\n" \ " -v or --version: prints the version of criterion " \ "these tests have been linked against\n" \ + " -l or --list: prints all the tests in a list\n" \ + " --ascii: don't use fancy unicode symbols " \ + "or colors in the output\n" \ " --tap: enables TAP formatting\n" \ " --always-succeed: always exit with 0\n" \ " --no-early-exit: do not exit the test worker " \ @@ -31,12 +37,54 @@ int print_version(void) { return 0; } +# define UTF8_TREE_NODE "├" +# define UTF8_TREE_END "└" +# define UTF8_TREE_JOIN "──" + +# define ASCII_TREE_NODE "|" +# define ASCII_TREE_END "`" +# define ASCII_TREE_JOIN "--" + +bool is_disabled(struct criterion_suite *s, struct criterion_test *t) { + return (s->data && s->data->disabled) || t->data->disabled; +} + +int list_tests(bool unicode) { + smart struct criterion_test_set *set = criterion_init(); + + const char *node = unicode ? UTF8_TREE_NODE : ASCII_TREE_NODE; + const char *join = unicode ? UTF8_TREE_JOIN : ASCII_TREE_JOIN; + const char *end = unicode ? UTF8_TREE_END : ASCII_TREE_END; + + FOREACH_SET(struct criterion_suite_set *s, set->suites) { + size_t tests = s->tests ? s->tests->size : 0; + if (!tests) + continue; + + printf("%s: " SIZE_T_FORMAT " test%s\n", + s->suite.name, + tests, + tests == 1 ? "" : "s"); + + FOREACH_SET(struct criterion_test *t, s->tests) { + printf("%s%s %s%s\n", + --tests == 0 ? end : node, + join, + t->name, + is_disabled(&s->suite, t) ? "(disabled)" : ""); + } + } + return 0; +} + int main(int argc, char *argv[]) { static struct option opts[] = { {"verbose", optional_argument, 0, 'b'}, {"version", no_argument, 0, 'v'}, {"tap", no_argument, 0, 't'}, {"help", no_argument, 0, 'h'}, + {"list", no_argument, 0, 'l'}, + {"ascii", no_argument, 0, 'k'}, {"always-succeed", no_argument, 0, 'y'}, {"no-early-exit", no_argument, 0, 'z'}, {0, 0, 0, 0 } @@ -49,17 +97,28 @@ int main(int argc, char *argv[]) { .logging_threshold = atoi(getenv("CRITERION_VERBOSITY_LEVEL") ?: "2"), }; - for (int c; (c = getopt_long(argc, argv, "hv", opts, NULL)) != -1;) { + bool do_list_tests = false; + bool do_print_version = false; + bool do_print_usage = false; + for (int c; (c = getopt_long(argc, argv, "hvl", opts, NULL)) != -1;) { switch (c) { case 'b': criterion_options.logging_threshold = atoi(optarg ?: "1"); break; case 't': criterion_options.enable_tap_format = true; break; case 'y': criterion_options.always_succeed = true; break; case 'z': criterion_options.no_early_exit = true; break; - case 'v': return print_version(); + case 'k': criterion_options.use_ascii = true; break; + case 'l': do_list_tests = true; break; + case 'v': do_print_version = true; break; case 'h': - default : return print_usage(argv[0]); + default : do_print_usage = true; break; } } + if (do_print_usage) + return print_usage(argv[0]); + if (do_print_version) + return print_version(); + if (do_list_tests) + return list_tests(!criterion_options.use_ascii); return !criterion_run_all_tests(); } diff --git a/src/runner.c b/src/runner.c index baaeee0..231bfc9 100644 --- a/src/runner.c +++ b/src/runner.c @@ -59,7 +59,7 @@ static void dtor_test_set(void *ptr, UNUSED void *meta) { sfree(t->suites); } -static struct criterion_test_set *criterion_init(void) { +struct criterion_test_set *criterion_init(void) { struct criterion_ordered_set *suites = new_ordered_set(cmp_suite, dtor_suite_set); FOREACH_SUITE_SEC(s) { diff --git a/src/runner.h b/src/runner.h index ca243f0..64cc668 100644 --- a/src/runner.h +++ b/src/runner.h @@ -29,6 +29,8 @@ DECL_SECTION_LIMITS(struct criterion_test, criterion_tests); DECL_SECTION_LIMITS(struct criterion_suite, crit_suites); +struct criterion_test_set *criterion_init(void); + # define FOREACH_TEST_SEC(Test) \ for (struct criterion_test *Test = SECTION_START(criterion_tests); \ Test < SECTION_END(criterion_tests); \ From 19720c2c2c448d60534f484c29f07a042d430b89 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Sun, 22 Mar 2015 21:32:44 +0100 Subject: [PATCH 2/4] Added --fail-fast command-line switch --- include/criterion/options.h | 1 + src/main.c | 5 ++++- src/runner.c | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/criterion/options.h b/include/criterion/options.h index 94829cf..12d9888 100644 --- a/include/criterion/options.h +++ b/include/criterion/options.h @@ -33,6 +33,7 @@ struct criterion_options { bool no_early_exit; bool always_succeed; bool use_ascii; + bool fail_fast; }; extern struct criterion_options criterion_options; diff --git a/src/main.c b/src/main.c index 3911cd7..518faac 100644 --- a/src/main.c +++ b/src/main.c @@ -18,6 +18,7 @@ " -v or --version: prints the version of criterion " \ "these tests have been linked against\n" \ " -l or --list: prints all the tests in a list\n" \ + " -f or --fail-fast: exit after the first failure\n" \ " --ascii: don't use fancy unicode symbols " \ "or colors in the output\n" \ " --tap: enables TAP formatting\n" \ @@ -85,6 +86,7 @@ int main(int argc, char *argv[]) { {"help", no_argument, 0, 'h'}, {"list", no_argument, 0, 'l'}, {"ascii", no_argument, 0, 'k'}, + {"fail-fast", no_argument, 0, 'f'}, {"always-succeed", no_argument, 0, 'y'}, {"no-early-exit", no_argument, 0, 'z'}, {0, 0, 0, 0 } @@ -100,13 +102,14 @@ int main(int argc, char *argv[]) { bool do_list_tests = false; bool do_print_version = false; bool do_print_usage = false; - for (int c; (c = getopt_long(argc, argv, "hvl", opts, NULL)) != -1;) { + for (int c; (c = getopt_long(argc, argv, "hvlf", opts, NULL)) != -1;) { switch (c) { case 'b': criterion_options.logging_threshold = atoi(optarg ?: "1"); break; case 't': criterion_options.enable_tap_format = true; break; case 'y': criterion_options.always_succeed = true; break; case 'z': criterion_options.no_early_exit = true; break; case 'k': criterion_options.use_ascii = true; break; + case 'f': criterion_options.fail_fast = true; break; case 'l': do_list_tests = true; break; case 'v': do_print_version = true; break; case 'h': diff --git a/src/runner.c b/src/runner.c index 231bfc9..85b4238 100644 --- a/src/runner.c +++ b/src/runner.c @@ -98,6 +98,8 @@ static void map_tests(struct criterion_test_set *set, struct criterion_global_st FOREACH_SET(struct criterion_test *t, s->tests) { fun(stats, t, &s->suite); + if (criterion_options.fail_fast && stats->tests_failed > 0) + return; if (!is_runner()) return; } From 0d64a92b50b215697d629aa8dd2724939f8bedb5 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Sun, 22 Mar 2015 21:43:23 +0100 Subject: [PATCH 3/4] Added missing header in main.c --- src/main.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main.c b/src/main.c index 518faac..86f1a20 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,26 @@ +/* + * The MIT License (MIT) + * + * Copyright © 2015 Franklin "Snaipe" Mathieu + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #define _GNU_SOURCE #include #include From 8c8d14901e94a863730010f913b45831bd95ee48 Mon Sep 17 00:00:00 2001 From: Snaipe Date: Sun, 22 Mar 2015 23:16:09 +0100 Subject: [PATCH 4/4] Added pattern filtering over parameters --- include/criterion/options.h | 1 + src/main.c | 4 ++++ src/report.c | 17 +++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/include/criterion/options.h b/include/criterion/options.h index 12d9888..ca622a7 100644 --- a/include/criterion/options.h +++ b/include/criterion/options.h @@ -34,6 +34,7 @@ struct criterion_options { bool always_succeed; bool use_ascii; bool fail_fast; + const char *pattern; }; extern struct criterion_options criterion_options; diff --git a/src/main.c b/src/main.c index 86f1a20..63a6631 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,8 @@ " -f or --fail-fast: exit after the first failure\n" \ " --ascii: don't use fancy unicode symbols " \ "or colors in the output\n" \ + " --pattern [PATTERN]: run tests matching the " \ + "given pattern\n" \ " --tap: enables TAP formatting\n" \ " --always-succeed: always exit with 0\n" \ " --no-early-exit: do not exit the test worker " \ @@ -110,6 +112,7 @@ int main(int argc, char *argv[]) { {"list", no_argument, 0, 'l'}, {"ascii", no_argument, 0, 'k'}, {"fail-fast", no_argument, 0, 'f'}, + {"pattern", required_argument, 0, 'p'}, {"always-succeed", no_argument, 0, 'y'}, {"no-early-exit", no_argument, 0, 'z'}, {0, 0, 0, 0 } @@ -133,6 +136,7 @@ int main(int argc, char *argv[]) { case 'z': criterion_options.no_early_exit = true; break; case 'k': criterion_options.use_ascii = true; break; case 'f': criterion_options.fail_fast = true; break; + case 'p': criterion_options.pattern = optarg; break; case 'l': do_list_tests = true; break; case 'v': do_print_version = true; break; case 'h': diff --git a/src/report.c b/src/report.c index cd9b68d..7494f0a 100644 --- a/src/report.c +++ b/src/report.c @@ -21,7 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#define _GNU_SOURCE #include +#include #include "criterion/criterion.h" #include "criterion/stats.h" #include "criterion/logging.h" @@ -95,6 +97,21 @@ ReportHook(PRE_TEST)() {} ReportHook(POST_FINI)() {} ReportHook(PRE_ALL)(struct criterion_test_set *set) { + if (criterion_options.pattern) { + FOREACH_SET(struct criterion_suite_set *s, set->suites) { + if ((s->suite.data && s->suite.data->disabled) || !s->tests) + continue; + + FOREACH_SET(struct criterion_test *test, s->tests) { + char *name = NULL; + asprintf(&name, "%s/%s", s->suite.name, test->name); + if (fnmatch(criterion_options.pattern, name, 0)) + test->data->disabled = true; + + free(name); + } + } + } if (criterion_options.enable_tap_format) { size_t enabled_count = 0; FOREACH_SET(struct criterion_suite_set *s, set->suites) {