| OpenMS 2.5.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-2020.
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...
41 #include <OpenMS/CONCEPT/PrecisionWrapper.h>
42 #include <OpenMS/CONCEPT/Types.h>
43 #include <OpenMS/CONCEPT/UniqueIdGenerator.h>
44 #include <OpenMS/DATASTRUCTURES/DataValue.h>
45 #include <OpenMS/DATASTRUCTURES/DateTime.h>
46 #include <OpenMS/CONCEPT/MacrosTest.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 stdcout
66 #define stdcout 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
111 isRealType(const DataValue&)
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 stdcout << " + line " << line << ": TEST_EQUAL("
287 << expression_1_stringified << ','
288 << expression_2_stringified << "): got '" << expression_1
289 << "', expected '" << expression_2 << "'\n";
290 }
291 else
292 {
293 stdcout << " - line " << line << ": TEST_EQUAL("
294 << expression_1_stringified << ','
295 << expression_2_stringified << "): got '" << expression_1
296 << "', expected '" << expression_2 << "'\n";
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 stdcout << " + line " << line << ": TEST_NOT_EQUAL("
318 << expression_1_stringified << ','
319 << expression_2_stringified << "): got '" << expression_1
320 << "', forbidden is '" << expression_2 << "'\n";
321 }
322 else
323 {
324 stdcout << " - line " << line << ": TEST_NOT_EQUAL("
325 << expression_1_stringified << ','
326 << expression_2_stringified << "): got '" << expression_1
327 << "', forbidden is '" << expression_2 << "'\n";
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 (?)
338 namespace TEST = OpenMS::Internal::ClassTest;
339
364
365 //@name test and subtest
367
392 #define START_TEST(class_name, version) \
393 int main(int argc, char** argv) \
394 { \
395 OpenMS::UInt64 seed = 2453440375; \
396 OpenMS::UniqueIdGenerator::setSeed(seed); \
397 TEST::version_string = version; \
398 \
399 if (argc > 1) \
400 { \
401 std::cerr \
402 << "This is " << argv[0] << ", the test program for the\n" \
403 << # class_name " class.\n" \
404 "\n" \
405 "On successful operation it returns PASSED,\n" \
406 "otherwise FAILED is printed.\n"; \
407 return 1; \
408 } \
409 \
410 try {
411
423 #define END_TEST \
424 /* global try block */ \
425 } \
426 catch (::OpenMS::Exception::BaseException& e) \
427 { \
428 TEST::this_test = false; \
429 TEST::test = false; \
430 TEST::all_tests = false; \
431 { \
432 TEST::initialNewline(); \
433 stdcout << "Error: Caught unexpected OpenMS exception of type '" \
434 << e.getName() \
435 << "'"; \
436 if ((e.getLine() > 0) && std::strcmp(e.getFile(), "")) \
437 { \
438 stdcout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
439 << "' in function '" << e.getFunction() << "'"; \
440 } \
441 stdcout << " - Message: " << e.what() << std::endl; \
442 } \
443 } \
444 /* catch std:: exceptions */ \
445 catch (std::exception& e) \
446 { \
447 TEST::this_test = false; \
448 TEST::test = false; \
449 TEST::all_tests = false; \
450 { \
451 TEST::initialNewline(); \
452 stdcout << "Error: Caught unexpected std::exception" << std::endl; \
453 stdcout << " - Message: " << e.what() << std::endl; \
454 } \
455 } \
456 /* catch all other exceptions */ \
457 catch (...) \
458 { \
459 TEST::this_test = false; \
460 TEST::test = false; \
461 TEST::all_tests = false; \
462 { \
463 TEST::initialNewline(); \
464 stdcout << "Error: Caught unidentified and unexpected exception - No message." \
465 << std::endl; \
466 } \
467 } \
468 /* check validity of temporary files if known */ \
469 if (!TEST::validate(TEST::tmp_file_list)) \
470 { \
471 TEST::all_tests = false; \
472 } \
473 /* check for exit code */ \
474 if (!TEST::all_tests) \
475 { \
476 stdcout << "FAILED" << std::endl; \
477 if (TEST::add_message != "") stdcout << "Message: " \
478 << TEST::add_message \
479 << std::endl; \
480 stdcout << "Failed lines: "; \
481 for (OpenMS::Size i = 0; i < TEST::failed_lines_list.size(); ++i) \
482 { \
483 stdcout << TEST::failed_lines_list[i] << " "; \
484 } \
485 stdcout << std::endl; \
486 return 1; \
487 } \
488 else \
489 { \
490 /* remove temporary files*/ \
491 for (OpenMS::Size i = 0; i < TEST::tmp_file_list.size(); ++i) \
492 { \
493 if (!OpenMS::File::remove(TEST::tmp_file_list[i])) \
494 { \
495 stdcout << "Warning: unable to remove temporary file '" \
496 << TEST::tmp_file_list[i] \
497 << "'" \
498 << std::endl; \
499 } \
500 } \
501 stdcout << "PASSED"; \
502 if (TEST::add_message != "") stdcout << " (" << TEST::add_message << ")"; \
503 stdcout << std::endl; \
504 return 0; \
505 } \
506 }
507
530 #define START_SECTION(name_of_test) \
531 TEST::test = true; \
532 TEST::newline = false; \
533 TEST::test_name = # name_of_test; \
534 TEST::test_count = 0; \
535 TEST::start_section_line = __LINE__; \
536 stdcout << "checking " << TEST::test_name << " ... " << std::flush; \
537 try \
538 { \
539 while (true) \
540 {
541
567 #define END_SECTION \
568 break; \
569 } \
570 } \
571 catch (::OpenMS::Exception::BaseException& e) \
572 { \
573 TEST::this_test = false; \
574 TEST::test = false; \
575 TEST::all_tests = false; \
576 { \
577 TEST::initialNewline(); \
578 stdcout << "Error: Caught unexpected exception of type '" << e.getName() << "'"; \
579 if ((e.getLine() > 0) && (std::strcmp(e.getFile(), "") != 0)) \
580 { \
581 stdcout << " thrown in line " << e.getLine() << " of file '" << e.getFile() \
582 << "' in function '" << e.getFunction() << "'"; \
583 } \
584 stdcout << " - Message: " << e.what() << std::endl; \
585 } \
586 } \
587 /* catch std:: exceptions */ \
588 catch (std::exception& e) \
589 { \
590 TEST::this_test = false; \
591 TEST::test = false; \
592 TEST::all_tests = false; \
593 { \
594 TEST::initialNewline(); \
595 stdcout << "Error: Caught std::exception" << std::endl; \
596 stdcout << " - Message: " << e.what() << std::endl; \
597 } \
598 } \
599 /* catch all other exceptions */ \
600 catch (...) \
601 { \
602 TEST::this_test = false; \
603 TEST::test = false; \
604 TEST::all_tests = false; \
605 { \
606 TEST::initialNewline(); \
607 stdcout << "Error: Caught unidentified and unexpected exception - No message." \
608 << std::endl; \
609 } \
610 } \
611 TEST::all_tests = TEST::all_tests && TEST::test; \
612 { \
613 if (TEST::test) \
614 { \
615 stdcout << ": passed" << std::endl; \
616 } \
617 else \
618 { \
619 stdcout << ": failed" << std::endl; \
620 } \
621 } \
622 /* issue a warning if no tests were performed (unless in destructor)*/ \
623 if (TEST::test_count == 0) \
624 { \
625 bool destructor = false; \
626 for (OpenMS::Size i = 0; i != TEST::test_name.size(); ++i) \
627 { \
628 if (TEST::test_name[i] == '~') \
629 { \
630 destructor = true; \
631 break; \
632 } \
633 } \
634 if (!destructor) stdcout << "Warning: no subtests performed in '" \
635 << TEST::test_name \
636 << "' (line " \
637 << __LINE__ \
638 << ")!" \
639 << std::endl; \
640 } \
641 stdcout << 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::test_line = __LINE__; \
711 \
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 stdcout << " TEST_FILE_EQUAL: line mismatch:\n got: '" \
734 << TEST_FILE__line << "'\n expected: '" \
735 << TEST_FILE__template_line << "'\n"; \
736 } \
737 } \
738 } \
739 } \
740 else \
741 { \
742 TEST::equal_files = false; \
743 { \
744 TEST::initialNewline(); \
745 stdcout << " + line " \
746 << __LINE__ \
747 << ": TEST_FILE_EQUAL(" \
748 << # filename \
749 << ", " \
750 << # templatename; \
751 stdcout << ") : " << " cannot open file: \""; \
752 if (!TEST::infile.good()) \
753 { \
754 stdcout << filename << "\" (input file) "; \
755 } \
756 if (!TEST::templatefile.good()) \
757 { \
758 stdcout << templatename << "\" (template file) "; \
759 } \
760 stdcout << "'\n"; \
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 stdcout << " + line " \
776 << __LINE__ \
777 << ": TEST_FILE_EQUAL(" \
778 << # filename \
779 << ", " \
780 << # templatename \
781 << "): true"; \
782 } \
783 else \
784 { \
785 stdcout << " - 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 stdcout << " + 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 << ")\n"; \
869 stdcout << "message: \n"; \
870 stdcout << TEST::fuzzy_message; \
871 } \
872 else \
873 { \
874 stdcout << " - line " << TEST::test_line << \
875 ": TEST_FILE_SIMILAR(" # a "," # b ") ... -\n"; \
876 stdcout << "message: \n"; \
877 stdcout << TEST::fuzzy_message; \
878 TEST::failed_lines_list.push_back(TEST::test_line); \
879 } \
880 } \
881 }
882
895 #define TOLERANCE_RELATIVE(a) \
896 TEST::ratio_max_allowed = (a); \
897 { \
898 TEST::initialNewline(); \
899 stdcout << " + line " << __LINE__ << \
900 ": TOLERANCE_RELATIVE(" << TEST::ratio_max_allowed << \
901 ") (\"" # a "\")\n"; \
902 }
903
915 #define TOLERANCE_ABSOLUTE(a) \
916 TEST::absdiff_max_allowed = (a); \
917 { \
918 TEST::initialNewline(); \
919 stdcout << " + line " << __LINE__ << \
920 ": TOLERANCE_ABSOLUTE(" << TEST::absdiff_max_allowed << \
921 ") (\"" # a "\")\n"; \
922 }
923
929 #define WHITELIST(a) TEST::setWhitelist(__FILE__, __LINE__, (a));
930
943 #define TEST_EXCEPTION(exception_type, command) \
944 { \
945 ++TEST::test_count; \
946 TEST::test_line = __LINE__; \
947 TEST::exception = 0; \
948 try \
949 { \
950 command; \
951 } \
952 catch (exception_type&) \
953 { \
954 TEST::exception = 1; \
955 } \
956 catch (::OpenMS::Exception::BaseException& e) \
957 { \
958 TEST::exception = 2; \
959 TEST::exception_name = e.getName(); \
960 } \
961 catch (...) \
962 { \
963 TEST::exception = 3; \
964 } \
965 TEST::this_test = (TEST::exception == 1); \
966 TEST::test = TEST::test && TEST::this_test; \
967 \
968 { \
969 TEST::initialNewline(); \
970 switch (TEST::exception) \
971 { \
972 case 0: \
973 stdcout << " - line " << TEST::test_line << \
974 ": TEST_EXCEPTION(" # exception_type "," # command \
975 "): no exception thrown!\n"; \
976 TEST::failed_lines_list.push_back(TEST::test_line); \
977 break; \
978 case 1: \
979 stdcout << " + line " << TEST::test_line << \
980 ": TEST_EXCEPTION(" # exception_type "," # command \
981 "): OK\n"; \
982 break; \
983 case 2: \
984 stdcout << " - line " << TEST::test_line << \
985 ": TEST_EXCEPTION(" # exception_type "," # command \
986 "): wrong exception thrown! \"" \
987 << TEST::exception_name << "\"\n"; \
988 TEST::failed_lines_list.push_back(TEST::test_line); \
989 break; \
990 case 3: \
991 stdcout << " - line " << TEST::test_line << \
992 ": TEST_EXCEPTION(" # exception_type "," # command \
993 "): wrong exception thrown!\n"; \
994 TEST::failed_lines_list.push_back(TEST::test_line); \
995 break; \
996 } \
997 } \
998 }
999
1011 #ifdef OPENMS_ASSERTIONS
1012 #define TEST_PRECONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Precondition, command);
1013 #else
1014 #define TEST_PRECONDITION_VIOLATED(command) STATUS("TEST_PRECONDITION_VIOLATED(" # command ") - skipped");
1015 #endif
1016
1028 #ifdef OPENMS_ASSERTIONS
1029 #define TEST_POSTCONDITION_VIOLATED(command) TEST_EXCEPTION(Exception::Postcondition, command);
1030 #else
1031 #define TEST_POSTCONDITION_VIOLATED(command) STATUS("TEST_POSTCONDITION_VIOLATED(" # command ") - skipped");
1032 #endif
1033
1034
1051 #define TEST_EXCEPTION_WITH_MESSAGE(exception_type, command, message) \
1052 { \
1053 ++TEST::test_count; \
1054 TEST::test_line = __LINE__; \
1055 TEST::exception = 0; \
1056 try \
1057 { \
1058 command; \
1059 } \
1060 catch (exception_type& et) \
1061 { \
1062 if (std::string(et.getMessage()) != std::string(message)) \
1063 { \
1064 TEST::exception = 4; \
1065 TEST::exception_message = et.getMessage(); \
1066 } \
1067 else TEST::exception = 1; \
1068 } \
1069 catch (::OpenMS::Exception::BaseException& e) \
1070 { \
1071 TEST::exception = 2; \
1072 TEST::exception_name = e.getName(); \
1073 } \
1074 catch (...) \
1075 { \
1076 TEST::exception = 3; \
1077 } \
1078 TEST::this_test = (TEST::exception == 1); \
1079 TEST::test = TEST::test && TEST::this_test; \
1080 \
1081 { \
1082 TEST::initialNewline(); \
1083 switch (TEST::exception) \
1084 { \
1085 case 0: \
1086 stdcout << " - line " << TEST::test_line << \
1087 ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1088 "): no exception thrown!\n"; \
1089 TEST::failed_lines_list.push_back(TEST::test_line); \
1090 break; \
1091 case 1: \
1092 /* this is actually what we want to get: */ \
1093 stdcout << " + line " << TEST::test_line << \
1094 ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1095 "): OK\n"; \
1096 break; \
1097 case 2: \
1098 stdcout << " - line " << TEST::test_line << \
1099 ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1100 "): wrong exception thrown! \"" << \
1101 TEST::exception_name << "\"\n"; \
1102 TEST::failed_lines_list.push_back(TEST::test_line); \
1103 break; \
1104 case 3: \
1105 stdcout << " - line " << TEST::test_line << \
1106 ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1107 "): wrong exception thrown!\n"; \
1108 TEST::failed_lines_list.push_back(TEST::test_line); \
1109 break; \
1110 case 4: \
1111 stdcout << " - line " << TEST::test_line << \
1112 ": TEST_EXCEPTION_WITH_MESSAGE(" # exception_type "," # command ", " # message \
1113 "): exception has wrong message: got '" << \
1114 TEST::exception_message << \
1115 "', expected '" << \
1116 (message) << "'\n"; \
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 stdcout << " creating new temporary filename '" \
1145 << filename \
1146 << "' (line " \
1147 << __LINE__ \
1148 << ")\n"; \
1149 } \
1150 }
1151
1159 #define ABORT_IF(condition) \
1160 if (condition) \
1161 { \
1162 { \
1163 TEST::initialNewline(); \
1164 stdcout << " - line " << __LINE__ << \
1165 ": ABORT_IF(" # condition "): TEST ABORTED\n"; \
1166 TEST::failed_lines_list.push_back(TEST::test_line); \
1167 } \
1168 break; \
1169 }
1170
1188 #define STATUS(message) \
1189 { \
1190 TEST::initialNewline(); \
1191 stdcout << " line " \
1192 << __LINE__ \
1193 << ": status: " \
1194 << message \
1195 << "\n"; \
1196 }
1197
1207 #define ADD_MESSAGE(message) \
1208 TEST::add_message = message;
1209
1219 #define NOT_TESTABLE \
1220 TEST::test_count = 1;
1221
1223
OpenMS::Internal::ClassTest::absdiff_max_allowed
double absdiff_max_allowed
Maximum absolute difference of numbers allowed, see TOLERANCE_ABSOLUTE.
OpenMS::Internal::ClassTest::line_buffer
char line_buffer[65536]
(A buffer for one line from a file. Used by TEST_FILE_EQUAL.)
OpenMS::Internal::ClassTest::test_line
int test_line
Line of current elementary test.
OpenMS::DataValue
Class to hold strings, numeric values, lists of strings and lists of numeric values.
Definition: DataValue.h:56
OpenMS::Internal::ClassTest::testRealSimilar
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.
OpenMS::Internal::ClassTest::printWithPrefix
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 ...
UniqueIdGenerator.h
OpenMS::Internal::ClassTest::testStringEqual
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
OpenMS::Internal::ClassTest::version_string
const char * version_string
Version string supplied with START_TEST.
OpenMS::Internal::ClassTest::isFileSimilar
bool isFileSimilar(const std::string &filename_1, const std::string &filename_2)
Compare files using absdiff_max_allowed and ratio_max_allowed.
OpenMS::Internal::ClassTest::testEqual
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
OpenMS::Internal::ClassTest::testStringSimilar
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.
MacrosTest.h
OpenMS::Internal::ClassTest::templatefile
std::ifstream templatefile
Template (correct) file used by TEST_FILE_EQUAL.
OpenMS::Internal::ClassTest::verbose
int verbose
Verbosity level ( "-v" is 1 and "-V" is 2 )
OpenMS::Internal::ClassTest::ratio_max_allowed
double ratio_max_allowed
Maximum ratio of numbers allowed, see TOLERANCE_RELATIVE.
OpenMS::Internal::ClassTest::test_count
int test_count
Counter for the number of elementary tests within the current subsection.
OpenMS::Internal::ClassTest::validate
bool validate(const std::vector< std::string > &file_names)
Validates the given files against the XML schema (if available)
OpenMS::Internal::ClassTest::exception_name
std::string exception_name
(Used by various macros. Stores the "name" of the exception, if applicable.)
Types.h
OpenMS::Internal::ClassTest::testNotEqual
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
OpenMS::Internal::ClassTest::test
bool test
Status of the current subsection.
OpenMS::Internal::ClassTest
Namespace for class tests.
Definition: ClassTest.h:74
OpenMS::Internal::ClassTest::fuzzy_message
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;.
OpenMS::Internal::ClassTest::line_num_2_max
int line_num_2_max
OpenMS::Internal::ClassTest::tmp_file_list
std::vector< std::string > tmp_file_list
List of tmp file names (these will be cleaned up, see NEW_TMP_FILE)
PrecisionWrapper.h
OpenMS::Internal::ClassTest::exception_message
std::string exception_message
(Used by various macros. Stores the "message" of the exception, if applicable.)
OpenMS::Internal::ClassTest::isRealType
bool isRealType(float)
This overload returns true; float is a floating point type.
Definition: ClassTest.h:90
DateTime.h
OpenMS
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:46
OpenMS::Internal::ClassTest::equal_files
bool equal_files
(A variable used by TEST_FILE_EQUAL)
OpenMS::Internal::ClassTest::line_num_1_max
int line_num_1_max
OpenMS::Internal::ClassTest::failed_lines_list
std::vector< UInt > failed_lines_list
List of all failed lines for summary at the end of the test.
OpenMS::Internal::ClassTest::infile
std::ifstream infile
Questionable file tested by TEST_FILE_EQUAL.
OpenMS::Internal::ClassTest::newline
bool newline
(Flags whether a new line is in place, depending on context and verbosity setting. Used by initialNewline() and some macros.)
OpenMS::Internal::ClassTest::isRealSimilar
bool isRealSimilar(long double number_1, long double number_2)
used by testRealSimilar()
OpenMS::Internal::ClassTest::this_test
bool this_test
Status of last elementary test.
OpenMS::Internal::ClassTest::tmpFileName
std::string tmpFileName(const std::string &file, int line)
Creates a temporary file name from the test name and the line.
OpenMS::Internal::ClassTest::test_name
std::string test_name
Name of current subsection.
int
OpenMS::Internal::ClassTest::initialNewline
void initialNewline()
make sure we have a newline before results from first subtest
OpenMS::Internal::ClassTest::absdiff_max
double absdiff_max
Maximum difference of numbers observed so far, see TOLERANCE_ABSOLUTE.
File.h
OpenMS::Internal::ClassTest::start_section_line
int start_section_line
Line where current subsection started.
DataValue.h
OpenMS::Internal::ClassTest::setWhitelist
void setWhitelist(const char *const, const int line, const std::string &whitelist)
set the whitelist_
OpenMS::Internal::ClassTest::ratio_max
double ratio_max
Maximum ratio of numbers observed so far, see TOLERANCE_RELATIVE.
OpenMS::Internal::ClassTest::add_message
std::string add_message
See ADD_MESSAGE.
stdcout
#define stdcout
Provide a point of redirection for testing the test macros, see ClassTest_test.cpp.
Definition: ClassTest.h:66
OpenMS::Internal::ClassTest::ratio
double ratio
Recent ratio of numbers, see TOLERANCE_RELATIVE.
OpenMS::Internal::ClassTest::all_tests
bool all_tests
Status of the whole test.
OpenMS::Internal::ClassTest::absdiff
double absdiff
Recent absolute difference of numbers, see TOLERANCE_ABSOLUTE.
OpenMS::Internal::ClassTest::exception
int exception
(Used by various macros. Indicates a rough category of the exception being caught.)