OpenMS  2.4.0
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-2018.
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 #pragma once
36 
37 // Avoid OpenMS includes here at all costs
38 // When the included headers are changed, *all* tests have to be recompiled!
39 // Use the ClassTest class if you need add high-level functionality.
40 // Includes in the C-file are ok...
42 #include <OpenMS/CONCEPT/Types.h>
46 #include <OpenMS/SYSTEM/File.h>
47 #include <OpenMS/OpenMSConfig.h>
48 #include <OpenMS/config.h>
49 
50 #include <cmath> // fabs
51 #include <cstdio> // tmpnam()
52 #include <cstdlib> // getenv()
53 #include <cstring>
54 #include <fstream>
55 #include <iostream>
56 #include <list>
57 #include <string>
58 #include <vector>
59 
60 // Empty declaration to avoid problems in case the namespace is not
61 // yet defined (e.g. TEST/ClassTest_test.cpp)
62 
64 #ifndef std__cout
65 #define std__cout std::cout
66 #endif
67 
68 namespace OpenMS
69 {
70  namespace Internal
71  {
73  namespace ClassTest
74  {
75 
80  bool OPENMS_DLLAPI
81  validate(const std::vector<std::string>& file_names);
82 
84  std::string OPENMS_DLLAPI
85  tmpFileName(const std::string& file, int line);
86 
88  inline bool OPENMS_DLLAPI
89  isRealType(float)
90  {
91  return true;
92  }
93 
95  inline bool OPENMS_DLLAPI
96  isRealType(double)
97  {
98  return true;
99  }
100 
102  inline bool OPENMS_DLLAPI
103  isRealType(long double)
104  {
105  return true;
106  }
107 
109  inline bool OPENMS_DLLAPI
111  {
112  return true;
113  }
114 
116  template <typename T>
117  inline bool
118  isRealType(const T&)
119  {
120  return false;
121  }
122 
128  void OPENMS_DLLAPI
129  testRealSimilar(const char* file, int line, long double number_1,
130  const char* number_1_stringified,
131  bool number_1_is_realtype, Int number_1_written_digits,
132  long double number_2, const char* number_2_stringified,
133  bool /* number_2_is_realtype */, Int number_2_written_digits);
134 
136  bool OPENMS_DLLAPI
137  isRealSimilar(long double number_1, long double number_2);
138 
146  void OPENMS_DLLAPI
147  testStringSimilar(const char* file, int line,
148  const std::string& string_1,
149  const char* string_1_stringified,
150  const std::string& string_2,
151  const char* string_2_stringified);
152 
154  void OPENMS_DLLAPI
155  testStringEqual(const char* file, int line,
156  const std::string& string_1,
157  const char* string_1_stringified,
158  const std::string& string_2,
159  const char* string_2_stringified);
160 
166  bool OPENMS_DLLAPI
167  isFileSimilar(const std::string& filename_1,
168  const std::string& filename_2);
169 
171  void OPENMS_DLLAPI
172  initialNewline();
173 
175  void OPENMS_DLLAPI
176  printWithPrefix(const std::string& text, const int marked = -1);
177 
179  void OPENMS_DLLAPI
180  setWhitelist(const char* const /* file */, const int line,
181  const std::string& whitelist);
182 
184  extern OPENMS_DLLAPI double ratio_max_allowed;
185 
187  extern OPENMS_DLLAPI double ratio_max;
188 
190  extern OPENMS_DLLAPI double ratio;
191 
193  extern OPENMS_DLLAPI double absdiff_max_allowed;
194 
196  extern OPENMS_DLLAPI double absdiff_max;
197 
199  extern OPENMS_DLLAPI double absdiff;
200 
201  extern OPENMS_DLLAPI int line_num_1_max;
202  extern OPENMS_DLLAPI int line_num_2_max;
203 
205  extern OPENMS_DLLAPI int verbose;
206 
208  extern OPENMS_DLLAPI bool all_tests;
209 
211  extern OPENMS_DLLAPI bool test;
212 
214  extern OPENMS_DLLAPI bool this_test;
215 
217  extern OPENMS_DLLAPI int exception;
218 
220  extern OPENMS_DLLAPI std::string exception_name;
221 
223  extern OPENMS_DLLAPI std::string exception_message;
224 
226  extern OPENMS_DLLAPI std::string test_name;
227 
229  extern OPENMS_DLLAPI int start_section_line;
230 
232  extern OPENMS_DLLAPI int test_line;
233 
235  extern OPENMS_DLLAPI const char* version_string;
236 
238  extern OPENMS_DLLAPI std::vector<std::string> tmp_file_list;
239 
241  extern OPENMS_DLLAPI std::vector<UInt> failed_lines_list;
242 
244  extern OPENMS_DLLAPI std::ifstream infile;
245 
247  extern OPENMS_DLLAPI std::ifstream templatefile;
248 
250  extern OPENMS_DLLAPI bool equal_files;
251 
253  extern OPENMS_DLLAPI char line_buffer[65536];
254 
256  extern OPENMS_DLLAPI int test_count;
257 
259  extern OPENMS_DLLAPI std::string add_message;
260 
265  extern OPENMS_DLLAPI std::string fuzzy_message;
266 
268  extern OPENMS_DLLAPI bool newline;
269 
270  template <typename T1, typename T2>
271  void
272  testEqual(const char* /*file*/, int line, const T1& expression_1,
273  const char* expression_1_stringified,
274  const T2& expression_2,
275  const char* expression_2_stringified)
276  {
277  ++test_count;
278  test_line = line;
279  this_test = bool(expression_1 == T1(expression_2));
280  test = test && this_test;
281  {
282  initialNewline();
283  if (this_test)
284  {
285  std__cout << " + line " << line << ": TEST_EQUAL("
286  << expression_1_stringified << ','
287  << expression_2_stringified << "): got " << expression_1
288  << ", expected " << expression_2 << std::endl;
289  }
290  else
291  {
292  std__cout << " - line " << line << ": TEST_EQUAL("
293  << expression_1_stringified << ','
294  << expression_2_stringified << "): got " << expression_1
295  << ", expected " << expression_2 << std::endl;
296  failed_lines_list.push_back(line);
297  }
298  }
299  }
300 
301  template <typename T1, typename T2>
302  void
303  testNotEqual(const char* /*file*/, int line, const T1& expression_1,
304  const char* expression_1_stringified,
305  const T2& expression_2,
306  const char* expression_2_stringified)
307  {
308  ++test_count;
309  test_line = line;
310  this_test = !(expression_1 == T1(expression_2));
311  test = test && this_test;
312  {
313  initialNewline();
314  if (this_test)
315  {
316  std__cout << " + line " << line << ": TEST_NOT_EQUAL("
317  << expression_1_stringified << ','
318  << expression_2_stringified << "): got " << expression_1
319  << ", forbidden is " << expression_2 << std::endl;
320  }
321  else
322  {
323  std__cout << " - line " << line << ": TEST_NOT_EQUAL("
324  << expression_1_stringified << ','
325  << expression_2_stringified << "): got " << expression_1
326  << ", forbidden is " << expression_2 << std::endl;
327  failed_lines_list.push_back(line);
328  }
329  }
330  }
331 
332  }
333  }
334 }
335 
336 // A namespace alias - apparently these cannot be documented using doxygen (?)
338 
363 
364 //@name test and subtest
366 
391 #define START_TEST(class_name, version) \
392  int main(int argc, char** argv) \
393  { \
394  OpenMS::UInt64 seed = 2453440375; \
395  OpenMS::UniqueIdGenerator::setSeed(seed); \
396  TEST::version_string = version; \
397  \
398  if (argc > 1) \
399  { \
400  std::cerr \
401  << "This is " << argv[0] << ", the test program for the\n" \
402  << # class_name " class.\n" \
403  "\n" \
404  "On successful operation it returns PASSED,\n" \
405  "otherwise FAILED is printed.\n"; \
406  return 1; \
407  } \
408  \
409  try {
410 
422 #define END_TEST \
423  /* global try block */ \
424  } \
425  catch (::OpenMS::Exception::BaseException& e) \
426  { \
427  TEST::this_test = false; \
428  TEST::test = false; \
429  TEST::all_tests = false; \
430  { \
431  TEST::initialNewline(); \
432  std__cout << "Error: Caught unexpected OpenMS exception of type '" \
433  << e.getName() \
434  << "'"; \
435  if ((e.getLine() > 0) && (std::strcmp(e.getFile(), "") != 0)) \
436  { \
437  std__cout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
438  << "' in function '" << e.getFunction() << "'"; \
439  } \
440  std__cout << " - Message: " << e.what() << std::endl; \
441  } \
442  } \
443  /* catch std:: exceptions */ \
444  catch (std::exception& e) \
445  { \
446  TEST::this_test = false; \
447  TEST::test = false; \
448  TEST::all_tests = false; \
449  { \
450  TEST::initialNewline(); \
451  std__cout << "Error: Caught unexpected std::exception" << std::endl; \
452  std__cout << " - Message: " << e.what() << std::endl; \
453  } \
454  } \
455  /* catch all other exceptions */ \
456  catch (...) \
457  { \
458  TEST::this_test = false; \
459  TEST::test = false; \
460  TEST::all_tests = false; \
461  { \
462  TEST::initialNewline(); \
463  std__cout << "Error: Caught unidentified and unexpected exception - No message." \
464  << std::endl; \
465  } \
466  } \
467  /* check validity of temporary files if known */ \
468  if (!TEST::validate(TEST::tmp_file_list)) \
469  { \
470  TEST::all_tests = false; \
471  } \
472  /* check for exit code */ \
473  if (!TEST::all_tests) \
474  { \
475  std__cout << "FAILED" << std::endl; \
476  if (TEST::add_message != "") std__cout << "Message: " \
477  << TEST::add_message \
478  << std::endl; \
479  std__cout << "Failed lines: "; \
480  for (OpenMS::Size i = 0; i < TEST::failed_lines_list.size(); ++i) \
481  { \
482  std__cout << TEST::failed_lines_list[i] << " "; \
483  } \
484  std__cout << std::endl; \
485  return 1; \
486  } \
487  else \
488  { \
489  /* remove temporary files*/ \
490  for (OpenMS::Size i = 0; i < TEST::tmp_file_list.size(); ++i) \
491  { \
492  if (!OpenMS::File::remove(TEST::tmp_file_list[i])) \
493  { \
494  std__cout << "Warning: unable to remove temporary file '" \
495  << TEST::tmp_file_list[i] \
496  << "'" \
497  << std::endl; \
498  } \
499  } \
500  std__cout << "PASSED"; \
501  if (TEST::add_message != "") std__cout << " (" << TEST::add_message << ")"; \
502  std__cout << std::endl; \
503  return 0; \
504  } \
505  }
506 
529 #define START_SECTION(name_of_test) \
530  TEST::test = true; \
531  TEST::newline = false; \
532  TEST::test_name = # name_of_test; \
533  TEST::test_count = 0; \
534  TEST::start_section_line = __LINE__; \
535  std__cout << "checking " << TEST::test_name << " ... " << std::flush; \
536  try \
537  { \
538  while (true) \
539  {
540 
566 #define END_SECTION \
567  break; \
568  } \
569  } \
570  catch (::OpenMS::Exception::BaseException& e) \
571  { \
572  TEST::this_test = false; \
573  TEST::test = false; \
574  TEST::all_tests = false; \
575  { \
576  TEST::initialNewline(); \
577  std__cout << "Error: Caught unexpected exception of type '" << e.getName() << "'"; \
578  if ((e.getLine() > 0) && (std::strcmp(e.getFile(), "") != 0)) \
579  { \
580  std__cout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
581  << "' in function '" << e.getFunction() << "'"; \
582  } \
583  std__cout << " - Message: " << e.what() << std::endl; \
584  } \
585  } \
586  /* catch std:: exceptions */ \
587  catch (std::exception& e) \
588  { \
589  TEST::this_test = false; \
590  TEST::test = false; \
591  TEST::all_tests = false; \
592  { \
593  TEST::initialNewline(); \
594  std__cout << "Error: Caught std::exception" << std::endl; \
595  std__cout << " - Message: " << e.what() << std::endl; \
596  } \
597  } \
598  /* catch all other exceptions */ \
599  catch (...) \
600  { \
601  TEST::this_test = false; \
602  TEST::test = false; \
603  TEST::all_tests = false; \
604  { \
605  TEST::initialNewline(); \
606  std__cout << "Error: Caught unidentified and unexpected exception - No message." \
607  << std::endl; \
608  } \
609  } \
610  TEST::all_tests = TEST::all_tests && TEST::test; \
611  { \
612  if (TEST::test) \
613  { \
614  std__cout << ": passed" << std::endl; \
615  } \
616  else \
617  { \
618  std__cout << ": failed" << std::endl; \
619  } \
620  } \
621  /* issue a warning if no tests were performed (unless in destructor)*/ \
622  if (TEST::test_count == 0) \
623  { \
624  bool destructor = false; \
625  for (OpenMS::Size i = 0; i != TEST::test_name.size(); ++i) \
626  { \
627  if (TEST::test_name[i] == '~') \
628  { \
629  destructor = true; \
630  break; \
631  } \
632  } \
633  if (!destructor) std__cout << "Warning: no subtests performed in '" \
634  << TEST::test_name \
635  << "' (line " \
636  << __LINE__ \
637  << ")!" \
638  << std::endl \
639  << std::flush; \
640  } \
641  std__cout << std::endl;
642 
644 
664 #define TEST_EQUAL(a, b) TEST::testEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
665 
677 #define TEST_NOT_EQUAL(a, b) TEST::testNotEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
678 
691 #define TEST_STRING_EQUAL(a, b) TEST::testStringEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
692 
707 #define TEST_FILE_EQUAL(filename, templatename) \
708  { \
709  ++TEST::test_count; \
710  TEST::equal_files = true; \
711  TEST::infile.open(filename, std::ios::in); \
712  TEST::templatefile.open(templatename, std::ios::in); \
713  \
714  if (TEST::infile.good() && TEST::templatefile.good()) \
715  { \
716  std::string TEST_FILE__template_line; \
717  std::string TEST_FILE__line; \
718  \
719  while (TEST::infile.good() && TEST::templatefile.good()) \
720  { \
721  TEST::templatefile.getline(TEST::line_buffer, 65535); \
722  TEST_FILE__template_line = TEST::line_buffer; \
723  TEST::infile.getline(TEST::line_buffer, 65535); \
724  TEST_FILE__line = TEST::line_buffer; \
725  \
726  TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line); \
727  if (TEST_FILE__template_line != TEST_FILE__line) \
728  { \
729  { \
730  TEST::initialNewline(); \
731  std__cout << " TEST_FILE_EQUAL: line mismatch:\n got: '" \
732  << TEST_FILE__line << "'\n expected: '" \
733  << TEST_FILE__template_line << "'" << std::endl; \
734  } \
735  } \
736  } \
737  } \
738  else \
739  { \
740  TEST::equal_files = false; \
741  { \
742  TEST::initialNewline(); \
743  std__cout << " + line " \
744  << __LINE__ \
745  << ": TEST_FILE_EQUAL(" \
746  << # filename \
747  << ", " \
748  << # templatename; \
749  std__cout << ") : " << " cannot open file: \""; \
750  if (!TEST::infile.good()) \
751  { \
752  std__cout << filename << "\" (input file) "; \
753  } \
754  if (!TEST::templatefile.good()) \
755  { \
756  std__cout << templatename << "\" (template file) "; \
757  } \
758  std__cout << std::endl; \
759  \
760  } \
761  } \
762  TEST::infile.close(); \
763  TEST::templatefile.close(); \
764  TEST::infile.clear(); \
765  TEST::templatefile.clear(); \
766  \
767  TEST::this_test = TEST::equal_files; \
768  TEST::test = TEST::test && TEST::this_test; \
769  { \
770  TEST::initialNewline(); \
771  if (TEST::this_test) \
772  { \
773  std__cout << " + line " \
774  << __LINE__ \
775  << ": TEST_FILE_EQUAL(" \
776  << # filename \
777  << ", " \
778  << # templatename \
779  << "): true"; \
780  } \
781  else \
782  { \
783  std__cout << " - line " \
784  << __LINE__ \
785  << ": TEST_FILE_EQUAL(" \
786  << # filename \
787  << ", " \
788  << # templatename \
789  << "): false (different files: " \
790  << filename \
791  << " " \
792  << templatename \
793  << " )\n"; \
794  TEST::failed_lines_list.push_back(TEST::test_line); \
795  } \
796  } \
797  }
798 
814 #define TEST_REAL_SIMILAR(a, b) TEST::testRealSimilar(__FILE__, __LINE__, (a), (# a), TEST::isRealType(a), writtenDigits(a), (b), (# b), TEST::isRealType(b), writtenDigits(b));
815 
831 #define TEST_STRING_SIMILAR(a, b) TEST::testStringSimilar(__FILE__, __LINE__, (a), (# a), (b), (# b));
832 
847 #define TEST_FILE_SIMILAR(a, b) \
848  { \
849  ++TEST::test_count; \
850  TEST::test_line = __LINE__; \
851  TEST::this_test = TEST::isFileSimilar((a), (b)); \
852  TEST::test = TEST::test && TEST::this_test; \
853  { \
854  TEST::initialNewline(); \
855  if (TEST::this_test) \
856  { \
857  std__cout << " + line " << __LINE__ \
858  << ": TEST_FILE_SIMILAR(" # a "," # b "): absolute: " \
859  << precisionWrapper(TEST::absdiff) \
860  << " (" \
861  << precisionWrapper(TEST::absdiff_max_allowed) \
862  << "), relative: " \
863  << precisionWrapper(TEST::ratio) \
864  << " (" \
865  << precisionWrapper(TEST::ratio_max_allowed) \
866  << ")" \
867  << std::endl; \
868  std__cout << "message: \n"; \
869  std__cout << TEST::fuzzy_message; \
870  } \
871  else \
872  { \
873  std__cout << " - line " << TEST::test_line << \
874  ": TEST_FILE_SIMILAR(" # a "," # b ") ... -\n"; \
875  std__cout << "message: \n"; \
876  std__cout << TEST::fuzzy_message; \
877  TEST::failed_lines_list.push_back(TEST::test_line); \
878  } \
879  } \
880  }
881 
894 #define TOLERANCE_RELATIVE(a) \
895  TEST::ratio_max_allowed = (a); \
896  { \
897  TEST::initialNewline(); \
898  std__cout << " + line " << __LINE__ << \
899  ": TOLERANCE_RELATIVE(" << TEST::ratio_max_allowed << \
900  ") (\"" # a "\")" << std::endl; \
901  }
902 
914 #define TOLERANCE_ABSOLUTE(a) \
915  TEST::absdiff_max_allowed = (a); \
916  { \
917  TEST::initialNewline(); \
918  std__cout << " + line " << __LINE__ << \
919  ": TOLERANCE_ABSOLUTE(" << TEST::absdiff_max_allowed << \
920  ") (\"" # a "\")" << std::endl; \
921  }
922 
928 #define WHITELIST(a) TEST::setWhitelist(__FILE__, __LINE__, (a));
929 
942 #define TEST_EXCEPTION(exception_type, command) \
943  { \
944  ++TEST::test_count; \
945  TEST::test_line = __LINE__; \
946  TEST::exception = 0; \
947  try \
948  { \
949  command; \
950  } \
951  catch (exception_type) \
952  { \
953  TEST::exception = 1; \
954  } \
955  catch (::OpenMS::Exception::BaseException e) \
956  { \
957  TEST::exception = 2; \
958  TEST::exception_name = e.getName(); \
959  } \
960  catch (...) \
961  { \
962  TEST::exception = 3; \
963  } \
964  TEST::this_test = (TEST::exception == 1); \
965  TEST::test = TEST::test && TEST::this_test; \
966  \
967  { \
968  TEST::initialNewline(); \
969  switch (TEST::exception) \
970  { \
971  case 0: \
972  std__cout << " - line " << TEST::test_line << \
973  ": TEST_EXCEPTION(" # exception_type "," # command \
974  "): no exception thrown!" << std::endl; \
975  TEST::failed_lines_list.push_back(TEST::test_line); \
976  break; \
977  case 1: \
978  std__cout << " + line " << TEST::test_line << \
979  ": TEST_EXCEPTION(" # exception_type "," # command \
980  "): OK" << std::endl; \
981  break; \
982  case 2: \
983  std__cout << " - line " << TEST::test_line << \
984  ": TEST_EXCEPTION(" # exception_type "," # command \
985  "): wrong exception thrown! \"" \
986  << TEST::exception_name << "\"" << std::endl; \
987  TEST::failed_lines_list.push_back(TEST::test_line); \
988  break; \
989  case 3: \
990  std__cout << " - line " << TEST::test_line << \
991  ": TEST_EXCEPTION(" # exception_type "," # command \
992  "): wrong exception thrown!" << std::endl; \
993  TEST::failed_lines_list.push_back(TEST::test_line); \
994  break; \
995  } \
996  } \
997  }
998 
1010 #ifdef OPENMS_ASSERTIONS
1011 #define TEST_PRECONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Precondition, command);
1012 #else
1013 #define TEST_PRECONDITION_VIOLATED(command) STATUS("TEST_PRECONDITION_VIOLATED(" # command ") - skipped");
1014 #endif
1015 
1027 #ifdef OPENMS_ASSERTIONS
1028 #define TEST_POSTCONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Postcondition, command);
1029 #else
1030 #define TEST_POSTCONDITION_VIOLATED(command) STATUS("TEST_POSTCONDITION_VIOLATED(" # command ") - skipped");
1031 #endif
1032 
1033 
1050 #define TEST_EXCEPTION_WITH_MESSAGE(exception_type, command, message) \
1051  { \
1052  ++TEST::test_count; \
1053  TEST::test_line = __LINE__; \
1054  TEST::exception = 0; \
1055  try \
1056  { \
1057  command; \
1058  } \
1059  catch (exception_type et) \
1060  { \
1061  if (std::string(et.getMessage()) != std::string(message)) \
1062  { \
1063  TEST::exception = 4; \
1064  TEST::exception_message = et.getMessage(); \
1065  } \
1066  else TEST::exception = 1; \
1067  } \
1068  catch (::OpenMS::Exception::BaseException e) \
1069  { \
1070  TEST::exception = 2; \
1071  TEST::exception_name = e.getName(); \
1072  } \
1073  catch (...) \
1074  { \
1075  TEST::exception = 3; \
1076  } \
1077  TEST::this_test = (TEST::exception == 1); \
1078  TEST::test = TEST::test && TEST::this_test; \
1079  \
1080  { \
1081  TEST::initialNewline(); \
1082  switch (TEST::exception) \
1083  { \
1084  case 0: \
1085  std__cout << " - line " << TEST::test_line << \
1086  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1087  "): no exception thrown!" << std::endl; \
1088  TEST::failed_lines_list.push_back(TEST::test_line); \
1089  break; \
1090  case 1: \
1091  /* this is actually what we want to get: */ \
1092  std__cout << " + line " << TEST::test_line << \
1093  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1094  "): OK" << std::endl; \
1095  break; \
1096  case 2: \
1097  std__cout << " - line " << TEST::test_line << \
1098  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1099  "): wrong exception thrown! \"" << \
1100  TEST::exception_name << "\"" << std::endl; \
1101  TEST::failed_lines_list.push_back(TEST::test_line); \
1102  break; \
1103  case 3: \
1104  std__cout << " - line " << TEST::test_line << \
1105  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1106  "): wrong exception thrown!" << std::endl; \
1107  TEST::failed_lines_list.push_back(TEST::test_line); \
1108  break; \
1109  case 4: \
1110  std__cout << " - line " << TEST::test_line << \
1111  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1112  "): exception has wrong message: got '" << \
1113  TEST::exception_message << \
1114  "', expected '" << \
1115  (message) << \
1116  "'" << std::endl; \
1117  TEST::failed_lines_list.push_back(TEST::test_line); \
1118  break; \
1119  } \
1120  } \
1121  }
1122 
1138 #define NEW_TMP_FILE(filename) \
1139  { \
1140  filename = TEST::tmpFileName(__FILE__, __LINE__); \
1141  TEST::tmp_file_list.push_back(filename); \
1142  { \
1143  TEST::initialNewline(); \
1144  std__cout << " creating new temporary filename '" \
1145  << filename \
1146  << "' (line " \
1147  << __LINE__ \
1148  << ")" \
1149  << std::endl; \
1150  } \
1151  }
1152 
1160 #define ABORT_IF(condition) \
1161  if (condition) \
1162  { \
1163  { \
1164  TEST::initialNewline(); \
1165  std__cout << " - line " << __LINE__ << \
1166  ": ABORT_IF(" # condition "): TEST ABORTED" << \
1167  std::endl; \
1168  TEST::failed_lines_list.push_back(TEST::test_line); \
1169  } \
1170  break; \
1171  }
1172 
1190 #define STATUS(message) \
1191  { \
1192  TEST::initialNewline(); \
1193  std__cout << " line " \
1194  << __LINE__ \
1195  << ": status: " \
1196  << message \
1197  << std::endl; \
1198  }
1199 
1209 #define ADD_MESSAGE(message) \
1210  TEST::add_message = message;
1211 
1221 #define NOT_TESTABLE \
1222  TEST::test_count = 1;
1223 
1225 
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:272
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:46
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:89
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition: DataValue.h:56
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:65
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:303
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:73
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:102
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.