ModErn Text Analysis
META Enumerates Textual Applications
unit_test.h
Go to the documentation of this file.
1 
10 #ifndef META_UNIT_TEST_H_
11 #define META_UNIT_TEST_H_
12 
13 #include <cmath>
14 #include <iomanip>
15 #include <string>
16 #include <functional>
17 #include <iostream>
18 #include "util/printing.h"
19 
23 #define ASSERT(expr) \
24  do \
25  { \
26  if (!(expr)) \
27  FAIL("Assertion failed: " #expr); \
28  } while (0)
29 
34 #define ASSERT_EQUAL(exp1, exp2) \
35  do \
36  { \
37  std::string msg = testing::assert_equal(exp1, exp2, #exp1, #exp2); \
38  if (!msg.empty()) \
39  FAIL(msg); \
40  } while (0)
41 
45 #define ASSERT_APPROX_EQUAL(exp1, exp2) \
46  do \
47  { \
48  std::string msg \
49  = testing::assert_approx_equal(exp1, exp2, #exp1, #exp2); \
50  if (!msg.empty()) \
51  FAIL(msg); \
52  } while (0)
53 
57 #define ASSERT_BINOP(exp1, exp2, binop) \
58  do \
59  { \
60  std::string msg = testing::assert(exp1, exp2, #exp1, #exp2, binop); \
61  if (!msg.empty()) \
62  FAIL(msg); \
63  } while (0)
64 
69 #define FAIL(why) \
70  do \
71  { \
72  std::string fail_msg = "[ " + printing::make_red("FAIL") + " ] " \
73  + (why) + " (" + testing::filename(__FILE__) \
74  + ":" + std::to_string(__LINE__) + ")"; \
75  throw testing::unit_test_exception{fail_msg}; \
76  } while (0)
77 
81 #define ASSERT_LESS(exp1, exp2) \
82  do \
83  { \
84  std::string msg = testing::assert_less(exp1, exp2, #exp1, #exp2); \
85  if (!msg.empty()) \
86  FAIL(msg); \
87  } while (0)
88 
92 #define ASSERT_GREATER(exp1, exp2) \
93  do \
94  { \
95  std::string msg = testing::assert_greater(exp1, exp2, #exp1, #exp2); \
96  if (!msg.empty()) \
97  FAIL(msg); \
98  } while (0)
99 
100 namespace meta
101 {
102 
106 namespace testing
107 {
109 static double epsilon = 0.0000001;
110 
114 inline std::string filename(const std::string& path)
115 {
116  size_t slash = path.find_last_of("/\\");
117  if(slash == std::string::npos)
118  return path;
119  return path.substr(slash + 1);
120 }
121 
131 template <class T, class K, class BinOp>
132 inline std::string assert_equal(const T& expected, const K& actual,
133  const char* expstr, const char* actstr,
134  BinOp&& binop)
135 {
136  if (!binop(expected, actual))
137  {
138  std::stringstream ss;
139  ss << "[" << expstr << " == " << actstr << "] => [" << expected
140  << " == " << actual << "]";
141  return ss.str();
142  }
143  return "";
144 }
145 
152 template <class T, class K>
153 inline std::string assert_equal(const T& expected, const K& actual,
154  const char* expstr, const char* actstr)
155 {
156  return assert_equal(expected, actual, expstr, actstr,
157  [](const T& a, const K& b)
158  {
159  return a == b;
160  });
161 }
162 
169 template <class T, class K>
170 inline std::string assert_approx_equal(const T& expected, const K& actual,
171  const char* expstr, const char* actstr)
172 {
173  if (!(std::abs(expected - actual) < epsilon))
174  {
175  std::stringstream ss;
176  ss << "[abs(" << expstr << " - " << actstr << ") < epsilon] => [abs("
177  << expected << " - " << actual << ") < " << epsilon << "]";
178  return ss.str();
179  }
180  return "";
181 }
182 
189 template <class T, class K>
190 inline std::string assert_less(const T& expected, const K& actual,
191  const char* expstr, const char* actstr)
192 {
193  if (!(expected < actual))
194  {
195  std::stringstream ss;
196  ss << "[" << expstr << " < " << actstr << "] => [" << expected << " < "
197  << actual << "]";
198  return ss.str();
199  }
200  return "";
201 }
202 
209 template <class T, class K>
210 inline std::string assert_greater(const T& expected, const K& actual,
211  const char* expstr, const char* actstr)
212 {
213  if (!(expected > actual))
214  {
215  std::stringstream ss;
216  ss << "[" << expstr << " > " << actstr << "] => [" << expected << " > "
217  << actual << "]";
218  return ss.str();
219  }
220  return "";
221 }
222 
226 class unit_test_exception: public std::runtime_error
227 {
228  public:
229  using std::runtime_error::runtime_error;
230 };
231 
238 template <class Func>
239 int run_test(const std::string& test_name, Func&& func)
240 {
241  try
242  {
243  func();
244  }
245  catch (std::exception& ex)
246  {
247  std::cerr << " " << std::setw(40) << std::left
248  << (test_name + ": ") << ex.what() << std::endl;
249  return 1;
250  }
251 
252  return 0;
253 }
254 }
255 }
256 
257 #endif
std::string assert_greater(const T &expected, const K &actual, const char *expstr, const char *actstr)
Definition: unit_test.h:210
std::string assert_approx_equal(const T &expected, const K &actual, const char *expstr, const char *actstr)
Definition: unit_test.h:170
std::string assert_equal(const T &expected, const K &actual, const char *expstr, const char *actstr, BinOp &&binop)
Allows the user to see what the evaluated statements are.
Definition: unit_test.h:132
std::string assert_less(const T &expected, const K &actual, const char *expstr, const char *actstr)
Definition: unit_test.h:190
int run_test(const std::string &test_name, Func &&func)
Runs a unit test in a semi-controlled environment.
Definition: unit_test.h:239
The ModErn Text Analysis toolkit is a suite of natural language processing, classification, information retreival, data mining, and other applications of text processing.
Definition: analyzer.h:24
Exception class used to report errors in the unit test.
Definition: unit_test.h:226
std::string filename(const std::string &path)
Definition: unit_test.h:114