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#pragma once
6
7#include <xrpl/beast/unit_test/amount.h>
8#include <xrpl/beast/unit_test/recorder.h>
9
10#include <boost/lexical_cast.hpp>
11#include <boost/optional.hpp>
12
13#include <algorithm>
14#include <chrono>
15#include <iomanip>
16#include <iostream>
17#include <sstream>
18#include <string>
19#include <utility>
20
21namespace beast {
22namespace unit_test {
23
24namespace detail {
25
29template <class = void>
30class reporter : public runner
31{
32private:
34
36 {
40
41 explicit case_results(std::string name_ = "") : name(std::move(name_))
42 {
43 }
44 };
45
47 {
52 typename clock_type::time_point start = clock_type::now();
53
54 explicit suite_results(std::string name_ = "") : name(std::move(name_))
55 {
56 }
57
58 void
59 add(case_results const& r);
60 };
61
78
83
84public:
85 reporter(reporter const&) = delete;
87 operator=(reporter const&) = delete;
88
89 ~reporter();
90
91 explicit reporter(std::ostream& os = std::cout);
92
93private:
94 static std::string
95 fmtdur(typename clock_type::duration const& d);
96
97 virtual void
98 on_suite_begin(suite_info const& info) override;
99
100 virtual void
101 on_suite_end() override;
102
103 virtual void
104 on_case_begin(std::string const& name) override;
105
106 virtual void
107 on_case_end() override;
108
109 virtual void
110 on_pass() override;
111
112 virtual void
113 on_fail(std::string const& reason) override;
114
115 virtual void
116 on_log(std::string const& s) override;
117};
118
119//------------------------------------------------------------------------------
120
121template <class _>
122void
124{
125 ++cases;
126 total += r.total;
127 failed += r.failed;
128}
129
130template <class _>
131void
133{
134 ++suites;
135 total += r.total;
136 cases += r.cases;
137 failed += r.failed;
138 auto const elapsed = clock_type::now() - r.start;
139 if (elapsed >= std::chrono::seconds{1})
140 {
141 auto const iter = std::lower_bound(
142 top.begin(),
143 top.end(),
144 elapsed,
145 [](run_time const& t1, typename clock_type::duration const& t2) {
146 return t1.second > t2;
147 });
148 if (iter != top.end())
149 {
150 if (top.size() == max_top)
151 top.resize(top.size() - 1);
152 top.emplace(iter, r.name, elapsed);
153 }
154 else if (top.size() < max_top)
155 {
156 top.emplace_back(r.name, elapsed);
157 }
158 }
159}
160
161//------------------------------------------------------------------------------
162
163template <class _>
167
168template <class _>
170{
171 if (results_.top.size() > 0)
172 {
173 os_ << "Longest suite times:\n";
174 for (auto const& i : results_.top)
175 os_ << std::setw(8) << fmtdur(i.second) << " " << i.first << '\n';
176 }
177 auto const elapsed = clock_type::now() - results_.start;
178 os_ << fmtdur(elapsed) << ", " << amount{results_.suites, "suite"} << ", "
179 << amount{results_.cases, "case"} << ", " << amount{results_.total, "test"} << " total, "
180 << amount{results_.failed, "failure"} << std::endl;
181}
182
183template <class _>
185reporter<_>::fmtdur(typename clock_type::duration const& d)
186{
187 using namespace std::chrono;
188 auto const ms = duration_cast<milliseconds>(d);
189 if (ms < seconds{1})
190 return boost::lexical_cast<std::string>(ms.count()) + "ms";
192 ss << std::fixed << std::setprecision(1) << (ms.count() / 1000.) << "s";
193 return ss.str();
194}
195
196template <class _>
197void
199{
200 suite_results_ = suite_results{info.full_name()};
201}
202
203template <class _>
204void
206{
207 results_.add(suite_results_);
208}
209
210template <class _>
211void
213{
214 case_results_ = case_results(name);
215 os_ << suite_results_.name << (case_results_.name.empty() ? "" : (" " + case_results_.name))
216 << std::endl;
217}
218
219template <class _>
220void
222{
223 suite_results_.add(case_results_);
224}
225
226template <class _>
227void
229{
230 ++case_results_.total;
231}
232
233template <class _>
234void
236{
237 ++case_results_.failed;
238 ++case_results_.total;
239 os_ << "#" << case_results_.total << " failed" << (reason.empty() ? "" : ": ") << reason
240 << std::endl;
241}
242
243template <class _>
244void
246{
247 os_ << s;
248}
249
250} // namespace detail
251
253
254} // namespace unit_test
255} // namespace beast
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:31
virtual void on_log(std::string const &s) override
Called when a test logs output.
Definition reporter.h:245
reporter(reporter const &)=delete
virtual void on_case_end() override
Called when a new case ends.
Definition reporter.h:221
reporter & operator=(reporter const &)=delete
virtual void on_suite_begin(suite_info const &info) override
Called when a new suite starts.
Definition reporter.h:198
virtual void on_case_begin(std::string const &name) override
Called when a new case starts.
Definition reporter.h:212
virtual void on_fail(std::string const &reason) override
Called for each failing condition.
Definition reporter.h:235
static std::string fmtdur(typename clock_type::duration const &d)
Definition reporter.h:185
virtual void on_suite_end() override
Called when a suite ends.
Definition reporter.h:205
virtual void on_pass() override
Called for each passing condition.
Definition reporter.h:228
Unit test runner interface.
Definition runner.h:23
Associates a unit test type with metadata.
Definition suite_info.h:19
std::string full_name() const
Return the canonical suite name as a string.
Definition suite_info.h:73
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:132