Echo Writes Code

suite.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "crucible/testing/suite.inl"

#include <memory>

namespace crucible::testing::suite {
  struct Suite::ConstructorPermission {};

  auto Suite::get_reference() -> Suite & {
    static auto instance { std::make_unique<Suite>(ConstructorPermission()) };
    return *instance;
  }

  Suite::Suite(ConstructorPermission const &) {
  }

  auto Suite::set_name(std::string const &name) -> void {
    my_name = name;
  }

  auto Suite::set_group_filter(std::set<std::string> const &group_filter) -> void {
    my_group_filter = group_filter;
  }

  auto Suite::add_scenario(std::string const &group, std::string const &name, scenario::ScenarioFunction const &function) -> void {
    auto emplace_result { my_scenarios_by_group.emplace(group, std::vector<scenario::Scenario> {}) };
    auto &iterator { emplace_result.first };
    auto &scenario_list { iterator->second };
    scenario_list.emplace_back(group, name, function);
  }

  auto Suite::execute(reporter::Reporter &reporter) -> bool {
    if (my_scenarios_by_group.empty()) {
      reporter.handle_empty_suite(my_name);
      return true;
    }

    reporter.handle_suite_start(my_name);
    execute_scenarios(reporter);
    reporter.handle_suite_end(my_pass_count, my_fail_count, my_scenario_count, my_fixture_count);

    return my_fail_count == 0;
  }

  auto Suite::execute_scenarios(reporter::Reporter &reporter) -> void {
    for (auto &pair : my_scenarios_by_group) {
      auto const &group = pair.first;

      bool const do_filtering { !my_group_filter.empty() };
      bool const is_filtered_out { my_group_filter.find(group) == my_group_filter.end() };

      if (do_filtering && is_filtered_out) {
        continue;
      }

      execute_fixtures_with_group<fixture::BeforeAll>(group, reporter);
      reporter.handle_group_start(group);

      auto &scenario_list { pair.second };

      for (auto &scenario : scenario_list) {
        execute_fixtures_with_group<fixture::BeforeEach>(group, reporter);
        reporter.handle_scenario_start(scenario);

        auto const outcome { scenario.execute() };

        reporter.handle_scenario_end(scenario, outcome);
        execute_fixtures_with_group<fixture::AfterEach>(group, reporter);

        if (outcome.passed()) {
          ++my_pass_count;
        } else {
          ++my_fail_count;
        }

        ++my_scenario_count;
      }

      reporter.handle_group_end(group);
      execute_fixtures_with_group<fixture::AfterAll>(group, reporter);
    }
  }

  ScenarioRegistrar::ScenarioRegistrar(std::string const &group, std::string const &name, scenario::ScenarioFunction const &test) {
    auto &suite { suite::Suite::get_reference() };
    suite.add_scenario(group, name, test);
  }
}