diff --git a/contrib/kyua/cli/cmd_test.cpp b/contrib/kyua/cli/cmd_test.cpp --- a/contrib/kyua/cli/cmd_test.cpp +++ b/contrib/kyua/cli/cmd_test.cpp @@ -64,6 +64,12 @@ bool _parallel; public: + /// The amount of all test results. + unsigned long total_count; + + /// The amount of test results per type. + unsigned long type_count[model::test_result_type_count]; + /// The amount of positive test results found so far. unsigned long good_count; @@ -77,9 +83,12 @@ print_hooks(cmdline::ui* ui_, const bool parallel_) : _ui(ui_), _parallel(parallel_), + total_count(0), good_count(0), bad_count(0) { + for (size_t i = 0; i < model::test_result_type_count; i++) + type_count[i] = 0; } /// Called when the processing of a test case begins. @@ -116,9 +125,14 @@ } _ui->out(F("%s [%s]") % cli::format_result(result) % cli::format_delta(duration)); - if (result.good()) + + total_count++; + + const auto type = model::test_result_types[result.type()]; + type_count[type.id]++; + if (type.is_run && type.is_good) good_count++; - else + if (!type.is_good) bad_count++; } }; @@ -160,7 +174,7 @@ parse_filters(cmdline.arguments()), user_config, hooks); int exit_code; - if (hooks.good_count > 0 || hooks.bad_count > 0) { + if (hooks.total_count > 0) { ui->out(""); if (!results.first.empty()) { ui->out(F("Results file id is %s") % results.first); @@ -168,8 +182,17 @@ ui->out(F("Results saved to %s") % results.second); ui->out(""); - ui->out(F("%s/%s passed (%s failed)") % hooks.good_count % - (hooks.good_count + hooks.bad_count) % hooks.bad_count); + ui->out(F("%s/%s passed (") % hooks.good_count % hooks.total_count, + false); + for (size_t i = 0; i < model::test_result_type_count; i++) { + const auto type = model::test_result_types[i]; + if (!type.is_run || !type.is_good) { + if (i > 0) + ui->out(", ", false); + ui->out(F("%s %s") % hooks.type_count[i] % type.name, false); + } + } + ui->out(")"); exit_code = (hooks.bad_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } else { diff --git a/contrib/kyua/model/test_result.hpp b/contrib/kyua/model/test_result.hpp --- a/contrib/kyua/model/test_result.hpp +++ b/contrib/kyua/model/test_result.hpp @@ -40,6 +40,23 @@ namespace model { +/// Total number of test result types. +const size_t test_result_type_count = 5; + + +/// Test result type metadata. +struct test_result_type_desc { + enum test_result_type id; + std::string name; + bool is_run; + bool is_good; +}; + + +/// Description of each test result type. +extern const struct test_result_type_desc test_result_types[]; + + /// Representation of a single test result. /// /// A test result is a simple pair of (type, reason). The type indicates the diff --git a/contrib/kyua/model/test_result.cpp b/contrib/kyua/model/test_result.cpp --- a/contrib/kyua/model/test_result.cpp +++ b/contrib/kyua/model/test_result.cpp @@ -35,6 +35,15 @@ namespace text = utils::text; +const struct model::test_result_type_desc model::test_result_types[] = { + { test_result_broken, "broken", true, false, }, + { test_result_expected_failure, "xfail", true, true, }, + { test_result_failed, "failed", true, false, }, + { test_result_passed, "passed", true, true, }, + { test_result_skipped, "skipped", false, true, }, +}; + + /// Constructs a base result. /// /// \param type_ The type of the result. @@ -74,17 +83,7 @@ bool model::test_result::good(void) const { - switch (_type) { - case test_result_expected_failure: - case test_result_passed: - case test_result_skipped: - return true; - - case test_result_broken: - case test_result_failed: - return false; - } - UNREACHABLE; + return test_result_types[_type].is_good; }