rippled
Loading...
Searching...
No Matches
reporter.h
1// Distributed under the Boost Software License, Version 1.0. (See accompanying
2// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
3//
4
5#ifndef BEAST_UNIT_TEST_REPORTER_HPP
6#define BEAST_UNIT_TEST_REPORTER_HPP
7
8#include <xrpl/beast/unit_test/amount.h>
9#include <xrpl/beast/unit_test/recorder.h>
10
11#include <boost/lexical_cast.hpp>
12#include <boost/optional.hpp>
13
14#include <algorithm>
15#include <chrono>
16#include <iomanip>
17#include <iostream>
18#include <sstream>
19#include <string>
20#include <utility>
21
22namespace beast {
23namespace unit_test {
24
25namespace detail {
26
30template <class = void>
31class reporter : public runner
32{
33private:
35
37 {
41
42 explicit case_results(std::string name_ = "") : name(std::move(name_))
43 {
44 }
45 };
46
48 {
53 typename clock_type::time_point start = clock_type::now();
54
55 explicit suite_results(std::string name_ = "") : name(std::move(name_))
56 {
57 }
58
59 void
60 add(case_results const& r);
61 };
62
79
84
85public:
86 reporter(reporter const&) = delete;
88 operator=(reporter const&) = delete;
89
90 ~reporter();
91
92 explicit reporter(std::ostream& os = std::cout);
93
94private:
95 static std::string
96 fmtdur(typename clock_type::duration const& d);
97
98 virtual void
99 on_suite_begin(suite_info const& info) override;
100
101 virtual void
102 on_suite_end() override;
103
104 virtual void
105 on_case_begin(std::string const& name) override;
106
107 virtual void
108 on_case_end() override;
109
110 virtual void
111 on_pass() override;
112
113 virtual void
114 on_fail(std::string const& reason) override;
115
116 virtual void
117 on_log(std::string const& s) override;
118};
119
120//------------------------------------------------------------------------------
121
122template <class _>
123void
125{
126 ++cases;
127 total += r.total;
128 failed += r.failed;
129}
130
131template <class _>
132void
134{
135 ++suites;
136 total += r.total;
137 cases += r.cases;
138 failed += r.failed;
139 auto const elapsed = clock_type::now() - r.start;
140 if (elapsed >= std::chrono::seconds{1})
141 {
142 auto const iter = std::lower_bound(
143 top.begin(),
144 top.end(),
145 elapsed,
146 [](run_time const& t1, typename clock_type::duration const& t2) {
147 return t1.second > t2;
148 });
149 if (iter != top.end())
150 {
151 if (top.size() == max_top)
152 top.resize(top.size() - 1);
153 top.emplace(iter, r.name, elapsed);
154 }
155 else if (top.size() < max_top)
156 {
157 top.emplace_back(r.name, elapsed);
158 }
159 }
160}
161
162//------------------------------------------------------------------------------
163
164template <class _>
168
169template <class _>
171{
172 if (results_.top.size() > 0)
173 {
174 os_ << "Longest suite times:\n";
175 for (auto const& i : results_.top)
176 os_ << std::setw(8) << fmtdur(i.second) << " " << i.first << '\n';
177 }
178 auto const elapsed = clock_type::now() - results_.start;
179 os_ << fmtdur(elapsed) << ", " << amount{results_.suites, "suite"} << ", "
180 << amount{results_.cases, "case"} << ", "
181 << amount{results_.total, "test"} << " total, "
182 << amount{results_.failed, "failure"} << std::endl;
183}
184
185template <class _>
187reporter<_>::fmtdur(typename clock_type::duration const& d)
188{
189 using namespace std::chrono;
190 auto const ms = duration_cast<milliseconds>(d);
191 if (ms < seconds{1})
192 return boost::lexical_cast<std::string>(ms.count()) + "ms";
194 ss << std::fixed << std::setprecision(1) << (ms.count() / 1000.) << "s";
195 return ss.str();
196}
197
198template <class _>
199void
201{
202 suite_results_ = suite_results{info.full_name()};
203}
204
205template <class _>
206void
208{
209 results_.add(suite_results_);
210}
211
212template <class _>
213void
215{
216 case_results_ = case_results(name);
217 os_ << suite_results_.name
218 << (case_results_.name.empty() ? "" : (" " + case_results_.name))
219 << std::endl;
220}
221
222template <class _>
223void
225{
226 suite_results_.add(case_results_);
227}
228
229template <class _>
230void
232{
233 ++case_results_.total;
234}
235
236template <class _>
237void
239{
240 ++case_results_.failed;
241 ++case_results_.total;
242 os_ << "#" << case_results_.total << " failed"
243 << (reason.empty() ? "" : ": ") << reason << std::endl;
244}
245
246template <class _>
247void
249{
250 os_ << s;
251}
252
253} // namespace detail
254
256
257} // namespace unit_test
258} // namespace beast
259
260#endif
Utility for producing nicely composed output of amounts with units.
A simple test runner that writes everything to a stream in real time.
Definition reporter.h:32
virtual void on_log(std::string const &s) override
Called when a test logs output.
Definition reporter.h:248
reporter(reporter const &)=delete
virtual void on_case_end() override
Called when a new case ends.
Definition reporter.h:224
reporter & operator=(reporter const &)=delete
virtual void on_suite_begin(suite_info const &info) override
Called when a new suite starts.
Definition reporter.h:200
virtual void on_case_begin(std::string const &name) override
Called when a new case starts.
Definition reporter.h:214
virtual void on_fail(std::string const &reason) override
Called for each failing condition.
Definition reporter.h:238
static std::string fmtdur(typename clock_type::duration const &d)
Definition reporter.h:187
virtual void on_suite_end() override
Called when a suite ends.
Definition reporter.h:207
virtual void on_pass() override
Called for each passing condition.
Definition reporter.h:231
Unit test runner interface.
Definition runner.h:24
Associates a unit test type with metadata.
Definition suite_info.h:20
std::string full_name() const
Return the canonical suite name as a string.
Definition suite_info.h:74
T empty(T... args)
T endl(T... args)
T fixed(T... args)
T lower_bound(T... args)
STL namespace.
T setprecision(T... args)
T setw(T... args)
T str(T... args)
void add(suite_results const &r)
Definition reporter.h:133