1#ifndef BANDIT_PROGRESS_REPORTER_H
2#define BANDIT_PROGRESS_REPORTER_H
3
4#include <algorithm>
5#include <list>
6#include <sstream>
7#include <bandit/failure_formatters/failure_formatter.h>
8#include <bandit/listener.h>
9
10namespace bandit {
11 namespace detail {
12 struct progress_reporter : public listener {
13 progress_reporter(const detail::failure_formatter& failure_formatter)
14 : specs_run_(0), specs_succeeded_(0), specs_failed_(0), specs_skipped_(0),
15 failure_formatter_(failure_formatter) {}
16
17 progress_reporter& operator=(const progress_reporter&) {
18 return *this;
19 }
20
21 void test_run_starting() override {
22 specs_run_ = 0;
23 specs_succeeded_ = 0;
24 specs_failed_ = 0;
25 specs_skipped_ = 0;
26 failures_.clear();
27 contexts_.clear();
28 }
29
30 void test_run_complete() override {}
31
32 void context_starting(const std::string& desc) override {
33 contexts_.push_back(std::string(desc));
34 }
35
36 void context_ended(const std::string&) override {
37 contexts_.pop_back();
38 }
39
40 void test_run_error(const std::string&, const struct test_run_error&) override {}
41
42 void it_starting(const std::string&) override {
43 specs_run_++;
44 }
45
46 void it_succeeded(const std::string&) override {
47 specs_succeeded_++;
48 }
49
50 void it_failed(const std::string& desc, const assertion_exception& ex) override {
51 specs_failed_++;
52
53 std::stringstream ss;
54 ss << std::endl;
55 ss << current_context_name() << " " << desc << ":" << std::endl;
56 ss << failure_formatter_.format(ex);
57
58 failures_.push_back(ss.str());
59 }
60
61 void it_unknown_error(const std::string& desc) override {
62 specs_failed_++;
63
64 std::stringstream ss;
65 ss << std::endl;
66 ss << current_context_name() << " " << desc << ":" << std::endl;
67 ss << "Unknown exception";
68 ss << std::endl;
69
70 failures_.push_back(ss.str());
71 }
72
73 void it_skip(const std::string&) override {
74 specs_skipped_++;
75 }
76
77 bool did_we_pass() const override final {
78 return specs_failed_ == 0 && test_run_errors_.size() == 0;
79 }
80
81 protected:
82 std::string current_context_name() {
83 std::string name;
84
85 for (const auto& context : contexts_) {
86 if (name.size() > 0) {
87 name += " ";
88 }
89
90 name += context;
91 }
92
93 return name;
94 }
95
96 protected:
97 int specs_run_;
98 int specs_succeeded_;
99 int specs_failed_;
100 int specs_skipped_;
101 const detail::failure_formatter& failure_formatter_;
102 std::list<std::string> contexts_;
103 std::list<std::string> failures_;
104 std::list<std::string> test_run_errors_;
105 };
106 }
107}
108#endif
109