Home  · Classes  · Annotated Classes  · Modules  · Members  · Namespaces  · Related Pages
ClassTest.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2017.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Timo Sachsenberg $
32 // $Authors: Marc Sturm, Clemens Groepl $
33 // --------------------------------------------------------------------------
34 
35 #ifndef OPENMS_CONCEPT_CLASSTEST_H
36 #define OPENMS_CONCEPT_CLASSTEST_H
37 
38 // Avoid OpenMS includes here at all costs
39 // When the included headers are changed, *all* tests have to be recompiled!
40 // Use the ClassTest class if you need add high-level functionality.
41 // Includes in the C-file are ok...
43 #include <OpenMS/CONCEPT/Types.h>
47 #include <OpenMS/SYSTEM/File.h>
48 #include <OpenMS/OpenMSConfig.h>
49 #include <OpenMS/config.h>
50 
51 #include <cmath> // fabs
52 #include <cstdio> // tmpnam()
53 #include <cstdlib> // getenv()
54 #include <cstring>
55 #include <fstream>
56 #include <iostream>
57 #include <list>
58 #include <string>
59 #include <vector>
60 
61 // Empty declaration to avoid problems in case the namespace is not
62 // yet defined (e.g. TEST/ClassTest_test.cpp)
63 
65 #ifndef std__cout
66 #define std__cout std::cout
67 #endif
68 
69 namespace OpenMS
70 {
71  namespace Internal
72  {
74  namespace ClassTest
75  {
76 
81  bool OPENMS_DLLAPI
82  validate(const std::vector<std::string>& file_names);
83 
85  std::string OPENMS_DLLAPI
86  tmpFileName(const std::string& file, int line);
87 
89  inline bool OPENMS_DLLAPI
90  isRealType(float)
91  {
92  return true;
93  }
94 
96  inline bool OPENMS_DLLAPI
97  isRealType(double)
98  {
99  return true;
100  }
101 
103  inline bool OPENMS_DLLAPI
104  isRealType(long double)
105  {
106  return true;
107  }
108 
110  inline bool OPENMS_DLLAPI
112  {
113  return true;
114  }
115 
117  template <typename T>
118  inline bool
119  isRealType(const T&)
120  {
121  return false;
122  }
123 
129  void OPENMS_DLLAPI
130  testRealSimilar(const char* file, int line, long double number_1,
131  const char* number_1_stringified,
132  bool number_1_is_realtype, Int number_1_written_digits,
133  long double number_2, const char* number_2_stringified,
134  bool /* number_2_is_realtype */, Int number_2_written_digits);
135 
137  bool OPENMS_DLLAPI
138  isRealSimilar(long double number_1, long double number_2);
139 
147  void OPENMS_DLLAPI
148  testStringSimilar(const char* file, int line,
149  const std::string& string_1,
150  const char* string_1_stringified,
151  const std::string& string_2,
152  const char* string_2_stringified);
153 
155  void OPENMS_DLLAPI
156  testStringEqual(const char* file, int line,
157  const std::string& string_1,
158  const char* string_1_stringified,
159  const std::string& string_2,
160  const char* string_2_stringified);
161 
167  bool OPENMS_DLLAPI
168  isFileSimilar(const std::string& filename_1,
169  const std::string& filename_2);
170 
172  void OPENMS_DLLAPI
173  initialNewline();
174 
176  void OPENMS_DLLAPI
177  printWithPrefix(const std::string& text, const int marked = -1);
178 
180  void OPENMS_DLLAPI
181  setWhitelist(const char* const /* file */, const int line,
182  const std::string& whitelist);
183 
185  extern OPENMS_DLLAPI double ratio_max_allowed;
186 
188  extern OPENMS_DLLAPI double ratio_max;
189 
191  extern OPENMS_DLLAPI double ratio;
192 
194  extern OPENMS_DLLAPI double absdiff_max_allowed;
195 
197  extern OPENMS_DLLAPI double absdiff_max;
198 
200  extern OPENMS_DLLAPI double absdiff;
201 
202  extern OPENMS_DLLAPI int line_num_1_max;
203  extern OPENMS_DLLAPI int line_num_2_max;
204 
206  extern OPENMS_DLLAPI int verbose;
207 
209  extern OPENMS_DLLAPI bool all_tests;
210 
212  extern OPENMS_DLLAPI bool test;
213 
215  extern OPENMS_DLLAPI bool this_test;
216 
218  extern OPENMS_DLLAPI int exception;
219 
221  extern OPENMS_DLLAPI std::string exception_name;
222 
224  extern OPENMS_DLLAPI std::string exception_message;
225 
227  extern OPENMS_DLLAPI std::string test_name;
228 
230  extern OPENMS_DLLAPI int start_section_line;
231 
233  extern OPENMS_DLLAPI int test_line;
234 
236  extern OPENMS_DLLAPI const char* version_string;
237 
239  extern OPENMS_DLLAPI std::vector<std::string> tmp_file_list;
240 
242  extern OPENMS_DLLAPI std::vector<UInt> failed_lines_list;
243 
245  extern OPENMS_DLLAPI std::ifstream infile;
246 
248  extern OPENMS_DLLAPI std::ifstream templatefile;
249 
251  extern OPENMS_DLLAPI bool equal_files;
252 
254  extern OPENMS_DLLAPI char line_buffer[65536];
255 
257  extern OPENMS_DLLAPI int test_count;
258 
260  extern OPENMS_DLLAPI std::string add_message;
261 
266  extern OPENMS_DLLAPI std::string fuzzy_message;
267 
269  extern OPENMS_DLLAPI bool newline;
270 
271  template <typename T1, typename T2>
272  void
273  testEqual(const char* /*file*/, int line, const T1& expression_1,
274  const char* expression_1_stringified,
275  const T2& expression_2,
276  const char* expression_2_stringified)
277  {
278  ++test_count;
279  test_line = line;
280  this_test = bool(expression_1 == T1(expression_2));
281  test = test && this_test;
282  {
283  initialNewline();
284  if (this_test)
285  {
286  std__cout << " + line " << line << ": TEST_EQUAL("
287  << expression_1_stringified << ','
288  << expression_2_stringified << "): got " << expression_1
289  << ", expected " << expression_2 << std::endl;
290  }
291  else
292  {
293  std__cout << " - line " << line << ": TEST_EQUAL("
294  << expression_1_stringified << ','
295  << expression_2_stringified << "): got " << expression_1
296  << ", expected " << expression_2 << std::endl;
297  failed_lines_list.push_back(line);
298  }
299  }
300  }
301 
302  template <typename T1, typename T2>
303  void
304  testNotEqual(const char* /*file*/, int line, const T1& expression_1,
305  const char* expression_1_stringified,
306  const T2& expression_2,
307  const char* expression_2_stringified)
308  {
309  ++test_count;
310  test_line = line;
311  this_test = !(expression_1 == T1(expression_2));
312  test = test && this_test;
313  {
314  initialNewline();
315  if (this_test)
316  {
317  std__cout << " + line " << line << ": TEST_NOT_EQUAL("
318  << expression_1_stringified << ','
319  << expression_2_stringified << "): got " << expression_1
320  << ", forbidden is " << expression_2 << std::endl;
321  }
322  else
323  {
324  std__cout << " - line " << line << ": TEST_NOT_EQUAL("
325  << expression_1_stringified << ','
326  << expression_2_stringified << "): got " << expression_1
327  << ", forbidden is " << expression_2 << std::endl;
328  failed_lines_list.push_back(line);
329  }
330  }
331  }
332 
333  }
334  }
335 }
336 
337 // A namespace alias - apparently these cannot be documented using doxygen (?)
339 
364 
365 //@name test and subtest
367 
393 #define START_TEST(class_name, version) \
394  int main(int argc, char** argv) \
395  { \
396  OpenMS::UInt64 seed = 2453440375; \
397  OpenMS::UniqueIdGenerator::setSeed(seed); \
398  TEST::version_string = version; \
399  \
400  if (argc > 1) \
401  { \
402  std::cerr \
403  << "This is " << argv[0] << ", the test program for the\n" \
404  << # class_name " class.\n" \
405  "\n" \
406  "On successful operation it returns PASSED,\n" \
407  "otherwise FAILED is printed.\n"; \
408  return 1; \
409  } \
410  \
411  try {
412 
424 #define END_TEST \
425  /* global try block */ \
426  } \
427  catch (::OpenMS::Exception::BaseException& e) \
428  { \
429  TEST::this_test = false; \
430  TEST::test = false; \
431  TEST::all_tests = false; \
432  { \
433  TEST::initialNewline(); \
434  std__cout << "Error: Caught unexpected OpenMS exception of type '" \
435  << e.getName() \
436  << "'"; \
437  if ((e.getLine() > 0) && (std::strcmp(e.getFile(), "") != 0)) \
438  { \
439  std__cout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
440  << "' in function '" << e.getFunction() << "'"; \
441  } \
442  std__cout << " - Message: " << e.what() << std::endl; \
443  } \
444  } \
445  /* catch std:: exceptions */ \
446  catch (std::exception& e) \
447  { \
448  TEST::this_test = false; \
449  TEST::test = false; \
450  TEST::all_tests = false; \
451  { \
452  TEST::initialNewline(); \
453  std__cout << "Error: Caught unexpected std::exception" << std::endl; \
454  std__cout << " - Message: " << e.what() << std::endl; \
455  } \
456  } \
457  /* catch all other exceptions */ \
458  catch (...) \
459  { \
460  TEST::this_test = false; \
461  TEST::test = false; \
462  TEST::all_tests = false; \
463  { \
464  TEST::initialNewline(); \
465  std__cout << "Error: Caught unidentified and unexpected exception - No message." \
466  << std::endl; \
467  } \
468  } \
469  /* check validity of temporary files if known */ \
470  if (!TEST::validate(TEST::tmp_file_list)) \
471  { \
472  TEST::all_tests = false; \
473  } \
474  /* check for exit code */ \
475  if (!TEST::all_tests) \
476  { \
477  std__cout << "FAILED" << std::endl; \
478  if (TEST::add_message != "") std__cout << "Message: " \
479  << TEST::add_message \
480  << std::endl; \
481  std__cout << "Failed lines: "; \
482  for (OpenMS::Size i = 0; i < TEST::failed_lines_list.size(); ++i) \
483  { \
484  std__cout << TEST::failed_lines_list[i] << " "; \
485  } \
486  std__cout << std::endl; \
487  return 1; \
488  } \
489  else \
490  { \
491  /* remove temporary files*/ \
492  for (OpenMS::Size i = 0; i < TEST::tmp_file_list.size(); ++i) \
493  { \
494  if (!OpenMS::File::remove(TEST::tmp_file_list[i])) \
495  { \
496  std__cout << "Warning: unable to remove temporary file '" \
497  << TEST::tmp_file_list[i] \
498  << "'" \
499  << std::endl; \
500  } \
501  } \
502  std__cout << "PASSED"; \
503  if (TEST::add_message != "") std__cout << " (" << TEST::add_message << ")"; \
504  std__cout << std::endl; \
505  return 0; \
506  } \
507  }
508 
531 #define START_SECTION(name_of_test) \
532  TEST::test = true; \
533  TEST::newline = false; \
534  TEST::test_name = # name_of_test; \
535  TEST::test_count = 0; \
536  TEST::start_section_line = __LINE__; \
537  std__cout << "checking " << TEST::test_name << " ... " << std::flush; \
538  try \
539  { \
540  while (true) \
541  {
542 
568 #define END_SECTION \
569  break; \
570  } \
571  } \
572  catch (::OpenMS::Exception::BaseException& e) \
573  { \
574  TEST::this_test = false; \
575  TEST::test = false; \
576  TEST::all_tests = false; \
577  { \
578  TEST::initialNewline(); \
579  std__cout << "Error: Caught unexpected exception of type '" << e.getName() << "'"; \
580  if ((e.getLine() > 0) && (std::strcmp(e.getFile(), "") != 0)) \
581  { \
582  std__cout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
583  << "' in function '" << e.getFunction() << "'"; \
584  } \
585  std__cout << " - Message: " << e.what() << std::endl; \
586  } \
587  } \
588  /* catch std:: exceptions */ \
589  catch (std::exception& e) \
590  { \
591  TEST::this_test = false; \
592  TEST::test = false; \
593  TEST::all_tests = false; \
594  { \
595  TEST::initialNewline(); \
596  std__cout << "Error: Caught std::exception" << std::endl; \
597  std__cout << " - Message: " << e.what() << std::endl; \
598  } \
599  } \
600  /* catch all other exceptions */ \
601  catch (...) \
602  { \
603  TEST::this_test = false; \
604  TEST::test = false; \
605  TEST::all_tests = false; \
606  { \
607  TEST::initialNewline(); \
608  std__cout << "Error: Caught unidentified and unexpected exception - No message." \
609  << std::endl; \
610  } \
611  } \
612  TEST::all_tests = TEST::all_tests && TEST::test; \
613  { \
614  if (TEST::test) \
615  { \
616  std__cout << ": passed" << std::endl; \
617  } \
618  else \
619  { \
620  std__cout << ": failed" << std::endl; \
621  } \
622  } \
623  /* issue a warning if no tests were performed (unless in destructor)*/ \
624  if (TEST::test_count == 0) \
625  { \
626  bool destructor = false; \
627  for (OpenMS::Size i = 0; i != TEST::test_name.size(); ++i) \
628  { \
629  if (TEST::test_name[i] == '~') \
630  { \
631  destructor = true; \
632  break; \
633  } \
634  } \
635  if (!destructor) std__cout << "Warning: no subtests performed in '" \
636  << TEST::test_name \
637  << "' (line " \
638  << __LINE__ \
639  << ")!" \
640  << std::endl \
641  << std::flush; \
642  } \
643  std__cout << std::endl;
644 
646 
666 #define TEST_EQUAL(a, b) TEST::testEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
667 
679 #define TEST_NOT_EQUAL(a, b) TEST::testNotEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
680 
693 #define TEST_STRING_EQUAL(a, b) TEST::testStringEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
694 
709 #define TEST_FILE_EQUAL(filename, templatename) \
710  { \
711  ++TEST::test_count; \
712  TEST::equal_files = true; \
713  TEST::infile.open(filename, std::ios::in); \
714  TEST::templatefile.open(templatename, std::ios::in); \
715  \
716  if (TEST::infile.good() && TEST::templatefile.good()) \
717  { \
718  std::string TEST_FILE__template_line; \
719  std::string TEST_FILE__line; \
720  \
721  while (TEST::infile.good() && TEST::templatefile.good()) \
722  { \
723  TEST::templatefile.getline(TEST::line_buffer, 65535); \
724  TEST_FILE__template_line = TEST::line_buffer; \
725  TEST::infile.getline(TEST::line_buffer, 65535); \
726  TEST_FILE__line = TEST::line_buffer; \
727  \
728  TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line); \
729  if (TEST_FILE__template_line != TEST_FILE__line) \
730  { \
731  { \
732  TEST::initialNewline(); \
733  std__cout << " TEST_FILE_EQUAL: line mismatch:\n got: '" \
734  << TEST_FILE__line << "'\n expected: '" \
735  << TEST_FILE__template_line << "'" << std::endl; \
736  } \
737  } \
738  } \
739  } \
740  else \
741  { \
742  TEST::equal_files = false; \
743  { \
744  TEST::initialNewline(); \
745  std__cout << " + line " \
746  << __LINE__ \
747  << ": TEST_FILE_EQUAL(" \
748  << # filename \
749  << ", " \
750  << # templatename; \
751  std__cout << ") : " << " cannot open file: \""; \
752  if (!TEST::infile.good()) \
753  { \
754  std__cout << filename << "\" (input file) "; \
755  } \
756  if (!TEST::templatefile.good()) \
757  { \
758  std__cout << templatename << "\" (template file) "; \
759  } \
760  std__cout << std::endl; \
761  \
762  } \
763  } \
764  TEST::infile.close(); \
765  TEST::templatefile.close(); \
766  TEST::infile.clear(); \
767  TEST::templatefile.clear(); \
768  \
769  TEST::this_test = TEST::equal_files; \
770  TEST::test = TEST::test && TEST::this_test; \
771  { \
772  TEST::initialNewline(); \
773  if (TEST::this_test) \
774  { \
775  std__cout << " + line " \
776  << __LINE__ \
777  << ": TEST_FILE_EQUAL(" \
778  << # filename \
779  << ", " \
780  << # templatename \
781  << "): true"; \
782  } \
783  else \
784  { \
785  std__cout << " - line " \
786  << __LINE__ \
787  << ": TEST_FILE_EQUAL(" \
788  << # filename \
789  << ", " \
790  << # templatename \
791  << "): false (different files: " \
792  << filename \
793  << " " \
794  << templatename \
795  << " )\n"; \
796  TEST::failed_lines_list.push_back(TEST::test_line); \
797  } \
798  } \
799  }
800 
816 #define TEST_REAL_SIMILAR(a, b) TEST::testRealSimilar(__FILE__, __LINE__, (a), (# a), TEST::isRealType(a), writtenDigits(a), (b), (# b), TEST::isRealType(b), writtenDigits(b));
817 
833 #define TEST_STRING_SIMILAR(a, b) TEST::testStringSimilar(__FILE__, __LINE__, (a), (# a), (b), (# b));
834 
849 #define TEST_FILE_SIMILAR(a, b) \
850  { \
851  ++TEST::test_count; \
852  TEST::test_line = __LINE__; \
853  TEST::this_test = TEST::isFileSimilar((a), (b)); \
854  TEST::test = TEST::test && TEST::this_test; \
855  { \
856  TEST::initialNewline(); \
857  if (TEST::this_test) \
858  { \
859  std__cout << " + line " << __LINE__ \
860  << ": TEST_FILE_SIMILAR(" # a "," # b "): absolute: " \
861  << precisionWrapper(TEST::absdiff) \
862  << " (" \
863  << precisionWrapper(TEST::absdiff_max_allowed) \
864  << "), relative: " \
865  << precisionWrapper(TEST::ratio) \
866  << " (" \
867  << precisionWrapper(TEST::ratio_max_allowed) \
868  << ")" \
869  << std::endl; \
870  std__cout << "message: \n"; \
871  std__cout << TEST::fuzzy_message; \
872  } \
873  else \
874  { \
875  std__cout << " - line " << TEST::test_line << \
876  ": TEST_FILE_SIMILAR(" # a "," # b ") ... -\n"; \
877  std__cout << "message: \n"; \
878  std__cout << TEST::fuzzy_message; \
879  TEST::failed_lines_list.push_back(TEST::test_line); \
880  } \
881  } \
882  }
883 
896 #define TOLERANCE_RELATIVE(a) \
897  TEST::ratio_max_allowed = (a); \
898  { \
899  TEST::initialNewline(); \
900  std__cout << " + line " << __LINE__ << \
901  ": TOLERANCE_RELATIVE(" << TEST::ratio_max_allowed << \
902  ") (\"" # a "\")" << std::endl; \
903  }
904 
916 #define TOLERANCE_ABSOLUTE(a) \
917  TEST::absdiff_max_allowed = (a); \
918  { \
919  TEST::initialNewline(); \
920  std__cout << " + line " << __LINE__ << \
921  ": TOLERANCE_ABSOLUTE(" << TEST::absdiff_max_allowed << \
922  ") (\"" # a "\")" << std::endl; \
923  }
924 
930 #define WHITELIST(a) TEST::setWhitelist(__FILE__, __LINE__, (a));
931 
944 #define TEST_EXCEPTION(exception_type, command) \
945  { \
946  ++TEST::test_count; \
947  TEST::test_line = __LINE__; \
948  TEST::exception = 0; \
949  try \
950  { \
951  command; \
952  } \
953  catch (exception_type) \
954  { \
955  TEST::exception = 1; \
956  } \
957  catch (::OpenMS::Exception::BaseException e) \
958  { \
959  TEST::exception = 2; \
960  TEST::exception_name = e.getName(); \
961  } \
962  catch (...) \
963  { \
964  TEST::exception = 3; \
965  } \
966  TEST::this_test = (TEST::exception == 1); \
967  TEST::test = TEST::test && TEST::this_test; \
968  \
969  { \
970  TEST::initialNewline(); \
971  switch (TEST::exception) \
972  { \
973  case 0: \
974  std__cout << " - line " << TEST::test_line << \
975  ": TEST_EXCEPTION(" # exception_type "," # command \
976  "): no exception thrown!" << std::endl; \
977  TEST::failed_lines_list.push_back(TEST::test_line); \
978  break; \
979  case 1: \
980  std__cout << " + line " << TEST::test_line << \
981  ": TEST_EXCEPTION(" # exception_type "," # command \
982  "): OK" << std::endl; \
983  break; \
984  case 2: \
985  std__cout << " - line " << TEST::test_line << \
986  ": TEST_EXCEPTION(" # exception_type "," # command \
987  "): wrong exception thrown! \"" \
988  << TEST::exception_name << "\"" << std::endl; \
989  TEST::failed_lines_list.push_back(TEST::test_line); \
990  break; \
991  case 3: \
992  std__cout << " - line " << TEST::test_line << \
993  ": TEST_EXCEPTION(" # exception_type "," # command \
994  "): wrong exception thrown!" << std::endl; \
995  TEST::failed_lines_list.push_back(TEST::test_line); \
996  break; \
997  } \
998  } \
999  }
1000 
1012 #ifdef OPENMS_ASSERTIONS
1013 #define TEST_PRECONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Precondition, command);
1014 #else
1015 #define TEST_PRECONDITION_VIOLATED(command) STATUS("TEST_PRECONDITION_VIOLATED(" # command ") - skipped");
1016 #endif
1017 
1029 #ifdef OPENMS_ASSERTIONS
1030 #define TEST_POSTCONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Postcondition, command);
1031 #else
1032 #define TEST_POSTCONDITION_VIOLATED(command) STATUS("TEST_POSTCONDITION_VIOLATED(" # command ") - skipped");
1033 #endif
1034 
1035 
1052 #define TEST_EXCEPTION_WITH_MESSAGE(exception_type, command, message) \
1053  { \
1054  ++TEST::test_count; \
1055  TEST::test_line = __LINE__; \
1056  TEST::exception = 0; \
1057  try \
1058  { \
1059  command; \
1060  } \
1061  catch (exception_type et) \
1062  { \
1063  if (std::string(et.getMessage()) != std::string(message)) \
1064  { \
1065  TEST::exception = 4; \
1066  TEST::exception_message = et.getMessage(); \
1067  } \
1068  else TEST::exception = 1; \
1069  } \
1070  catch (::OpenMS::Exception::BaseException e) \
1071  { \
1072  TEST::exception = 2; \
1073  TEST::exception_name = e.getName(); \
1074  } \
1075  catch (...) \
1076  { \
1077  TEST::exception = 3; \
1078  } \
1079  TEST::this_test = (TEST::exception == 1); \
1080  TEST::test = TEST::test && TEST::this_test; \
1081  \
1082  { \
1083  TEST::initialNewline(); \
1084  switch (TEST::exception) \
1085  { \
1086  case 0: \
1087  std__cout << " - line " << TEST::test_line << \
1088  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1089  "): no exception thrown!" << std::endl; \
1090  TEST::failed_lines_list.push_back(TEST::test_line); \
1091  break; \
1092  case 1: \
1093  /* this is actually what we want to get: */ \
1094  std__cout << " + line " << TEST::test_line << \
1095  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1096  "): OK" << std::endl; \
1097  break; \
1098  case 2: \
1099  std__cout << " - line " << TEST::test_line << \
1100  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1101  "): wrong exception thrown! \"" << \
1102  TEST::exception_name << "\"" << std::endl; \
1103  TEST::failed_lines_list.push_back(TEST::test_line); \
1104  break; \
1105  case 3: \
1106  std__cout << " - line " << TEST::test_line << \
1107  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1108  "): wrong exception thrown!" << std::endl; \
1109  TEST::failed_lines_list.push_back(TEST::test_line); \
1110  break; \
1111  case 4: \
1112  std__cout << " - line " << TEST::test_line << \
1113  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1114  "): exception has wrong message: got '" << \
1115  TEST::exception_message << \
1116  "', expected '" << \
1117  (message) << \
1118  "'" << std::endl; \
1119  TEST::failed_lines_list.push_back(TEST::test_line); \
1120  break; \
1121  } \
1122  } \
1123  }
1124 
1140 #define NEW_TMP_FILE(filename) \
1141  { \
1142  filename = TEST::tmpFileName(__FILE__, __LINE__); \
1143  TEST::tmp_file_list.push_back(filename); \
1144  { \
1145  TEST::initialNewline(); \
1146  std__cout << " creating new temporary filename '" \
1147  << filename \
1148  << "' (line " \
1149  << __LINE__ \
1150  << ")" \
1151  << std::endl; \
1152  } \
1153  }
1154 
1162 #define ABORT_IF(condition) \
1163  if (condition) \
1164  { \
1165  { \
1166  TEST::initialNewline(); \
1167  std__cout << " - line " << __LINE__ << \
1168  ": ABORT_IF(" # condition "): TEST ABORTED" << \
1169  std::endl; \
1170  TEST::failed_lines_list.push_back(TEST::test_line); \
1171  } \
1172  break; \
1173  }
1174 
1192 #define STATUS(message) \
1193  { \
1194  TEST::initialNewline(); \
1195  std__cout << " line " \
1196  << __LINE__ \
1197  << ": status: " \
1198  << message \
1199  << std::endl; \
1200  }
1201 
1211 #define ADD_MESSAGE(message) \
1212  TEST::add_message = message;
1213 
1223 #define NOT_TESTABLE \
1224  TEST::test_count = 1;
1225 
1227 
1228 #endif //OPENMS_CONCEPT_CLASSTEST_H
double absdiff_max_allowed
Maximum absolute difference of numbers allowed, see TOLERANCE_ABSOLUTE.
int test_count
Counter for the number of elementary tests within the current subsection.
void testStringSimilar(const char *file, int line, const std::string &string_1, const char *string_1_stringified, const std::string &string_2, const char *string_2_stringified)
Compare strings using absdiff_max_allowed and ratio_max_allowed.
std::ifstream templatefile
Template (correct) file used by TEST_FILE_EQUAL.
std::string exception_name
(Used by various macros. Stores the "name" of the exception, if applicable.)
bool newline
(Flags whether a new line is in place, depending on context and verbosity setting. Used by initialNewline() and some macros.)
bool this_test
Status of last elementary test.
std::ifstream infile
Questionable file tested by TEST_FILE_EQUAL.
int start_section_line
Line where current subsection started.
std::vector< std::string > tmp_file_list
List of tmp file names (these will be cleaned up, see NEW_TMP_FILE)
void setWhitelist(const char *const, const int line, const std::string &whitelist)
set the whitelist_
std::string add_message
See ADD_MESSAGE.
double ratio_max
Maximum ratio of numbers observed so far, see TOLERANCE_RELATIVE.
void testEqual(const char *, int line, const T1 &expression_1, const char *expression_1_stringified, const T2 &expression_2, const char *expression_2_stringified)
Definition: ClassTest.h:273
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47
std::string tmpFileName(const std::string &file, int line)
Creates a temporary file name from the test name and the line.
char line_buffer[65536]
(A buffer for one line from a file. Used by TEST_FILE_EQUAL.)
bool isRealType(float)
This overload returns true; float is a floating point type.
Definition: ClassTest.h:90
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition: DataValue.h:57
std::string exception_message
(Used by various macros. Stores the "message" of the exception, if applicable.)
#define std__cout
Provide a point of redirection for testing the test macros, see ClassTest_test.cpp.
Definition: ClassTest.h:66
bool equal_files
(A variable used by TEST_FILE_EQUAL)
void testNotEqual(const char *, int line, const T1 &expression_1, const char *expression_1_stringified, const T2 &expression_2, const char *expression_2_stringified)
Definition: ClassTest.h:304
int exception
(Used by various macros. Indicates a rough category of the exception being caught.)
double ratio
Recent ratio of numbers, see TOLERANCE_RELATIVE.
const char * version_string
Version string supplied with START_TEST.
bool all_tests
Status of the whole test.
int test_line
Line of current elementary test.
void testRealSimilar(const char *file, int line, long double number_1, const char *number_1_stringified, bool number_1_is_realtype, Int number_1_written_digits, long double number_2, const char *number_2_stringified, bool, Int number_2_written_digits)
Compare floating point numbers using absdiff_max_allowed and ratio_max_allowed.
void initialNewline()
make sure we have a newline before results from first subtest
std::string test_name
Name of current subsection.
std::vector< UInt > failed_lines_list
List of all failed lines for summary at the end of the test.
Namespace for class tests.
Definition: ClassTest.h:74
bool isRealSimilar(long double number_1, long double number_2)
used by testRealSimilar()
double absdiff
Recent absolute difference of numbers, see TOLERANCE_ABSOLUTE.
bool isFileSimilar(const std::string &filename_1, const std::string &filename_2)
Compare files using absdiff_max_allowed and ratio_max_allowed.
bool test
Status of the current subsection.
int Int
Signed integer type.
Definition: Types.h:103
double absdiff_max
Maximum difference of numbers observed so far, see TOLERANCE_ABSOLUTE.
bool validate(const std::vector< std::string > &file_names)
Validates the given files against the XML schema (if available)
int verbose
Verbosity level ( "-v" is 1 and "-V" is 2 )
void testStringEqual(const char *file, int line, const std::string &string_1, const char *string_1_stringified, const std::string &string_2, const char *string_2_stringified)
used by TEST_STRING_EQUAL
void printWithPrefix(const std::string &text, const int marked=-1)
print the text, each line gets a prefix, the marked line number gets a special prefix ...
std::string fuzzy_message
Last message from a fuzzy comparison. Written by isRealSimilar(), testStringSimilar(), isFileSimilar(). Read by TEST_REAL_SIMILAR, TEST_STRING_SIMILAR, TEST_FILE_SIMILAR;.
double ratio_max_allowed
Maximum ratio of numbers allowed, see TOLERANCE_RELATIVE.

OpenMS / TOPP release 2.3.0 Documentation generated on Tue Jan 9 2018 18:21:59 using doxygen 1.8.13