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