Dune Core Modules (unstable)

testsuite.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_COMMON_TEST_TESTSUITE_HH
6#define DUNE_COMMON_TEST_TESTSUITE_HH
7
8#include <iostream>
9#include <sstream>
10#include <string>
11
13#include <dune/common/test/collectorstream.hh>
14
15
16
17namespace Dune {
18
19
20
31 {
32 public:
33 enum ThrowPolicy
34 {
35 AlwaysThrow,
36 ThrowOnRequired
37 };
38
45 TestSuite(ThrowPolicy policy, std::string name="") :
46 name_(name),
47 checks_(0),
48 failedChecks_(0),
49 throwPolicy_(policy==AlwaysThrow)
50 {}
51
58 TestSuite(std::string name="", ThrowPolicy policy=ThrowOnRequired) :
59 name_(name),
60 checks_(0),
61 failedChecks_(0),
62 throwPolicy_(policy==AlwaysThrow)
63 {}
64
74 CollectorStream check(bool condition, std::string name="")
75 {
76 ++checks_;
77 if (not condition)
78 ++failedChecks_;
79
80 return CollectorStream([condition, name, this](std::string reason) {
81 if (not condition)
82 this->announceCheckResult(throwPolicy_, "CHECK ", name, reason);
83 });
84 }
85
95 CollectorStream require(bool condition, std::string name="")
96 {
97 ++checks_;
98 if (not condition)
99 ++failedChecks_;
100
101 return CollectorStream([condition, name, this](std::string reason) {
102 if (not condition)
103 this->announceCheckResult(true, "REQUIRED CHECK", name, reason);
104 });
105 }
106
107
108 private:
109 struct AnyException{};
110 struct NoException{};
111
112 template <class Exception= AnyException,class Expression>
113 bool evaluateThrowCondition(Expression&& expr)
114 {
115 try { expr(); }
116 catch (const Exception& e)
117 {
118 return true;
119 }
120 catch (...) //If we end up here, but we wanted to catch a specific Exception, we consider this failed, but if Exception is AnyExpection, we pass.
121 {
122 return std::is_same_v<Exception,AnyException>;
123 }
124 // If we end up here we didn't catch any exception. Thus, if this is on purpose, i.e. 'Exception= NoException', we return true.
125 return std::is_same_v<Exception,NoException>;
126 }
127
128 public:
129
143 template <class Exception= AnyException,class Expression>
144 CollectorStream checkThrow(Expression&& expr, std::string name = "")
145 {
146 return check(evaluateThrowCondition<Exception>(expr),name);
147 }
148
162 template <class Expression>
163 CollectorStream checkNoThrow(Expression&& expr, std::string name = "")
164 {
165 return check(evaluateThrowCondition<NoException>(expr),name);
166 }
167
182 template <class Exception= AnyException,class Expression>
183 CollectorStream requireThrow(Expression&& expr, std::string name = "")
184 {
185 return require(evaluateThrowCondition<Exception>(expr),name);
186 }
187
201 template <class Expression>
202 CollectorStream requireNoThrow(Expression&& expr, std::string name = "")
203 {
204 return require(evaluateThrowCondition<NoException>(expr),name);
205 }
206
215 {
216 checks_ += subTest.checks_;
217 failedChecks_ += subTest.failedChecks_;
218
219 if (not subTest)
220 announceCheckResult(throwPolicy_, "SUBTEST", subTest.name(), std::to_string(subTest.failedChecks_)+"/"+std::to_string(subTest.checks_) + " checks failed in this subtest.");
221 }
222
228 explicit operator bool () const
229 {
230 return (failedChecks_==0);
231 }
232
238 std::string name() const
239 {
240 return name_;
241 }
242
248 bool report() const
249 {
250 if (failedChecks_>0)
251 std::cout << composeMessage("TEST ", name(), std::to_string(failedChecks_)+"/"+std::to_string(checks_) + " checks failed in this test.") << std::endl;
252 return (failedChecks_==0);
253 }
254
263 int exit() const
264 {
265 return (report() ? 0: 1);
266 }
267
268 protected:
269
270 // Compose a diagnostic message
271 static std::string composeMessage(std::string type, std::string name, std::string reason)
272 {
273 std::ostringstream s;
274 s << type << " FAILED";
275 if (name!="")
276 s << "(" << name << ")";
277 s << ": ";
278 if (reason!="")
279 s << reason;
280 return s.str();
281 }
282
283 // Announce check results. To be called on failed checks
284 static void announceCheckResult(bool throwException, std::string type, std::string name, std::string reason)
285 {
286 std::string message = composeMessage(type, name, reason);
287 std::cout << message << std::endl;
288 if (throwException)
289 {
291 ex.message(message);
292 throw ex;
293 }
294 }
295
296 std::string name_;
297 std::size_t checks_;
298 std::size_t failedChecks_;
299 bool throwPolicy_;
300 };
301
302
303
304} // namespace Dune
305
306
307
308#endif // DUNE_COMMON_TEST_TESTSUITE_HH
Data collector stream.
Definition: collectorstream.hh:32
Base class for Dune-Exceptions.
Definition: exceptions.hh:96
A Simple helper class to organize your test suite.
Definition: testsuite.hh:31
std::string name() const
Query name.
Definition: testsuite.hh:238
CollectorStream checkNoThrow(Expression &&expr, std::string name="")
Checks that the expression doesn't throw.
Definition: testsuite.hh:163
CollectorStream requireNoThrow(Expression &&expr, std::string name="")
Requires that the expression doesn't throw.
Definition: testsuite.hh:202
TestSuite(std::string name="", ThrowPolicy policy=ThrowOnRequired)
Create TestSuite.
Definition: testsuite.hh:58
void subTest(const TestSuite &subTest)
Collect data from a sub-TestSuite.
Definition: testsuite.hh:214
TestSuite(ThrowPolicy policy, std::string name="")
Create TestSuite.
Definition: testsuite.hh:45
int exit() const
Exit the test.
Definition: testsuite.hh:263
CollectorStream require(bool condition, std::string name="")
Check a required condition.
Definition: testsuite.hh:95
CollectorStream check(bool condition, std::string name="")
Check condition.
Definition: testsuite.hh:74
CollectorStream checkThrow(Expression &&expr, std::string name="")
Checks that the expression throws.
Definition: testsuite.hh:144
CollectorStream requireThrow(Expression &&expr, std::string name="")
Requires that the expression throws.
Definition: testsuite.hh:183
bool report() const
Print a summary of this TestSuite.
Definition: testsuite.hh:248
A few common exception classes.
void message(const std::string &msg)
store string in internal message buffer
Definition: exceptions.cc:32
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)