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