PLCnext API Documentation 23.6.0.37
Assert.hpp
1
2//
3// Copyright PHOENIX CONTACT Electronics GmbH
4//
6#pragma once
8#include "Arp/System/Core/TypeName.hxx"
9#include "Arp/System/Core/format_cast.hxx"
10#include "Arp/System/Commons/Io/File.hpp"
11#include <boost/test/unit_test.hpp>
12#include <cmath>
13
14namespace Arp { namespace System { namespace Commons { namespace Testing
15{
16
18class Assert
19{
20private: // deleted construction/destruction
21 Assert(void) = delete;
22 ~Assert(void) = delete;
23
24public: // AreEqual operations
25 static void AreEqual(const void* expected, const void* actual);
26 static void AreEqual(const char* expected, const char* actual);
27 static void AreEqual(const char* expected, const String& actual);
28 static void AreEqual(const String& expected, const char* actual);
29 static void AreEqual(char expected, char actual);
30 static void AreEqual(unsigned char expected, unsigned char actual);
31 static void AreEqual(float expected, float actual, float epsilon);
32 static void AreEqual(double expected, double actual, double epsilon);
33 template<typename... Args>
34 static void AreEqual(float expected, float actual, float epsilon, const char* message, const Args& ... args);
35 template<typename... Args>
36 static void AreEqual(double expected, double actual, double epsilon, const char* message, const Args& ... args);
37 template<class T1, class T2>
38 static void AreEqual(const T1& expected, const T2& actual);
39 template<class T1, class T2, typename... Args>
40 static void AreEqual(const T1& expected, const T2& actual, const char* message, const Args& ... args);
41 template<class T1, class T2>
42 static void AreEqual(T1* expected, T2* actual);
43
44public: // AreNotEqual operations
45 static void AreNotEqual(float notExpected, float actual, float epsilon);
46 static void AreNotEqual(double notExpected, double actual, double epsilon);
47 template<typename... Args>
48 static void AreNotEqual(float notExpected, float actual, float epsilon, const char* message, const Args& ... args);
49 template<typename... Args>
50 static void AreNotEqual(double notExpected, double actual, double epsilon, const char* message, const Args& ... args);
51 template<class T1, class T2>
52 static void AreNotEqual(const T1& notExpected, const T2& actual);
53 template<class T1, class T2, typename... Args>
54 static void AreNotEqual(const T1& notExpected, const T2& actual, const char* message, const Args& ... args);
55
56public: // Fail operations
57 template<typename ... Args>
58 static void Error(const char* message, const Args& ... args);
59 template<typename ... Args>
60 static void Fail(const char* message, const Args& ... args);
61
62public: // IsTrue operations
63 template<class Predicate>
64 static void IsTrue(Predicate predicate);
65 template<class Predicate, typename... Args>
66 static void IsTrue(Predicate predicate, const char* message, const Args& ... args);
67
68public: // IsFalse operations
69 template<class Predicate>
70 static void IsFalse(Predicate predicate);
71 template<class Predicate, typename... Args>
72 static void IsFalse(Predicate predicate, const char* message, const Args& ... args);
73
74public: // IsNull operations
75 template<class T>
76 static void IsNull(T* pValue);
77 template<class T, typename... Args>
78 static void IsNull(T* pValue, const char* message, const Args& ... args);
79
80public: // IsNotNull operations
81 template<class T>
82 static void IsNotNull(T* pValue);
83 template<class T, typename... Args>
84 static void IsNotNull(T* pValue, const char* message, const Args& ... args);
85
86public: // IsEmpty operations
87 static void IsEmpty(const String& s);
88 template<typename... Args>
89 static void IsEmpty(const String& s, const char* message, const Args& ... args);
90
91public: // IsNotEmpty operations
92 static void IsNotEmpty(const String& s);
93 template<typename... Args>
94 static void IsNotEmpty(const String& s, const char* message, const Args& ... args);
95
96public: // Exists operations
97 static void Exists(const String& path);
98 template<typename... Args>
99 static void Exists(const String& path, const char* message, const Args& ... args);
100
101public: // NotExists operations
102 static void NotExists(const String& path);
103 template<typename... Args>
104 static void NotExists(const String& path, const char* message, const Args& ... args);
105
106public: // IsInstanceOf operations
107 template<class TExpected, class T>
108 static void IsInstanceOfType(const T& instance);
109 template<class TExpected, class T, typename... Args>
110 static void IsInstanceOfType(const T& instance, const char* message, const Args& ... args);
111 template<class TExpected, class T>
112 static void IsInstanceOfType(const T* pInstance);
113 template<class TExpected, class T, typename... Args>
114 static void IsInstanceOfType(const T* pInstance, const char* message, const Args& ... args);
115
116public: // IsNotInstanceOfType operations
117 template<class TExpected, class T>
118 static void IsNotInstanceOfType(const T& instance);
119 template<class TExpected, class T, typename... Args>
120 static void IsNotInstanceOfType(const T& instance, const char* message, const Args& ... args);
121 template<class TExpected, class T>
122 static void IsNotInstanceOfType(const T* pInstance);
123 template<class TExpected, class T, typename... Args>
124 static void IsNotInstanceOfType(const T* pInstance, const char* message, const Args& ... args);
125
126public: // Throws operations
127 template<typename TException, typename TFunction>
128 static void Throws(TFunction&& func);
129 template<typename TException, typename TFunction>
130 static void Throws(const char* message, TFunction&& func);
131
132private: // methods
133 static void CheckInternal(bool predicate, const char* message);
134 static void ErrorInternal(const char* message);
135 static void FailInternal(const char* message);
136
137private: // static/const fields
138 static const char* const areEqualDefaultMessage;
139 static const char* const areEqualDefaultMessageIntegersInHex;
140 static const char* const areNotEqualDefaultMessage;
141 static const char* const isTrueDefaultMessage;
142 static const char* const isFalseDefaultMessage;
143 static const char* const isNullDefaultMessage;
144 static const char* const isNotNullDefaultMessage;
145 static const char* const isEmptyDefaultMessage;
146 static const char* const isNotEmptyDefaultMessage;
147 static const char* const existsDefaultMessage;
148 static const char* const notExistsDefaultMessage;
149 static const char* const isInstanceOfTypeDefaultMessage;
150 static const char* const isNotInstanceOfTypeDefaultMessage;
151 static const char* const throwsNotDefaultMessage;
152 static const char* const throwsWrongTypeOfExceptionDefaultMessage;
153};
154
156// inline methods of static class Assert
157
158// Assert::AreEqual() operations
159inline void Assert::AreEqual(const void* expected, const void* actual)
160{
161 return Assert::AreEqual(expected, actual, areEqualDefaultMessageIntegersInHex, expected, actual);
162}
163
164inline void Assert::AreEqual(const char* expected, const char* actual)
165{
166 if (expected == nullptr && actual == nullptr)
167 {
168 return;
169 }
170 if (expected == nullptr && actual != nullptr)
171 {
172 Assert::Fail(areEqualDefaultMessage, "", actual);
173 return;
174 }
175 if (expected != nullptr && actual == nullptr)
176 {
177 Assert::Fail(areEqualDefaultMessage, expected, "");
178 return;
179 }
180 Assert::CheckInternal(String(expected) == actual, String::Format(areEqualDefaultMessage, expected, actual));
181}
182
183inline void Assert::AreEqual(const char* expected, const String& actual)
184{
185 Assert::CheckInternal(expected == actual, String::Format(areEqualDefaultMessage, expected, actual));
186}
187
188inline void Assert::AreEqual(const String& expected, const char* actual)
189{
190 Assert::CheckInternal(expected == actual, String::Format(areEqualDefaultMessage, expected, actual));
191}
192
193inline void Assert::AreEqual(char expected, char actual)
194{
195 Assert::CheckInternal(expected == actual, String::Format(areEqualDefaultMessageIntegersInHex, format_cast(expected), format_cast(actual)));
196}
197
198inline void Assert::AreEqual(unsigned char expected, unsigned char actual)
199{
200 Assert::CheckInternal(expected == actual, String::Format(areEqualDefaultMessageIntegersInHex, format_cast(expected), format_cast(actual)));
201}
202
203inline void Assert::AreEqual(float expected, float actual, float epsilon)
204{
205 if (std::abs(actual - expected) > std::abs(epsilon))
206 {
207 Assert::FailInternal(String::Format(areEqualDefaultMessage, expected, actual));
208 }
209}
210
211inline void Assert::AreEqual(double expected, double actual, double epsilon)
212{
213 if (std::abs(actual - expected) > std::abs(epsilon))
214 {
215 Assert::FailInternal(String::Format(areEqualDefaultMessage, expected, actual));
216 }
217}
218
219template<typename... Args>
220inline void Assert::AreEqual(float expected, float actual, float epsilon, const char* message, const Args& ... args)
221{
222 if (std::abs(actual - expected) > std::abs(epsilon))
223 {
224 Assert::FailInternal(String::Format(message, format_cast(args)...));
225 }
226}
227
228template<typename... Args>
229inline void Assert::AreEqual(double expected, double actual, double epsilon, const char* message, const Args& ...args)
230{
231 if (std::abs(actual - expected) > std::abs(epsilon))
232 {
233 Assert::FailInternal(String::Format(message, format_cast(args)...));
234 }
235}
236
237template<class T1, class T2>
238inline void Assert::AreEqual(const T1& expected, const T2& actual)
239{
240 Assert::CheckInternal(expected == actual, String::Format(areEqualDefaultMessage, format_cast(expected), format_cast(actual)));
241}
242
243template<class T1, class T2, typename... Args>
244inline void Assert::AreEqual(const T1& expected, const T2& actual, const char* message, const Args& ... args)
245{
246 Assert::CheckInternal(expected == actual, String::Format(message, format_cast(args)...));
247}
248
249template<class T1, class T2>
250inline void Assert::AreEqual(T1* expected, T2* actual)
251{
252 Assert::AreEqual(static_cast<const void*>(expected), static_cast<const void*>(actual));
253}
254
255// Assert::AreNotEqual() operations
256inline void Assert::AreNotEqual(float expected, float actual, float epsilon)
257{
258 if (std::abs(actual - expected) <= std::abs(epsilon))
259 {
260 Assert::FailInternal(String::Format(areNotEqualDefaultMessage, expected, actual));
261 }
262}
263
264inline void Assert::AreNotEqual(double expected, double actual, double epsilon)
265{
266 if (std::abs(actual - expected) <= std::abs(epsilon))
267 {
268 Assert::FailInternal(String::Format(areNotEqualDefaultMessage, expected, actual));
269 }
270}
271
272template<typename... Args>
273inline void Assert::AreNotEqual(float expected, float actual, float epsilon, const char* message, const Args& ... args)
274{
275 if (std::abs(actual - expected) <= std::abs(epsilon))
276 {
277 Assert::FailInternal(String::Format(message, format_cast(args)...));
278 }
279}
280
281template<typename... Args>
282inline void Assert::AreNotEqual(double expected, double actual, double epsilon, const char* message, const Args& ... args)
283{
284 if (std::abs(actual - expected) <= std::abs(epsilon))
285 {
286 Assert::FailInternal(String::Format(message, format_cast(args)...));
287 }
288}
289
290template<class T1, class T2>
291inline void Assert::AreNotEqual(const T1& notExpected, const T2& actual)
292{
293 Assert::CheckInternal(notExpected != actual, String::Format(areNotEqualDefaultMessage, format_cast(notExpected), format_cast(actual)));
294}
295
296template<class T1, class T2, typename... Args>
297inline void Assert::AreNotEqual(const T1& notExpected, const T2& actual, const char* message, const Args& ... args)
298{
299 Assert::CheckInternal(notExpected != actual, String::Format(message, format_cast(args)...));
300}
301
302// Assert::Fail() operations
303template<typename... Args>
304inline void Assert::Error(const char* message, const Args& ... args)
305{
306 Assert::ErrorInternal(String::Format(message, format_cast(args)...));
307}
308
309// Assert::Fail() operations
310template<typename... Args>
311inline void Assert::Fail(const char* message, const Args& ... args)
312{
313 Assert::FailInternal(String::Format(message, format_cast(args)...));
314}
315
316// IsTrue operations
317template<class Predicate>
318inline void Assert::IsTrue(Predicate predicate)
319{
320 Assert::CheckInternal(predicate ? true : false, isTrueDefaultMessage);
321}
322
323template<class Predicate, typename... Args>
324inline void Assert::IsTrue(Predicate predicate, const char* message, const Args& ... args)
325{
326 Assert::CheckInternal(predicate ? true : false, String::Format(message, format_cast(args)...));
327}
328
329// IsFalse operations
330template<class Predicate>
331inline void Assert::IsFalse(Predicate predicate)
332{
333 Assert::CheckInternal(predicate ? false : true, isFalseDefaultMessage);
334}
335
336template<class Predicate, typename... Args>
337inline void Assert::IsFalse(Predicate predicate, const char* message, const Args& ... args)
338{
339 Assert::CheckInternal(predicate ? false : true, String::Format(message, format_cast(args)...));
340}
341
342// IsNull operations
343template<class T>
344inline void Assert::IsNull(T* pValue)
345{
346 Assert::CheckInternal(pValue == nullptr, isNullDefaultMessage);
347}
348
349template<class T, typename... Args>
350inline void Assert::IsNull(T* pValue, const char* message, const Args& ... args)
351{
352 Assert::CheckInternal(pValue == nullptr, String::Format(message, format_cast(args)...));
353}
354
355// IsNotNull operations
356template<class T>
357inline void Assert::IsNotNull(T* pValue)
358{
359 Assert::CheckInternal(pValue != nullptr, isNotNullDefaultMessage);
360}
361
362template<class T, typename... Args>
363inline void Assert::IsNotNull(T* pValue, const char* message, const Args& ... args)
364{
365 Assert::CheckInternal(pValue != nullptr, String::Format(message, format_cast(args)...));
366}
367
368// IsEmpty operations
369inline void Assert::IsEmpty(const String& s)
370{
371 Assert::CheckInternal(s.IsEmpty(), isEmptyDefaultMessage);
372}
373
374template<typename... Args>
375inline void Assert::IsEmpty(const String& s, const char* message, const Args& ... args)
376{
377 Assert::CheckInternal(s.IsEmpty(), String::Format(message, format_cast(args)...));
378}
379
380// IsNotEmpty operations
381inline void Assert::IsNotEmpty(const String& s)
382{
383 Assert::CheckInternal(!s.IsEmpty(), isNotEmptyDefaultMessage);
384}
385
386template<typename... Args>
387inline void Assert::IsNotEmpty(const String& s, const char* message, const Args& ... args)
388{
389 Assert::CheckInternal(!s.IsEmpty(), String::Format(message, format_cast(args)...));
390}
391
392// Exists operations
393inline void Assert::Exists(const String& path)
394{
395 Assert::CheckInternal(Io::File::Exists(path), existsDefaultMessage);
396}
397
398template<typename... Args>
399inline void Assert::Exists(const String& path, const char* message, const Args& ... args)
400{
401 Assert::CheckInternal(Io::File::Exists(path), String::Format(message, format_cast(args)...));
402}
403
404// NotExists operations
405inline void Assert::NotExists(const String& path)
406{
407 Assert::CheckInternal(!Io::File::Exists(path), notExistsDefaultMessage);
408}
409
410template<typename... Args>
411inline void Assert::NotExists(const String& path, const char* message, const Args& ... args)
412{
413 Assert::CheckInternal(!Io::File::Exists(path), String::Format(message, format_cast(args)...));
414}
415
416// IsInstanceOf operations
417template<class TExpected, class T>
418inline void Assert::IsInstanceOfType(const T& instance)
419{
420 if (!Arp::IsInstanceOfType<TExpected>(instance))
421 {
422 Assert::FailInternal(String::Format(isInstanceOfTypeDefaultMessage, Arp::TypeName<TExpected>()));
423 }
424}
425
426template<class TExpected, class T, typename... Args>
427inline void Assert::IsInstanceOfType(const T& instance, const char* message, const Args& ... args)
428{
429 if (!Arp::IsInstanceOfType<TExpected>(instance))
430 {
431 Assert::FailInternal(String::Format(message, format_cast(args)...));
432 }
433}
434
435template<class TExpected, class T>
436inline void Assert::IsInstanceOfType(const T* pInstance)
437{
438 if (!Arp::IsInstanceOfType<TExpected>(pInstance))
439 {
440 Assert::FailInternal(String::Format(isInstanceOfTypeDefaultMessage, TypeName<TExpected>()));
441 }
442}
443
444template<class TExpected, class T, typename... Args>
445inline void Assert::IsInstanceOfType(const T* pInstance, const char* message, const Args& ... args)
446{
447 if (!Arp::IsInstanceOfType<TExpected>(pInstance))
448 {
449 Assert::FailInternal(String::Format(message, format_cast(args)...));
450 }
451}
452
453// IsNotInstanceOf operations
454template<class TExpected, class T>
455inline void Assert::IsNotInstanceOfType(const T& instance)
456{
457 if (Arp::IsInstanceOfType<TExpected>(instance))
458 {
459 Assert::FailInternal(String::Format(isNotInstanceOfTypeDefaultMessage, TypeName<TExpected>()));
460 }
461}
462
463template<class TExpected, class T, typename... Args>
464inline void Assert::IsNotInstanceOfType(const T& instance, const char* message, const Args& ... args)
465{
466 if (Arp::IsInstanceOfType<TExpected>(instance))
467 {
468 Assert::FailInternal(String::Format(message, format_cast(args)...));
469 }
470}
471
472template<class TExpected, class T>
473inline void Assert::IsNotInstanceOfType(const T* pInstance)
474{
475 if (Arp::IsInstanceOfType<TExpected>(pInstance))
476 {
477 Assert::FailInternal(String::Format(isNotInstanceOfTypeDefaultMessage, TypeName<TExpected>()));
478 }
479}
480
481template<class TExpected, class T, typename... Args>
482inline void Assert::IsNotInstanceOfType(const T* pInstance, const char* message, const Args& ... args)
483{
484 if (IsInstanceOfType<TExpected>(pInstance))
485 {
486 Assert::FailInternal(String::Format(message, format_cast(args)...));
487 }
488}
489
490// Throws operations
491template<typename TException, typename TFunction>
492inline void Assert::Throws(TFunction&& func)
493{
494 Assert::Throws<TException>(nullptr, std::forward<TFunction>(func));
495}
496
497#pragma warning (disable:4715)
498
499template<typename TException, typename TFunction>
500inline void Assert::Throws(const char* message, TFunction&& func)
501{
502 try
503 {
504 func();
505 }
506 catch (const TException&)
507 {
508 return; // success
509 }
510 catch (...)
511 {
512 // unexpected exception type was thrown
513 if (message == nullptr)
514 {
515 Assert::FailInternal(throwsWrongTypeOfExceptionDefaultMessage);
516 }
517 else
518 {
519 Assert::FailInternal(message);
520 }
521 }
522 // no exception at all
523 if (message == nullptr)
524 {
525 Assert::FailInternal(String::Format(throwsNotDefaultMessage, TypeName<TException>()));
526 }
527 else
528 {
529 Assert::FailInternal(message);
530 }
531}
532
533}}}} // end of namesapce Arp::System::Commons::Testing
static bool Exists(const String &path)
Checks for existence of a file.
Static assertion class for easy use in unit tests.
Definition: Assert.hpp:19
This (meta programming) class provides the C++ typename of the as template argument passed type.
Definition: TypeName.hxx:67
static SelfType Format(const SelfType &format, const Args &... args)
Formats the format string using the .NET/Python syntax with the given variadic arguments.
Definition: BasicString.hxx:1493
bool IsInstanceOfType(const TInstance &instance)
Tests if the type of the as argument passed instance is T or derived by T .
Definition: TypeDeduction.hxx:26
Root namespace for the PLCnext API