38 Runnable* parent =
nullptr;
41 std::source_location location;
43 std::list<std::shared_ptr<Runnable>> children_;
45 std::chrono::time_point<std::chrono::system_clock> start_time_;
46 std::chrono::duration<double> runtime_{};
49 Runnable(std::source_location location) : location(location) {}
51 virtual ~Runnable() =
default;
57 [[nodiscard]]
bool has_parent() const noexcept {
return parent !=
nullptr; }
61 [[nodiscard]] Runnable*
get_parent() noexcept {
return parent; }
64 std::list<std::shared_ptr<Runnable>>& get_children() noexcept {
return children_; }
65 [[nodiscard]]
const std::list<std::shared_ptr<Runnable>>& get_children() const noexcept {
return children_; }
68 C* get_parent_as() noexcept {
69 return static_cast<C*
>(parent);
73 [[nodiscard]]
const C* get_parent_as() const noexcept {
74 return static_cast<const C*
>(parent);
77 template <
typename T,
typename... Args>
78 T* make_child(Args&&... args) {
79 auto child = std::make_shared<T>(std::forward<Args>(args)...);
80 auto* child_ptr = child.get();
82 children_.push_back(std::move(child));
89 [[nodiscard]] std::string
padding() const noexcept;
92 [[nodiscard]] std::source_location get_location() const noexcept {
return this->location; }
95 void set_location(std::source_location location)
noexcept { this->location = location; }
97 virtual void run() = 0;
99 virtual void timed_run() {
100 using namespace std::chrono;
101 start_time_ = system_clock::now();
102 time_point start_time = high_resolution_clock::now();
104 time_point end = high_resolution_clock::now();
105 runtime_ = end - start_time;
108 [[nodiscard]] std::chrono::duration<double> get_runtime()
const {
return runtime_; }
110 [[nodiscard]] std::chrono::time_point<std::chrono::system_clock> get_start_time()
const {
return start_time_; }
112 [[nodiscard]]
virtual Result get_result()
const {
113 Result result = Result::success(location);
114 for (
const auto& child : get_children()) {
115 result = Result::reduce(result, child->get_result());
120 [[nodiscard]]
size_t num_tests() const noexcept {
121 if (get_children().empty()) {
127 for (
const auto& child : get_children()) {
128 count += child->num_tests();
133 [[nodiscard]]
size_t num_failures() const noexcept {
134 if (get_children().empty()) {
135 return this->get_result().is_failure() ? 1 : 0;
140 for (
const auto& child : get_children()) {
141 count += child->num_failures();