HOPS
HOPS class reference
MHO_TestAssertions.hh
Go to the documentation of this file.
1 #ifndef MHO_TestAssertions_HH__
2 #define MHO_TestAssertions_HH__
3 
12 #include "MHO_Message.hh"
13 #include <cmath>
14 #include <iostream>
15 #include <sstream>
16 #include <stdexcept>
17 #include <string>
18 
19 #define HOPS_THROW \
20  { \
21  throw std::runtime_error(std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + std::string(" in ") + \
22  std::string(__PRETTY_FUNCTION__)); \
23  }
24 
25 #define HOPS_ASSERT_THROW(test_cond) \
26  { \
27  if(!(test_cond)) \
28  { \
29  throw std::runtime_error(std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + \
30  std::string(" in ") + std::string(__PRETTY_FUNCTION__)); \
31  } \
32  }
33 
34 #define HOPS_ASSERT_EQUAL(a, b) \
35  { \
36  if((a) != (b)) \
37  { \
38  throw std::runtime_error(std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + \
39  std::string(" in ") + std::string(__PRETTY_FUNCTION__) + std::string(": ") + \
40  std::to_string((a)) + std::string(" != ") + std::to_string((b))); \
41  } \
42  }
43 
44 //to_string is unpredictable for floats/doubles, so this instead
45 #define HOPS_ASSERT_FLOAT_LESS_THAN(a, b) \
46  { \
47  std::stringstream ssa; \
48  ssa << a; \
49  std::stringstream ssb; \
50  ssb << b; \
51  if((a) > (b)) \
52  { \
53  throw std::runtime_error(std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + \
54  std::string(" in ") + std::string(__PRETTY_FUNCTION__) + std::string(": ") + ssa.str() + \
55  std::string(" !< ") + ssb.str()); \
56  } \
57  }
58 
59 // The macros below are intended for use inside an int-returning test main():
60 // on failure they print a diagnostic and "return 1", so the executable's exit
61 // code reports the failure to ctest, this is intended for use in unit test executabes.
62 
63 #define REQUIRE(cond) \
64  do \
65  { \
66  if(!(cond)) \
67  { \
68  std::cerr << "FAIL: " #cond " @ " << __FILE__ << ":" << __LINE__ << std::endl; \
69  return 1; \
70  } \
71  } \
72  while(0)
73 
74 //require that two streamable values compare equal; prints both operands on failure.
75 //works for any type with operator== and operator<< (std::string, numeric types, etc.)
76 #define REQUIRE_EQUAL(a, b) \
77  do \
78  { \
79  if(!((a) == (b))) \
80  { \
81  std::stringstream _hops_sa; \
82  std::stringstream _hops_sb; \
83  _hops_sa << (a); \
84  _hops_sb << (b); \
85  std::cerr << "FAIL: " #a " == " #b " @ " << __FILE__ << ":" << __LINE__ << " (\"" << _hops_sa.str() << "\" vs \"" \
86  << _hops_sb.str() << "\")" << std::endl; \
87  return 1; \
88  } \
89  } \
90  while(0)
91 
92 //require that evaluating the expression throws a std::exception (e.g. via HOPS_THROW)
93 #define REQUIRE_THROWS(expr) \
94  do \
95  { \
96  bool _hops_caught = false; \
97  try \
98  { \
99  (void)(expr); \
100  } \
101  catch(const std::exception&) \
102  { \
103  _hops_caught = true; \
104  } \
105  if(!_hops_caught) \
106  { \
107  std::cerr << "FAIL: expected exception from " #expr " @ " << __FILE__ << ":" << __LINE__ << std::endl; \
108  return 1; \
109  } \
110  } \
111  while(0)
112 
113 //compare two floating-point values up to an absolute tolerance
114 #define CHECK_CLOSE(a, b, tol) \
115  do \
116  { \
117  if(std::fabs((a) - (b)) > (tol)) \
118  { \
119  std::cerr << "FAIL: |" #a " - " #b "| > " #tol " @ " << __FILE__ << ":" << __LINE__ << " (" << (a) << " vs " \
120  << (b) << ")" << std::endl; \
121  return 1; \
122  } \
123  } \
124  while(0)
125 
126 //compare two complex (or other std::abs-able) values up to an absolute tolerance on the magnitude of their difference;
127 //std::abs is used instead of std::fabs so this works for std::complex as well as real types
128 #define REQUIRE_CLOSE_CPLX(a, b, tol) \
129  do \
130  { \
131  if(std::abs((a) - (b)) > (tol)) \
132  { \
133  std::cerr << "FAIL: |" #a " - " #b "| > " #tol " @ " << __FILE__ << ":" << __LINE__ \
134  << " (diff=" << std::abs((a) - (b)) << ")" << std::endl; \
135  return 1; \
136  } \
137  } \
138  while(0)
139 
140 #endif