xrpld
Loading...
Searching...
No Matches
runner.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/suite_info.h>
8
9#include <boost/assert.hpp>
10
11#include <mutex>
12#include <string>
13
14namespace beast::unit_test {
15
21class Runner
22{
24 bool default_ = false;
25 bool failed_ = false;
26 bool cond_ = false;
28
29public:
30 Runner() = default;
31 virtual ~Runner() = default;
32 Runner(Runner const&) = delete;
33 Runner&
34 operator=(Runner const&) = delete;
35
43 void
44 arg(std::string const& s)
45 {
46 arg_ = s;
47 }
48
50 [[nodiscard]] std::string const&
51 arg() const
52 {
53 return arg_;
54 }
55
59 template <class = void>
60 bool
61 run(SuiteInfo const& s);
62
69 template <class FwdIter>
70 bool
71 run(FwdIter first, FwdIter last);
72
80 template <class FwdIter, class Pred>
81 bool
82 runIf(FwdIter first, FwdIter last, Pred pred = Pred{});
83
87 template <class SequenceContainer>
88 bool
89 runEach(SequenceContainer const& c);
90
98 template <class SequenceContainer, class Pred>
99 bool
100 runEachIf(SequenceContainer const& c, Pred pred = Pred{});
101
102protected:
104 virtual void
106 {
107 }
108
110 virtual void
112 {
113 }
114
116 virtual void
118 {
119 }
120
122 virtual void
124 {
125 }
126
128 virtual void
130 {
131 }
132
134 virtual void
136 {
137 }
138
140 virtual void
142 {
143 }
144
145private:
146 friend class Suite;
147
148 // Start a new testcase.
149 template <class = void>
150 void
151 testcase(std::string const& name);
152
153 template <class = void>
154 void
155 pass();
156
157 template <class = void>
158 void
159 fail(std::string const& reason);
160
161 template <class = void>
162 void
163 log(std::string const& s);
164};
165
166//------------------------------------------------------------------------------
167
168template <class>
169bool
171{
172 // Enable 'default' testcase
173 default_ = true;
174 failed_ = false;
175 onSuiteBegin(s);
176 s.run(*this);
177 // Forgot to call pass or fail.
178 BOOST_ASSERT(cond_);
179 onCaseEnd();
180 onSuiteEnd();
181 return failed_;
182}
183
184template <class FwdIter>
185bool
186Runner::run(FwdIter first, FwdIter last)
187{
188 bool failed(false);
189 for (; first != last; ++first)
190 failed = run(*first) || failed;
191 return failed;
192}
193
194template <class FwdIter, class Pred>
195bool
196Runner::runIf(FwdIter first, FwdIter last, Pred pred)
197{
198 bool failed(false);
199 for (; first != last; ++first)
200 {
201 if (pred(*first))
202 failed = run(*first) || failed;
203 }
204 return failed;
205}
206
207template <class SequenceContainer>
208bool
209Runner::runEach(SequenceContainer const& c)
210{
211 bool failed(false);
212 for (auto const& s : c)
213 failed = run(s) || failed;
214 return failed;
215}
216
217template <class SequenceContainer, class Pred>
218bool
219Runner::runEachIf(SequenceContainer const& c, Pred pred)
220{
221 bool failed(false);
222 for (auto const& s : c)
223 {
224 if (pred(s))
225 failed = run(s) || failed;
226 }
227 return failed;
228}
229
230template <class>
231void
233{
234 std::scoped_lock const lock(mutex_);
235 // Name may not be empty
236 BOOST_ASSERT(default_ || !name.empty());
237 // Forgot to call pass or fail
238 BOOST_ASSERT(default_ || cond_);
239 if (!default_)
240 onCaseEnd();
241 default_ = false;
242 cond_ = false;
243 onCaseBegin(name);
244}
245
246template <class>
247void
249{
250 std::scoped_lock const lock(mutex_);
251 if (default_)
252 testcase("");
253 onPass();
254 cond_ = true;
255}
256
257template <class>
258void
260{
261 std::scoped_lock const lock(mutex_);
262 if (default_)
263 testcase("");
264 onFail(reason);
265 failed_ = true;
266 cond_ = true;
267}
268
269template <class>
270void
272{
273 std::scoped_lock const lock(mutex_);
274 if (default_)
275 testcase("");
276 onLog(s);
277}
278
279} // namespace beast::unit_test
bool runEachIf(SequenceContainer const &c, Pred pred=Pred{})
Conditionally run suites in a container.
Definition runner.h:219
void fail(std::string const &reason)
Definition runner.h:259
virtual ~Runner()=default
void testcase(std::string const &name)
Definition runner.h:232
virtual void onCaseBegin(std::string const &)
Called when a new case starts.
Definition runner.h:117
friend class Suite
Definition runner.h:146
virtual void onSuiteEnd()
Called when a suite ends.
Definition runner.h:111
std::recursive_mutex mutex_
Definition runner.h:27
Runner(Runner const &)=delete
virtual void onLog(std::string const &)
Called when a test logs output.
Definition runner.h:141
bool runEach(SequenceContainer const &c)
Run all suites in a container.
Definition runner.h:209
bool run(SuiteInfo const &s)
Run the specified suite.
Definition runner.h:170
bool runIf(FwdIter first, FwdIter last, Pred pred=Pred{})
Conditionally run a sequence of suites.
Definition runner.h:196
void log(std::string const &s)
Definition runner.h:271
virtual void onCaseEnd()
Called when a new case ends.
Definition runner.h:123
virtual void onSuiteBegin(SuiteInfo const &)
Called when a new suite starts.
Definition runner.h:105
std::string const & arg() const
Returns the argument string.
Definition runner.h:51
void arg(std::string const &s)
Set the argument string.
Definition runner.h:44
virtual void onFail(std::string const &)
Called for each failing condition.
Definition runner.h:135
Runner & operator=(Runner const &)=delete
virtual void onPass()
Called for each passing condition.
Definition runner.h:129
Associates a unit test type with metadata.
Definition suite_info.h:18
void run(Runner &r) const
Run a new instance of the associated test suite.
Definition suite_info.h:79
T empty(T... args)