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