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