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(), top.end(), elapsed, [](run_time const& t1, typename clock_type::duration const& t2) {
143 return t1.second > t2;
144 });
145 if (iter != top.end())
146 {
147 if (top.size() == max_top)
148 top.resize(top.size() - 1);
149 top.emplace(iter, r.name, elapsed);
150 }
151 else if (top.size() < max_top)
152 {
153 top.emplace_back(r.name, elapsed);
154 }
155 }
156}
157
158//------------------------------------------------------------------------------
159
160template <class _>
164
165template <class _>
167{
168 if (results_.top.size() > 0)
169 {
170 os_ << "Longest suite times:\n";
171 for (auto const& i : results_.top)
172 os_ << std::setw(8) << fmtdur(i.second) << " " << i.first << '\n';
173 }
174 auto const elapsed = clock_type::now() - results_.start;
175 os_ << fmtdur(elapsed) << ", " << amount{results_.suites, "suite"} << ", " << amount{results_.cases, "case"} << ", "
176 << amount{results_.total, "test"} << " total, " << amount{results_.failed, "failure"} << std::endl;
177}
178
179template <class _>
181reporter<_>::fmtdur(typename clock_type::duration const& d)
182{
183 using namespace std::chrono;
184 auto const ms = duration_cast<milliseconds>(d);
185 if (ms < seconds{1})
186 return boost::lexical_cast<std::string>(ms.count()) + "ms";
188 ss << std::fixed << std::setprecision(1) << (ms.count() / 1000.) << "s";
189 return ss.str();
190}
191
192template <class _>
193void
195{
196 suite_results_ = suite_results{info.full_name()};
197}
198
199template <class _>
200void
202{
203 results_.add(suite_results_);
204}
205
206template <class _>
207void
209{
210 case_results_ = case_results(name);
211 os_ << suite_results_.name << (case_results_.name.empty() ? "" : (" " + case_results_.name)) << std::endl;
212}
213
214template <class _>
215void
217{
218 suite_results_.add(case_results_);
219}
220
221template <class _>
222void
224{
225 ++case_results_.total;
226}
227
228template <class _>
229void
231{
232 ++case_results_.failed;
233 ++case_results_.total;
234 os_ << "#" << case_results_.total << " failed" << (reason.empty() ? "" : ": ") << reason << std::endl;
235}
236
237template <class _>
238void
240{
241 os_ << s;
242}
243
244} // namespace detail
245
247
248} // namespace unit_test
249} // 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:239
reporter(reporter const &)=delete
virtual void on_case_end() override
Called when a new case ends.
Definition reporter.h:216
reporter & operator=(reporter const &)=delete
virtual void on_suite_begin(suite_info const &info) override
Called when a new suite starts.
Definition reporter.h:194
virtual void on_case_begin(std::string const &name) override
Called when a new case starts.
Definition reporter.h:208
virtual void on_fail(std::string const &reason) override
Called for each failing condition.
Definition reporter.h:230
static std::string fmtdur(typename clock_type::duration const &d)
Definition reporter.h:181
virtual void on_suite_end() override
Called when a suite ends.
Definition reporter.h:201
virtual void on_pass() override
Called for each passing condition.
Definition reporter.h:223
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:67
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