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