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-2013.
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: Stephan Aiche $
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...
42 #include <OpenMS/CONCEPT/Types.h>
45 #include <OpenMS/SYSTEM/File.h>
46 
47 #include <vector>
48 #include <string>
49 #include <cstring>
50 #include <list>
51 #include <iostream>
52 #include <fstream>
53 #include <boost/lexical_cast.hpp>
54 
55 #ifdef OPENMS_HAS_UNISTD_H
56 #include <unistd.h> // unlink()
57 #endif
58 
59 #include <cstdio> // tmpnam()
60 #include <cmath> // fabs
61 #include <cstdlib> // getenv()
62 
63 // Empty declaration to avoid problems in case the namespace is not
64 // yet defined (e.g. TEST/ClassTest_test.C)
65 
67 #ifndef std__cout
68 #define std__cout std::cout
69 #endif
70 
71 namespace OpenMS
72 {
73  namespace Internal
74  {
76  namespace ClassTest
77  {
78 
83  bool OPENMS_DLLAPI
84  validate(const std::vector<std::string>& file_names);
85 
87  std::string OPENMS_DLLAPI
88  tmpFileName(const std::string& file, int line);
89 
91  inline bool OPENMS_DLLAPI
92  isRealType(float)
93  {
94  return true;
95  }
96 
98  inline bool OPENMS_DLLAPI
99  isRealType(double)
100  {
101  return true;
102  }
103 
105  inline bool OPENMS_DLLAPI
106  isRealType(long double)
107  {
108  return true;
109  }
110 
112  inline bool OPENMS_DLLAPI
114  {
115  return true;
116  }
117 
119  template <typename T>
120  inline bool
121  isRealType(const T&)
122  {
123  return false;
124  }
125 
131  void OPENMS_DLLAPI
132  testRealSimilar(const char* file, int line, long double number_1,
133  const char* number_1_stringified,
134  bool number_1_is_realtype, Int number_1_written_digits,
135  long double number_2, const char* number_2_stringified,
136  bool /* number_2_is_realtype */, Int number_2_written_digits);
137 
139  bool OPENMS_DLLAPI
140  isRealSimilar(long double number_1, long double number_2);
141 
149  void OPENMS_DLLAPI
150  testStringSimilar(const char* file, int line,
151  const std::string& string_1,
152  const char* string_1_stringified,
153  const std::string& string_2,
154  const char* string_2_stringified);
155 
157  void OPENMS_DLLAPI
158  testStringEqual(const char* file, int line,
159  const std::string& string_1,
160  const char* string_1_stringified,
161  const std::string& string_2,
162  const char* string_2_stringified);
163 
169  bool OPENMS_DLLAPI
170  isFileSimilar(const std::string& filename_1,
171  const std::string& filename_2);
172 
174  void OPENMS_DLLAPI
175  initialNewline();
176 
178  void OPENMS_DLLAPI
179  printWithPrefix(const std::string& text, const int marked = -1);
180 
182  void OPENMS_DLLAPI
183  setWhitelist(const char* const /* file */, const int line,
184  const std::string& whitelist);
185 
187  extern OPENMS_DLLAPI double ratio_max_allowed;
188 
190  extern OPENMS_DLLAPI double ratio_max;
191 
193  extern OPENMS_DLLAPI double ratio;
194 
196  extern OPENMS_DLLAPI double absdiff_max_allowed;
197 
199  extern OPENMS_DLLAPI double absdiff_max;
200 
202  extern OPENMS_DLLAPI double absdiff;
203 
204  extern OPENMS_DLLAPI int line_num_1_max;
205  extern OPENMS_DLLAPI int line_num_2_max;
206 
208  extern OPENMS_DLLAPI int verbose;
209 
211  extern OPENMS_DLLAPI bool all_tests;
212 
214  extern OPENMS_DLLAPI bool test;
215 
217  extern OPENMS_DLLAPI bool this_test;
218 
220  extern OPENMS_DLLAPI int exception;
221 
223  extern OPENMS_DLLAPI std::string exception_name;
224 
226  extern OPENMS_DLLAPI std::string exception_message;
227 
229  extern OPENMS_DLLAPI std::string test_name;
230 
232  extern OPENMS_DLLAPI int start_section_line;
233 
235  extern OPENMS_DLLAPI int test_line;
236 
238  extern OPENMS_DLLAPI const char* version_string;
239 
241  extern OPENMS_DLLAPI std::vector<std::string> tmp_file_list;
242 
244  extern OPENMS_DLLAPI std::vector<UInt> failed_lines_list;
245 
247  extern OPENMS_DLLAPI std::ifstream infile;
248 
250  extern OPENMS_DLLAPI std::ifstream templatefile;
251 
253  extern OPENMS_DLLAPI bool equal_files;
254 
256  extern OPENMS_DLLAPI char line_buffer[65536];
257 
259  extern OPENMS_DLLAPI int test_count;
260 
262  extern OPENMS_DLLAPI std::string add_message;
263 
268  extern OPENMS_DLLAPI std::string fuzzy_message;
269 
271  extern OPENMS_DLLAPI bool newline;
272 
273  template <typename T1, typename T2>
274  void
275  testEqual(const char* /*file*/, int line, const T1& expression_1,
276  const char* expression_1_stringified,
277  const T2& expression_2,
278  const char* expression_2_stringified)
279  {
280  ++test_count;
281  test_line = line;
282  this_test = bool(expression_1 == T1(expression_2));
283  test = test && this_test;
284  {
285  initialNewline();
286  if (this_test)
287  {
288  std__cout << " + line " << line << ": TEST_EQUAL("
289  << expression_1_stringified << ','
290  << expression_2_stringified << "): got " << expression_1
291  << ", expected " << expression_2 << std::endl;
292  }
293  else
294  {
295  std__cout << " - line " << line << ": TEST_EQUAL("
296  << expression_1_stringified << ','
297  << expression_2_stringified << "): got " << expression_1
298  << ", expected " << expression_2 << std::endl;
299  failed_lines_list.push_back(line);
300  }
301  }
302  }
303 
304  template <typename T1, typename T2>
305  void
306  testNotEqual(const char* /*file*/, int line, const T1& expression_1,
307  const char* expression_1_stringified,
308  const T2& expression_2,
309  const char* expression_2_stringified)
310  {
311  ++test_count;
312  test_line = line;
313  this_test = !(expression_1 == T1(expression_2));
314  test = test && this_test;
315  {
316  initialNewline();
317  if (this_test)
318  {
319  std__cout << " + line " << line << ": TEST_NOT_EQUAL("
320  << expression_1_stringified << ','
321  << expression_2_stringified << "): got " << expression_1
322  << ", forbidden is " << expression_2 << std::endl;
323  }
324  else
325  {
326  std__cout << " - line " << line << ": TEST_NOT_EQUAL("
327  << expression_1_stringified << ','
328  << expression_2_stringified << "): got " << expression_1
329  << ", forbidden is " << expression_2 << std::endl;
330  failed_lines_list.push_back(line);
331  }
332  }
333  }
334 
335  }
336  }
337 }
338 
339 // A namespace alias - apparently these cannot be documented using doxygen (?)
340 namespace TEST = OpenMS::Internal::ClassTest;
341 
366 
367 //@name test and subtest
369 
395 #define START_TEST(class_name, version) \
396  int main(int argc, char** argv) \
397  { \
398  \
399  { \
400  /* initialize the random generator as early as possible! */ \
401  OpenMS::DateTime date_time; \
402  date_time.set("1999-12-31 23:59:59"); \
403  OpenMS::UniqueIdGenerator::setSeed(date_time); \
404  } \
405  \
406  TEST::version_string = version; \
407  \
408  if (argc > 1) \
409  { \
410  std::cerr \
411  << "This is " << argv[0] << ", the test program for the\n" \
412  << # class_name " class.\n" \
413  "\n" \
414  "On successful operation it returns PASSED,\n" \
415  "otherwise FAILED is printed.\n"; \
416  return 1; \
417  } \
418  \
419  try {
420 
432 #define END_TEST \
433  /* global try block */ \
434  } \
435  catch (::OpenMS::Exception::BaseException& e) \
436  { \
437  TEST::this_test = false; \
438  TEST::test = false; \
439  TEST::all_tests = false; \
440  { \
441  TEST::initialNewline(); \
442  std__cout << "Error: Caught unexpected OpenMS exception of type '" \
443  << e.getName() \
444  << "'"; \
445  if ((e.getLine() > 0) && (std::strcmp(e.getFile(), "") != 0)) \
446  { \
447  std__cout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
448  << "' in function '" << e.getFunction() << "'"; \
449  } \
450  std__cout << " - Message: " << e.what() << std::endl; \
451  } \
452  } \
453  /* catch std:: exceptions */ \
454  catch (std::exception& e) \
455  { \
456  TEST::this_test = false; \
457  TEST::test = false; \
458  TEST::all_tests = false; \
459  { \
460  TEST::initialNewline(); \
461  std__cout << "Error: Caught unexpected std::exception" << std::endl; \
462  std__cout << " - Message: " << e.what() << std::endl; \
463  } \
464  } \
465  /* catch all other exceptions */ \
466  catch (...) \
467  { \
468  TEST::this_test = false; \
469  TEST::test = false; \
470  TEST::all_tests = false; \
471  { \
472  TEST::initialNewline(); \
473  std__cout << "Error: Caught unidentified and unexpected exception - No message." \
474  << std::endl; \
475  } \
476  } \
477  /* check validity of temporary files if known */ \
478  if (!TEST::validate(TEST::tmp_file_list)) \
479  { \
480  TEST::all_tests = false; \
481  } \
482  /* check for exit code */ \
483  if (!TEST::all_tests) \
484  { \
485  std__cout << "FAILED" << std::endl; \
486  if (TEST::add_message != "") std__cout << "Message: " \
487  << TEST::add_message \
488  << std::endl; \
489  std__cout << "Failed lines: "; \
490  for (OpenMS::Size i = 0; i < TEST::failed_lines_list.size(); ++i) \
491  { \
492  std__cout << TEST::failed_lines_list[i] << " "; \
493  } \
494  std__cout << std::endl; \
495  return 1; \
496  } \
497  else \
498  { \
499  /* remove temporary files*/ \
500  for (OpenMS::Size i = 0; i < TEST::tmp_file_list.size(); ++i) \
501  { \
502  if (!OpenMS::File::remove(TEST::tmp_file_list[i])) \
503  { \
504  std__cout << "Warning: unable to remove temporary file '" \
505  << TEST::tmp_file_list[i] \
506  << "'" \
507  << std::endl; \
508  } \
509  } \
510  std__cout << "PASSED"; \
511  if (TEST::add_message != "") std__cout << " (" << TEST::add_message << ")"; \
512  std__cout << std::endl; \
513  return 0; \
514  } \
515  }
516 
539 #define START_SECTION(name_of_test) \
540  TEST::test = true; \
541  TEST::newline = false; \
542  TEST::test_name = # name_of_test; \
543  TEST::test_count = 0; \
544  TEST::start_section_line = __LINE__; \
545  std__cout << "checking " << TEST::test_name << " ... " << std::flush; \
546  try \
547  { \
548  while (true) \
549  {
550 
576 #define END_SECTION \
577  break; \
578  } \
579  } \
580  catch (::OpenMS::Exception::BaseException& e) \
581  { \
582  TEST::this_test = false; \
583  TEST::test = false; \
584  TEST::all_tests = false; \
585  { \
586  TEST::initialNewline(); \
587  std__cout << "Error: Caught unexpected exception of type '" << e.getName() << "'"; \
588  if ((e.getLine() > 0) && (std::strcmp(e.getFile(), "") != 0)) \
589  { \
590  std__cout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
591  << "' in function '" << e.getFunction() << "'"; \
592  } \
593  std__cout << " - Message: " << e.what() << std::endl; \
594  } \
595  } \
596  /* catch std:: exceptions */ \
597  catch (std::exception& e) \
598  { \
599  TEST::this_test = false; \
600  TEST::test = false; \
601  TEST::all_tests = false; \
602  { \
603  TEST::initialNewline(); \
604  std__cout << "Error: Caught std::exception" << std::endl; \
605  std__cout << " - Message: " << e.what() << std::endl; \
606  } \
607  } \
608  /* catch all other exceptions */ \
609  catch (...) \
610  { \
611  TEST::this_test = false; \
612  TEST::test = false; \
613  TEST::all_tests = false; \
614  { \
615  TEST::initialNewline(); \
616  std__cout << "Error: Caught unidentified and unexpected exception - No message." \
617  << std::endl; \
618  } \
619  } \
620  TEST::all_tests = TEST::all_tests && TEST::test; \
621  { \
622  if (TEST::test) \
623  { \
624  std__cout << ": passed" << std::endl; \
625  } \
626  else \
627  { \
628  std__cout << ": failed" << std::endl; \
629  } \
630  } \
631  /* issue a warning if no tests were performed (unless in destructor)*/ \
632  if (TEST::test_count == 0) \
633  { \
634  bool destructor = false; \
635  for (OpenMS::Size i = 0; i != TEST::test_name.size(); ++i) \
636  { \
637  if (TEST::test_name[i] == '~') \
638  { \
639  destructor = true; \
640  break; \
641  } \
642  } \
643  if (!destructor) std__cout << "Warning: no subtests performed in '" \
644  << TEST::test_name \
645  << "' (line " \
646  << __LINE__ \
647  << ")!" \
648  << std::endl \
649  << std::flush; \
650  } \
651  std__cout << std::endl;
652 
654 
674 #define TEST_EQUAL(a, b) TEST::testEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
675 
687 #define TEST_NOT_EQUAL(a, b) TEST::testNotEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
688 
701 #define TEST_STRING_EQUAL(a, b) TEST::testStringEqual(__FILE__, __LINE__, (a), (# a), (b), (# b));
702 
717 #define TEST_FILE_EQUAL(filename, templatename) \
718  { \
719  ++TEST::test_count; \
720  TEST::equal_files = true; \
721  TEST::infile.open(filename, std::ios::in); \
722  TEST::templatefile.open(templatename, std::ios::in); \
723  \
724  if (TEST::infile.good() && TEST::templatefile.good()) \
725  { \
726  std::string TEST_FILE__template_line; \
727  std::string TEST_FILE__line; \
728  \
729  while (TEST::infile.good() && TEST::templatefile.good()) \
730  { \
731  TEST::templatefile.getline(TEST::line_buffer, 65535); \
732  TEST_FILE__template_line = TEST::line_buffer; \
733  TEST::infile.getline(TEST::line_buffer, 65535); \
734  TEST_FILE__line = TEST::line_buffer; \
735  \
736  TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line); \
737  if (TEST_FILE__template_line != TEST_FILE__line) \
738  { \
739  { \
740  TEST::initialNewline(); \
741  std__cout << " TEST_FILE_EQUAL: line mismatch:\n got: '" \
742  << TEST_FILE__line << "'\n expected: '" \
743  << TEST_FILE__template_line << "'" << std::endl; \
744  } \
745  } \
746  } \
747  } \
748  else \
749  { \
750  TEST::equal_files = false; \
751  { \
752  TEST::initialNewline(); \
753  std__cout << " + line " \
754  << __LINE__ \
755  << ": TEST_FILE_EQUAL(" \
756  << # filename \
757  << ", " \
758  << # templatename; \
759  std__cout << ") : " << " cannot open file: \""; \
760  if (!TEST::infile.good()) \
761  { \
762  std__cout << filename << "\" (input file) "; \
763  } \
764  if (!TEST::templatefile.good()) \
765  { \
766  std__cout << templatename << "\" (template file) "; \
767  } \
768  std__cout << std::endl; \
769  \
770  } \
771  } \
772  TEST::infile.close(); \
773  TEST::templatefile.close(); \
774  TEST::infile.clear(); \
775  TEST::templatefile.clear(); \
776  \
777  TEST::this_test = TEST::equal_files; \
778  TEST::test = TEST::test && TEST::this_test; \
779  { \
780  TEST::initialNewline(); \
781  if (TEST::this_test) \
782  { \
783  std__cout << " + line " \
784  << __LINE__ \
785  << ": TEST_FILE_EQUAL(" \
786  << # filename \
787  << ", " \
788  << # templatename \
789  << "): true"; \
790  } \
791  else \
792  { \
793  std__cout << " - line " \
794  << __LINE__ \
795  << ": TEST_FILE_EQUAL(" \
796  << # filename \
797  << ", " \
798  << # templatename \
799  << "): false (different files: " \
800  << filename \
801  << " " \
802  << templatename \
803  << " )\n"; \
804  TEST::failed_lines_list.push_back(TEST::test_line); \
805  } \
806  } \
807  }
808 
824 #define TEST_REAL_SIMILAR(a, b) TEST::testRealSimilar(__FILE__, __LINE__, (a), (# a), TEST::isRealType(a), writtenDigits(a), (b), (# b), TEST::isRealType(b), writtenDigits(b));
825 
841 #define TEST_STRING_SIMILAR(a, b) TEST::testStringSimilar(__FILE__, __LINE__, (a), (# a), (b), (# b));
842 
857 #define TEST_FILE_SIMILAR(a, b) \
858  { \
859  ++TEST::test_count; \
860  TEST::test_line = __LINE__; \
861  TEST::this_test = TEST::isFileSimilar((a), (b)); \
862  TEST::test = TEST::test && TEST::this_test; \
863  { \
864  TEST::initialNewline(); \
865  if (TEST::this_test) \
866  { \
867  std__cout << " + line " << __LINE__ \
868  << ": TEST_FILE_SIMILAR(" # a "," # b "): absolute: " \
869  << precisionWrapper(TEST::absdiff) \
870  << " (" \
871  << precisionWrapper(TEST::absdiff_max_allowed) \
872  << "), relative: " \
873  << precisionWrapper(TEST::ratio) \
874  << " (" \
875  << precisionWrapper(TEST::ratio_max_allowed) \
876  << ")" \
877  << std::endl; \
878  std__cout << "message: \n"; \
879  std__cout << TEST::fuzzy_message; \
880  } \
881  else \
882  { \
883  std__cout << " - line " << TEST::test_line << \
884  ": TEST_FILE_SIMILAR(" # a "," # b ") ... -\n"; \
885  std__cout << "message: \n"; \
886  std__cout << TEST::fuzzy_message; \
887  TEST::failed_lines_list.push_back(TEST::test_line); \
888  } \
889  } \
890  }
891 
904 #define TOLERANCE_RELATIVE(a) \
905  TEST::ratio_max_allowed = (a); \
906  { \
907  TEST::initialNewline(); \
908  std__cout << " + line " << __LINE__ << \
909  ": TOLERANCE_RELATIVE(" << TEST::ratio_max_allowed << \
910  ") (\"" # a "\")" << std::endl; \
911  }
912 
924 #define TOLERANCE_ABSOLUTE(a) \
925  TEST::absdiff_max_allowed = (a); \
926  { \
927  TEST::initialNewline(); \
928  std__cout << " + line " << __LINE__ << \
929  ": TOLERANCE_ABSOLUTE(" << TEST::absdiff_max_allowed << \
930  ") (\"" # a "\")" << std::endl; \
931  }
932 
938 #define WHITELIST(a) TEST::setWhitelist(__FILE__, __LINE__, (a));
939 
952 #define TEST_EXCEPTION(exception_type, command) \
953  { \
954  ++TEST::test_count; \
955  TEST::test_line = __LINE__; \
956  TEST::exception = 0; \
957  try \
958  { \
959  command; \
960  } \
961  catch (exception_type) \
962  { \
963  TEST::exception = 1; \
964  } \
965  catch (::OpenMS::Exception::BaseException e) \
966  { \
967  TEST::exception = 2; \
968  TEST::exception_name = e.getName(); \
969  } \
970  catch (...) \
971  { \
972  TEST::exception = 3; \
973  } \
974  TEST::this_test = (TEST::exception == 1); \
975  TEST::test = TEST::test && TEST::this_test; \
976  \
977  { \
978  TEST::initialNewline(); \
979  switch (TEST::exception) \
980  { \
981  case 0: \
982  std__cout << " - line " << TEST::test_line << \
983  ": TEST_EXCEPTION(" # exception_type "," # command \
984  "): no exception thrown!" << std::endl; \
985  TEST::failed_lines_list.push_back(TEST::test_line); \
986  break; \
987  case 1: \
988  std__cout << " + line " << TEST::test_line << \
989  ": TEST_EXCEPTION(" # exception_type "," # command \
990  "): OK" << std::endl; \
991  break; \
992  case 2: \
993  std__cout << " - line " << TEST::test_line << \
994  ": TEST_EXCEPTION(" # exception_type "," # command \
995  "): wrong exception thrown! \"" \
996  << TEST::exception_name << "\"" << std::endl; \
997  TEST::failed_lines_list.push_back(TEST::test_line); \
998  break; \
999  case 3: \
1000  std__cout << " - line " << TEST::test_line << \
1001  ": TEST_EXCEPTION(" # exception_type "," # command \
1002  "): wrong exception thrown!" << std::endl; \
1003  TEST::failed_lines_list.push_back(TEST::test_line); \
1004  break; \
1005  } \
1006  } \
1007  }
1008 
1020 #ifdef OPENMS_ASSERTIONS
1021 #define TEST_PRECONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Precondition, command);
1022 #else
1023 #define TEST_PRECONDITION_VIOLATED(command) STATUS("TEST_PRECONDITION_VIOLATED(" # command ") - skipped");
1024 #endif
1025 
1037 #ifdef OPENMS_ASSERTIONS
1038 #define TEST_POSTCONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Postcondition, command);
1039 #else
1040 #define TEST_POSTCONDITION_VIOLATED(command) STATUS("TEST_POSTCONDITION_VIOLATED(" # command ") - skipped");
1041 #endif
1042 
1043 
1060 #define TEST_EXCEPTION_WITH_MESSAGE(exception_type, command, message) \
1061  { \
1062  ++TEST::test_count; \
1063  TEST::test_line = __LINE__; \
1064  TEST::exception = 0; \
1065  try \
1066  { \
1067  command; \
1068  } \
1069  catch (exception_type et) \
1070  { \
1071  if (std::string(et.getMessage()) != std::string(message)) \
1072  { \
1073  TEST::exception = 4; \
1074  TEST::exception_message = et.getMessage(); \
1075  } \
1076  else TEST::exception = 1; \
1077  } \
1078  catch (::OpenMS::Exception::BaseException e) \
1079  { \
1080  TEST::exception = 2; \
1081  TEST::exception_name = e.getName(); \
1082  } \
1083  catch (...) \
1084  { \
1085  TEST::exception = 3; \
1086  } \
1087  TEST::this_test = (TEST::exception == 1); \
1088  TEST::test = TEST::test && TEST::this_test; \
1089  \
1090  { \
1091  TEST::initialNewline(); \
1092  switch (TEST::exception) \
1093  { \
1094  case 0: \
1095  std__cout << " - line " << TEST::test_line << \
1096  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1097  "): no exception thrown!" << std::endl; \
1098  TEST::failed_lines_list.push_back(TEST::test_line); \
1099  break; \
1100  case 1: \
1101  /* this is actually what we want to get: */ \
1102  std__cout << " + line " << TEST::test_line << \
1103  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1104  "): OK" << std::endl; \
1105  break; \
1106  case 2: \
1107  std__cout << " - line " << TEST::test_line << \
1108  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1109  "): wrong exception thrown! \"" << \
1110  TEST::exception_name << "\"" << std::endl; \
1111  TEST::failed_lines_list.push_back(TEST::test_line); \
1112  break; \
1113  case 3: \
1114  std__cout << " - line " << TEST::test_line << \
1115  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1116  "): wrong exception thrown!" << std::endl; \
1117  TEST::failed_lines_list.push_back(TEST::test_line); \
1118  break; \
1119  case 4: \
1120  std__cout << " - line " << TEST::test_line << \
1121  ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1122  "): exception has wrong message: got '" << \
1123  TEST::exception_message << \
1124  "', expected '" << \
1125  (message) << \
1126  "'" << std::endl; \
1127  TEST::failed_lines_list.push_back(TEST::test_line); \
1128  break; \
1129  } \
1130  } \
1131  }
1132 
1148 #define NEW_TMP_FILE(filename) \
1149  { \
1150  filename = TEST::tmpFileName(__FILE__, __LINE__); \
1151  TEST::tmp_file_list.push_back(filename); \
1152  { \
1153  TEST::initialNewline(); \
1154  std__cout << " creating new temporary filename '" \
1155  << filename \
1156  << "' (line " \
1157  << __LINE__ \
1158  << ")" \
1159  << std::endl; \
1160  } \
1161  }
1162 
1170 #define ABORT_IF(condition) \
1171  if (condition) \
1172  { \
1173  { \
1174  TEST::initialNewline(); \
1175  std__cout << " - line " << __LINE__ << \
1176  ": ABORT_IF(" # condition "): TEST ABORTED" << \
1177  std::endl; \
1178  TEST::failed_lines_list.push_back(TEST::test_line); \
1179  } \
1180  break; \
1181  }
1182 
1200 #define STATUS(message) \
1201  { \
1202  TEST::initialNewline(); \
1203  std__cout << " line " \
1204  << __LINE__ \
1205  << ": status: " \
1206  << message \
1207  << std::endl; \
1208  }
1209 
1219 #define ADD_MESSAGE(message) \
1220  TEST::add_message = message;
1221 
1231 #define NOT_TESTABLE \
1232  TEST::test_count = 1;
1233 
1235 
1236 #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 &quot;name&quot; of the exception, if applicable.)
void setWhitelist(const char *const , const int line, const std::string &whitelist)
set the whitelist_
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)
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:275
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:92
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 &quot;message&quot; of the exception, if applicable.)
#define std__cout
Provide a point of redirection for testing the test macros, see ClassTest_test.C. ...
Definition: ClassTest.h:68
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:306
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.
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:100
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 ( &quot;-v&quot; is 1 and &quot;-V&quot; 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 1.11.1 Documentation generated on Thu Nov 14 2013 11:19:12 using doxygen 1.8.5