SST/macro
test.h
Go to the documentation of this file.
1 #ifndef TEST_H
2 #define TEST_H
3 
4 #include <vector>
5 #include <iostream>
6 #include <string.h>
7 #include <sprockit/test/output.h>
10 #include <sprockit/test/fxn.h>
11 #include <sprockit/spkt_string.h>
12 
13 const char*
14 truncate_file(const char* file);
15 
16 class TestCase
17 {
18  public:
19  virtual bool is_correct() const = 0;
20 
21  virtual void print_error(std::ostream& os) const = 0;
22 
23  virtual void print_descr(std::ostream& os) const = 0;
24 
25  virtual void print_test_value(std::ostream& os) const = 0;
26 
27  virtual void print_asserted_value(std::ostream& os) const = 0;
28 
29 };
30 
31 template <class T>
33  public TestCase
34 {
35  private:
36  std::string descr_;
38  bool equal_;
39  T test_;
41 
42  public:
43  TestCase_impl(const std::string& descr,
44  bool should_be_equal,
45  const T& test,
46  const T& asserted)
47  : descr_(descr),
48  should_be_equal_(should_be_equal),
49  equal_(false),
50  test_(test),
51  asserted_(asserted) {
52  equal_ = TestEquals<T>::equals(test_, asserted_);
53  }
54 
55  bool is_correct() const {
56  return equal_ == should_be_equal_;
57  }
58 
59  void print_error(std::ostream &os) const {
60  if (should_be_equal_) {
61  os << "SHOULD BE EQUAL";
62  }
63  else {
64  os << "SHOULD NOT BE EQUAL";
65  }
66  }
67 
68  void
69  print_descr(std::ostream& os) const {
70  os << descr_;
71  }
72 
73  void
74  print_test_value(std::ostream& os) const {
75  ClassOutput<T>::print(test_, os);
76  }
77 
78  void
79  print_asserted_value(std::ostream& os) const {
80  ClassOutput<T>::print(asserted_, os);
81  }
82 
83 };
84 
85 class UnitTest
86 {
87 
88  private:
89  std::vector<TestCase*> tests_;
90 
91  public:
92  void append(TestCase* test_case) {
93  tests_.push_back(test_case);
94  }
95 
96  /**
97  @return The number of failed tests
98  */
99  int validate(std::ostream& os = std::cout);
100 
101  static int
102  exit_status(int nfailed) {
103  return nfailed == 0 ? 0 : 1;
104  }
105 
106 };
107 
108 template <class T, class A>
110 {
111  public:
112  static void
113  add_test(UnitTest& test_set,
114  const char* descr,
115  const char* file,
116  int line,
117  const T& test,
118  const A& asserted,
119  bool should_be_equal = true) {
120  A casted(test);
121  std::string info = sprockit::printf("%s %s:%d", descr, file, line);
122  test_set.append(new TestCase_impl<A>(info,should_be_equal,casted,asserted));
123  }
124 };
125 
126 template <class T>
127 class AssertEqual<T,T>
128 {
129  public:
130  static void
131  add_test(UnitTest &test_set,
132  const char *descr,
133  const char* file,
134  int line,
135  const T& test,
136  const T& asserted,
137  bool should_be_equal = true) {
138  std::string info = sprockit::printf("%s %s:%d", descr, file, line);
139  test_set.append(new TestCase_impl<T>(info,should_be_equal,test,asserted));
140  }
141 };
142 
143 
144 template <class T, class A>
145 class AssertEqual< std::vector<T>, A>
146 {
147  public:
148  static void
149  add_test(UnitTest& test_set,
150  const char* descr,
151  const char* file,
152  int line,
153  const std::vector<T>& test,
154  const A& asserted,
155  bool should_be_equal = true) {
156  std::vector<T> asserted_vec;
157  asserted_vec.push_back(asserted);
158  std::string info = sprockit::printf("%s %s:%d", descr, file, line);
159  test_set.append(new TestCase_impl<std::vector<T> >(info,should_be_equal,test,
160  asserted_vec));
161  }
162 };
163 
164 template <class T>
165 class AssertEqual< std::vector<T>, std::vector<T> >
166 {
167  public:
168  static void
169  add_test(UnitTest& test_set,
170  const char* descr,
171  const char* file,
172  int line,
173  const std::vector<T>& test,
174  const std::vector<T>& asserted,
175  bool should_be_equal = true) {
176  std::string info = sprockit::printf("%s %s:%d", descr, file, line);
177  test_set.append(new TestCase_impl<std::vector<T> >(info,should_be_equal,test,
178  asserted));
179  }
180 };
181 
182 void _assertFalse(UnitTest& test_set,
183  const char* descr,
184  const char* file,
185  int line,
186  bool test);
187 
188 void _assertTrue(UnitTest& test_set,
189  const char* descr,
190  const char* file,
191  int line,
192  bool test);
193 
194 template <class T, class A>
195 void _assertEqual(UnitTest& test_set,
196  const char* descr,
197  const char* file,
198  int line,
199  const T& test,
200  const A& asserted,
201  bool should_be_equal)
202 {
203  AssertEqual<T,A>::add_test(test_set, descr, file, line, test, asserted,
204  should_be_equal);
205 }
206 
207 template <class T, class A>
208 void _assertEqual(UnitTest& test_set,
209  const char* descr,
210  const char* file,
211  int line,
212  const T& test,
213  const A& assert1,
214  const A& assert2,
215  bool should_be_equal)
216 {
217  T assert_container;
218  ContainerAppend<T,A>::append(assert_container, assert1);
219  ContainerAppend<T,A>::append(assert_container, assert2);
220  AssertEqual<T,T>::add_test(test_set, descr, file, line, test, assert_container,
221  should_be_equal);
222 }
223 
224 template <class T, class A>
225 void _assertEqual(UnitTest& test_set,
226  const char* descr,
227  const char* file,
228  int line,
229  const T& test,
230  const A& assert1,
231  const A& assert2,
232  const A& assert3,
233  bool should_be_equal)
234 {
235  T assert_container;
236  ContainerAppend<T,A>::append(assert_container, assert1);
237  ContainerAppend<T,A>::append(assert_container, assert2);
238  ContainerAppend<T,A>::append(assert_container, assert3);
239  AssertEqual<T,T>::add_test(test_set, descr, file, line, test, assert_container,
240  should_be_equal);
241 }
242 
243 template <class T, class A>
244 void _assertEqual(UnitTest& test_set,
245  const char* descr,
246  const char* file,
247  int line,
248  const T& test,
249  const A& assert1,
250  const A& assert2,
251  const A& assert3,
252  const A& assert4,
253  bool should_be_equal)
254 {
255  T assert_container;
256  ContainerAppend<T,A>::append(assert_container, assert1);
257  ContainerAppend<T,A>::append(assert_container, assert2);
258  ContainerAppend<T,A>::append(assert_container, assert3);
259  ContainerAppend<T,A>::append(assert_container, assert4);
260  AssertEqual<T,T>::add_test(test_set, descr, file, line, test, assert_container,
261  should_be_equal);
262 }
263 
264 template <class T, class A>
265 void _assertEqual(UnitTest& test_set,
266  const char* descr,
267  const char* file,
268  int line,
269  const T& test,
270  const A& assert1,
271  const A& assert2,
272  const A& assert3,
273  const A& assert4,
274  const A& assert5,
275  bool should_be_equal)
276 {
277  T assert_container;
278  ContainerAppend<T,A>::append(assert_container, assert1);
279  ContainerAppend<T,A>::append(assert_container, assert2);
280  ContainerAppend<T,A>::append(assert_container, assert3);
281  ContainerAppend<T,A>::append(assert_container, assert4);
282  ContainerAppend<T,A>::append(assert_container, assert5);
283  AssertEqual<T,T>::add_test(test_set, descr, file, line, test, assert_container,
284  should_be_equal);
285 }
286 
287 template <class T, class A>
288 void _assertEqual(UnitTest& test_set,
289  const char* descr,
290  const char* file,
291  int line,
292  const T& test,
293  const A& assert1,
294  const A& assert2,
295  const A& assert3,
296  const A& assert4,
297  const A& assert5,
298  const A& assert6,
299  bool should_be_equal)
300 {
301  T assert_container;
302  ContainerAppend<T,A>::append(assert_container, assert1);
303  ContainerAppend<T,A>::append(assert_container, assert2);
304  ContainerAppend<T,A>::append(assert_container, assert3);
305  ContainerAppend<T,A>::append(assert_container, assert4);
306  ContainerAppend<T,A>::append(assert_container, assert5);
307  ContainerAppend<T,A>::append(assert_container, assert6);
308  AssertEqual<T,T>::add_test(test_set, descr, file, line, test, assert_container,
309  should_be_equal);
310 }
311 
312 template <class T, class A>
313 void _assertEqual(UnitTest& test_set,
314  const char* descr,
315  const char* file,
316  int line,
317  const T& test,
318  const A& asserted)
319 {
320  _assertEqual(test_set, descr, file, line, test, asserted, true);
321 }
322 
323 template <class T, class A>
324 void _assertEqual(UnitTest& test_set,
325  const char* descr,
326  const char* file,
327  int line,
328  const T& test,
329  const A& assert1,
330  const A& assert2)
331 {
332  _assertEqual(test_set, descr, file, line, test, assert1, assert2, true);
333 }
334 
335 template <class T, class A>
336 void _assertEqual(UnitTest& test_set,
337  const char* descr,
338  const char* file,
339  int line,
340  const T& test,
341  const A& assert1,
342  const A& assert2,
343  const A& assert3)
344 {
345  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
346  true);
347 }
348 
349 template <class T, class A>
350 void _assertEqual(UnitTest& test_set,
351  const char* descr,
352  const char* file,
353  int line,
354  const T& test,
355  const A& assert1,
356  const A& assert2,
357  const A& assert3,
358  const A& assert4)
359 {
360  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
361  assert4, true);
362 }
363 
364 template <class T, class A>
365 void _assertEqual(UnitTest& test_set,
366  const char* descr,
367  const char* file,
368  int line,
369  const T& test,
370  const A& assert1,
371  const A& assert2,
372  const A& assert3,
373  const A& assert4,
374  const A& assert5)
375 {
376  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
377  assert4, assert5, true);
378 }
379 
380 template <class T, class A>
381 void _assertEqual(UnitTest& test_set,
382  const char* descr,
383  const char* file,
384  int line,
385  const T& test,
386  const A& assert1,
387  const A& assert2,
388  const A& assert3,
389  const A& assert4,
390  const A& assert5,
391  const A& assert6)
392 {
393  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
394  assert4, assert5, assert6, true);
395 }
396 
397 template <class T, class A>
398 void _assertNotEqual(UnitTest& test_set,
399  const char* descr,
400  const char* file,
401  int line,
402  const T& test,
403  const A& asserted)
404 {
405  _assertEqual(test_set, descr, file, line, test, asserted, false);
406 }
407 
408 template <class T, class A>
409 void _assertNotEqual(UnitTest& test_set,
410  const char* descr,
411  const char* file,
412  int line,
413  const T& test,
414  const A& assert1,
415  const A& assert2)
416 {
417  _assertEqual(test_set, descr, file, line, test, assert1, assert2, false);
418 }
419 
420 template <class T, class A>
421 void _assertNotEqual(UnitTest& test_set,
422  const char* descr,
423  const char* file,
424  int line,
425  const T& test,
426  const A& assert1,
427  const A& assert2,
428  const A& assert3)
429 {
430  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
431  false);
432 }
433 
434 template <class T, class A>
435 void _assertNotEqual(UnitTest& test_set,
436  const char* descr,
437  const char* file,
438  int line,
439  const T& test,
440  const A& assert1,
441  const A& assert2,
442  const A& assert3,
443  const A& assert4)
444 {
445  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
446  assert4, false);
447 }
448 
449 template <class T, class A>
450 void _assertNotEqual(UnitTest& test_set,
451  const char* descr,
452  const char* file,
453  int line,
454  const T& test,
455  const A& assert1,
456  const A& assert2,
457  const A& assert3,
458  const A& assert4,
459  const A& assert5)
460 {
461  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
462  assert4, assert5, false);
463 }
464 
465 template <class T, class A>
466 void _assertNotEqual(UnitTest& test_set,
467  const char* descr,
468  const char* file,
469  int line,
470  const T& test,
471  const A& assert1,
472  const A& assert2,
473  const A& assert3,
474  const A& assert4,
475  const A& assert5,
476  const A& assert6)
477 {
478  _assertEqual(test_set, descr, file, line, test, assert1, assert2, assert3,
479  assert4, assert5, assert6, false);
480 }
481 
483  public TestCase
484 {
485  private:
486  std::string descr_;
487  const char* file_;
488  int line_;
489  std::string exc_;
490  std::string test_;
491  std::string errormsg_;
492  bool success_;
493 
494  public:
495  ExceptionTestCase(const std::string& descr,
496  const char* file,
497  int line,
498  const std::string& exc,
499  const std::string& test,
500  const std::string& errormsg,
501  bool success)
502  : descr_(descr),
503  file_(file),
504  line_(line),
505  exc_(exc),
506  errormsg_(errormsg),
507  success_(success) {
508  int last_split = 0;
509  const char* data = test.c_str();
510  for (int i=0; i < test.size(); ++i){
511  if (data[i] == '\n'){
512  int length = i - last_split;
513  test_ += test.substr(last_split, length) + "\n ";
514  last_split = i+1; //plus one to skip new line
515  }
516  }
517  test_ += test.substr(last_split);
518  }
519 
520  bool is_correct() const {
521  return success_;
522  }
523 
524  void print_error(std::ostream& os) const {
525  os << errormsg_;
526  }
527 
528  void print_descr(std::ostream& os) const {
529  os << descr_ << " "
530  << file_ << ":"
531  << line_;
532  }
533 
534  void print_test_value(std::ostream& os) const {
535  os << test_;
536  }
537 
538  void print_asserted_value(std::ostream& os) const {
539  os << exc_;
540  }
541 
542 };
543 
544 template <class Exc>
545 void assertThrows_impl(UnitTest& test_set, const char* descr, const char* file,
546  int line, const char* exc, TestFxn* fxn)
547 {
548  try {
549  fxn->run();
550  test_set.append(new ExceptionTestCase(descr, file, line, exc, "No Exception",
551  "SHOULD THROW", false));
552  }
553  catch(Exc) {
554  test_set.append(new ExceptionTestCase(descr, file, line, exc, exc,
555  "SHOULD THROW", true));
556  }
557  catch (std::exception& e) {
558  test_set.append(new ExceptionTestCase(descr, file, line, exc, e.what(),
559  "WRONG EXCEPTION THROWN", false));
560  }
561  catch(...) {
562  test_set.append(new ExceptionTestCase(descr, file, line, exc,
563  "Unknown Exception", "WRONG EXCEPTION THROWN", false));
564  }
565 }
566 
567 #define THIS_FILE truncate_file(__FILE__)
568 
569 #define SPROCKIT_RUN_TEST(fxn, unit_tester, ...) \
570  try { \
571  fxn(unit_tester, __VA_ARGS__); \
572  } catch (std::exception& e) { \
573  unit_tester.append(new ExceptionTestCase("unexpected exception in " #fxn, THIS_FILE, __LINE__, "none", e.what(), "exception thown", false)); \
574  }
575 
576 #define SPROCKIT_RUN_TEST_NO_ARGS(fxn, unit_tester) \
577  try { \
578  fxn(unit_tester); \
579  } catch (std::exception& e) { \
580  unit_tester.append(new ExceptionTestCase("unexpected exception in " #fxn, THIS_FILE, __LINE__, "none", e.what(), "exception thown", false)); \
581  }
582 
583 #define assertThrows(test_set, descr, exc, fxn) \
584  assertThrows_impl<exc>(test_set, descr, THIS_FILE, __LINE__, #exc, fxn)
585 
586 #define assertEqual(test_set, descr, ...) \
587  _assertEqual(test_set, descr, THIS_FILE, __LINE__, __VA_ARGS__)
588 
589 #define assertNotEqual(test_set, descr, ...) \
590  _assertNotEqual(test_set, descr, THIS_FILE, __LINE__, __VA_ARGS__)
591 
592 #define assertTrue(test_set, descr, ...) \
593  _assertTrue(test_set, descr, THIS_FILE, __LINE__, __VA_ARGS__)
594 
595 #define assertFalse(test_set, descr, ...) \
596  _assertFalse(test_set, descr, THIS_FILE, __LINE__, __VA_ARGS__)
597 
598 #endif // TEST_H
599 
600 
TestCase_impl(const std::string &descr, bool should_be_equal, const T &test, const T &asserted)
Definition: test.h:43
void _assertTrue(UnitTest &test_set, const char *descr, const char *file, int line, bool test)
static void add_test(UnitTest &test_set, const char *descr, const char *file, int line, const std::vector< T > &test, const A &asserted, bool should_be_equal=true)
Definition: test.h:149
std::string descr_
Definition: test.h:36
virtual void print_test_value(std::ostream &os) const =0
static void add_test(UnitTest &test_set, const char *descr, const char *file, int line, const T &test, const A &asserted, bool should_be_equal=true)
Definition: test.h:113
static int exit_status(int nfailed)
Definition: test.h:102
virtual void print_descr(std::ostream &os) const =0
virtual bool is_correct() const =0
Definition: fxn.h:4
bool success_
Definition: test.h:492
static void append(C &c, const A &a)
Definition: container.h:26
void _assertFalse(UnitTest &test_set, const char *descr, const char *file, int line, bool test)
void _assertEqual(UnitTest &test_set, const char *descr, const char *file, int line, const T &test, const A &asserted, bool should_be_equal)
Definition: test.h:195
void _assertNotEqual(UnitTest &test_set, const char *descr, const char *file, int line, const T &test, const A &asserted)
Definition: test.h:398
T asserted_
Definition: test.h:40
void print_asserted_value(std::ostream &os) const
Definition: test.h:79
std::string printf(const char *fmt,...)
ExceptionTestCase(const std::string &descr, const char *file, int line, const std::string &exc, const std::string &test, const std::string &errormsg, bool success)
Definition: test.h:495
bool should_be_equal_
Definition: test.h:37
void print_error(std::ostream &os) const
Definition: test.h:524
const char * file_
Definition: test.h:487
static bool equals(size_t n, const T *test, const T *right)
Definition: equality.h:16
void append(TestCase *test_case)
Definition: test.h:92
bool is_correct() const
Definition: test.h:55
bool equal_
Definition: test.h:38
static void print(const T &t, std::ostream &os)
Definition: output.h:14
virtual void print_asserted_value(std::ostream &os) const =0
void assertThrows_impl(UnitTest &test_set, const char *descr, const char *file, int line, const char *exc, TestFxn *fxn)
Definition: test.h:545
std::vector< TestCase * > tests_
Definition: test.h:89
Definition: test.h:16
virtual void print_error(std::ostream &os) const =0
void print_test_value(std::ostream &os) const
Definition: test.h:534
void print_asserted_value(std::ostream &os) const
Definition: test.h:538
Definition: test.h:85
static void add_test(UnitTest &test_set, const char *descr, const char *file, int line, const T &test, const T &asserted, bool should_be_equal=true)
Definition: test.h:131
static void add_test(UnitTest &test_set, const char *descr, const char *file, int line, const std::vector< T > &test, const std::vector< T > &asserted, bool should_be_equal=true)
Definition: test.h:169
virtual void run()=0
std::string test_
Definition: test.h:490
std::string exc_
Definition: test.h:489
void print_error(std::ostream &os) const
Definition: test.h:59
void print_test_value(std::ostream &os) const
Definition: test.h:74
std::string errormsg_
Definition: test.h:491
void print_descr(std::ostream &os) const
Definition: test.h:69
std::string descr_
Definition: test.h:486
void print_descr(std::ostream &os) const
Definition: test.h:528
const char * truncate_file(const char *file)
bool is_correct() const
Definition: test.h:520