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
22class Runner
23{
25 bool default_ = false;
26 bool failed_ = false;
27 bool cond_ = false;
29
30public:
31 Runner() = default;
32 virtual ~Runner() = default;
33 Runner(Runner const&) = delete;
34 Runner&
35 operator=(Runner const&) = delete;
36
45 void
46 arg(std::string const& s)
47 {
48 arg_ = s;
49 }
50
54 [[nodiscard]] std::string const&
55 arg() const
56 {
57 return arg_;
58 }
59
64 template <class = void>
65 bool
66 run(SuiteInfo const& s);
67
75 template <class FwdIter>
76 bool
77 run(FwdIter first, FwdIter last);
78
87 template <class FwdIter, class Pred>
88 bool
89 runIf(FwdIter first, FwdIter last, Pred pred = Pred{});
90
95 template <class SequenceContainer>
96 bool
97 runEach(SequenceContainer const& c);
98
107 template <class SequenceContainer, class Pred>
108 bool
109 runEachIf(SequenceContainer const& c, Pred pred = Pred{});
110
111protected:
115 virtual void
117 {
118 }
119
123 virtual void
125 {
126 }
127
131 virtual void
133 {
134 }
135
139 virtual void
141 {
142 }
143
147 virtual void
149 {
150 }
151
155 virtual void
157 {
158 }
159
163 virtual void
165 {
166 }
167
168private:
169 friend class Suite;
170
171 // Start a new testcase.
172 template <class = void>
173 void
174 testcase(std::string const& name);
175
176 template <class = void>
177 void
178 pass();
179
180 template <class = void>
181 void
182 fail(std::string const& reason);
183
184 template <class = void>
185 void
186 log(std::string const& s);
187};
188
189//------------------------------------------------------------------------------
190
191template <class>
192bool
194{
195 // Enable 'default' testcase
196 default_ = true;
197 failed_ = false;
198 onSuiteBegin(s);
199 s.run(*this);
200 // Forgot to call pass or fail.
201 BOOST_ASSERT(cond_);
202 onCaseEnd();
203 onSuiteEnd();
204 return failed_;
205}
206
207template <class FwdIter>
208bool
209Runner::run(FwdIter first, FwdIter last)
210{
211 bool failed(false);
212 for (; first != last; ++first)
213 failed = run(*first) || failed;
214 return failed;
215}
216
217template <class FwdIter, class Pred>
218bool
219Runner::runIf(FwdIter first, FwdIter last, Pred pred)
220{
221 bool failed(false);
222 for (; first != last; ++first)
223 {
224 if (pred(*first))
225 failed = run(*first) || failed;
226 }
227 return failed;
228}
229
230template <class SequenceContainer>
231bool
232Runner::runEach(SequenceContainer const& c)
233{
234 bool failed(false);
235 for (auto const& s : c)
236 failed = run(s) || failed;
237 return failed;
238}
239
240template <class SequenceContainer, class Pred>
241bool
242Runner::runEachIf(SequenceContainer const& c, Pred pred)
243{
244 bool failed(false);
245 for (auto const& s : c)
246 {
247 if (pred(s))
248 failed = run(s) || failed;
249 }
250 return failed;
251}
252
253template <class>
254void
256{
257 std::scoped_lock const lock(mutex_);
258 // Name may not be empty
259 BOOST_ASSERT(default_ || !name.empty());
260 // Forgot to call pass or fail
261 BOOST_ASSERT(default_ || cond_);
262 if (!default_)
263 onCaseEnd();
264 default_ = false;
265 cond_ = false;
266 onCaseBegin(name);
267}
268
269template <class>
270void
272{
273 std::scoped_lock const lock(mutex_);
274 if (default_)
275 testcase("");
276 onPass();
277 cond_ = true;
278}
279
280template <class>
281void
283{
284 std::scoped_lock const lock(mutex_);
285 if (default_)
286 testcase("");
287 onFail(reason);
288 failed_ = true;
289 cond_ = true;
290}
291
292template <class>
293void
295{
296 std::scoped_lock const lock(mutex_);
297 if (default_)
298 testcase("");
299 onLog(s);
300}
301
302} // namespace beast::unit_test
bool runEachIf(SequenceContainer const &c, Pred pred=Pred{})
Conditionally run suites in a container.
Definition runner.h:242
void fail(std::string const &reason)
Definition runner.h:282
virtual ~Runner()=default
void testcase(std::string const &name)
Definition runner.h:255
virtual void onCaseBegin(std::string const &)
Called when a new case starts.
Definition runner.h:132
friend class Suite
Definition runner.h:169
virtual void onSuiteEnd()
Called when a suite ends.
Definition runner.h:124
std::recursive_mutex mutex_
Definition runner.h:28
Runner(Runner const &)=delete
virtual void onLog(std::string const &)
Called when a test logs output.
Definition runner.h:164
bool runEach(SequenceContainer const &c)
Run all suites in a container.
Definition runner.h:232
bool run(SuiteInfo const &s)
Run the specified suite.
Definition runner.h:193
bool runIf(FwdIter first, FwdIter last, Pred pred=Pred{})
Conditionally run a sequence of suites.
Definition runner.h:219
void log(std::string const &s)
Definition runner.h:294
virtual void onCaseEnd()
Called when a new case ends.
Definition runner.h:140
virtual void onSuiteBegin(SuiteInfo const &)
Called when a new suite starts.
Definition runner.h:116
std::string const & arg() const
Returns the argument string.
Definition runner.h:55
void arg(std::string const &s)
Set the argument string.
Definition runner.h:46
virtual void onFail(std::string const &)
Called for each failing condition.
Definition runner.h:156
Runner & operator=(Runner const &)=delete
virtual void onPass()
Called for each passing condition.
Definition runner.h:148
Associates a unit test type with metadata.
Definition suite_info.h:20
void run(Runner &r) const
Run a new instance of the associated test suite.
Definition suite_info.h:87
T empty(T... args)