1#ifndef BALL_CONCEPT_CLASSTEST_H
2#define BALL_CONCEPT_CLASSTEST_H
35 std::cout << std::endl
36 <<
" (caught unidentified and unexpected exception"
37 << (subtest ?
"" :
" outside a subtest") <<
"!)"
44 std::cout << std::endl
45 <<
" (caught expected STL exception"
46 << (subtest ?
"" :
" outside a subtest")
47 <<
": " << e.what() <<
")"
54 std::cout << std::endl
55 <<
" (caught exception of type "
59 std::cout << (subtest ?
"" :
" outside a subtest")
60 <<
", which was thrown in line "
63 std::cout <<
" - unexpected!) "
72 std::cout << std::endl
73 <<
" (caught exception of type "
77 std::cout << (subtest ?
"" :
" outside a subtest")
78 <<
", which was thrown in line "
81 std::cout <<
" while looking for file " << e.
getFilename()
97 std::cout << std::endl;
112#define PRECISION(a) \
113 TEST::precision = (a);
128#define START_TEST(class_name)\
130int main(int argc, char **argv)\
134 if (!strcmp(argv[1], "-v"))\
136 if (!strcmp(argv[1], "-V"))\
140 if ((argc > 2) || ((argc == 2) && (TEST::verbose == 0))) {\
141 std::cerr << "Checks " #class_name " class" << std::endl;\
143 std::cerr << "On successful operation it simply returns OK," << std::endl;\
144 std::cerr << "otherwise FAILURE is printed." << std::endl;\
145 std::cerr << "If called with an argument of -v, " << argv[0] << " prints detailed" << std::endl;\
146 std::cerr << "information about individual tests." << std::endl;\
147 std::cerr << "Option -V provides verbose information on" << std::endl;\
148 std::cerr << "every subtest." << std::endl;\
152 if (TEST::verbose > 0)\
153 std::cout << "Version: " << TEST::version_string << std::endl;\
171 catch (BALL::Exception::FileNotFound& e) { TEST::printException(e, false); }\
172 catch (BALL::Exception::GeneralException& e) { TEST::printException(e, false); }\
173 catch (std::exception& e) { TEST::printException(e, false); }\
174 catch (...) { TEST::printException(0, false); }\
177 while (TEST::tmp_file_list.size() > 0 && TEST::verbose < 1)\
179 ::BALL::File::remove(TEST::tmp_file_list.back().c_str());\
180 TEST::tmp_file_list.pop_back();\
183 std::cout << (TEST::all_tests ? "PASSED" : "FAILED") << std::endl;\
184 return !TEST::all_tests;\
202#define CHECK(test_name) \
204 TEST::newline = false;\
205 if (TEST::verbose > 0)\
206 std::cout << "checking " << #test_name << "... " << std::flush;\
225#define STATUS(message)\
226 if (TEST::verbose > 1)\
228 if (!TEST::newline) \
230 TEST::newline = true;\
231 std::cout << std::endl;\
233 std::cout << " status (line " << __LINE__ << "): " << message << std::endl;\
259 catch (BALL::Exception::FileNotFound& e) { TEST::printException(e, true); }\
260 catch (::BALL::Exception::GeneralException& e) { TEST::printException(e, true); }\
261 catch (std::exception& e) { TEST::printException(e, true); }\
262 catch (...) { TEST::printException(0, true); }\
264 TEST::all_tests = TEST::all_tests && TEST::test;\
265 if (TEST::verbose > 0){\
268 std::cout << (TEST::test ? "passed" : "FAILED") << std::endl;\
276#define SLEEP_FOR_MSECS(ms) std::this_thread::sleep_for(std::chrono::milliseconds(ms))
285#define NEW_TMP_FILE(filename)\
286 ::BALL::File::createTemporaryFilename(filename);\
287 TEST::tmp_file_list.push_back(filename);\
288 if (TEST::verbose > 1)\
290 if (!TEST::newline) \
292 TEST::newline = true;\
293 std::cout << std::endl;\
295 std::cout << " creating new temporary file '" << filename << "' (line " << __LINE__ << ")" << std::endl;\
305#define NEW_TMP_FILE_WITH_SUFFIX(filename, suffix)\
306 ::BALL::File::createTemporaryFilename(filename, suffix);\
307 TEST::tmp_file_list.push_back(filename);\
308 if (TEST::verbose > 1)\
310 if (!TEST::newline) \
312 TEST::newline = true;\
313 std::cout << std::endl;\
315 std::cout << " creating new temporary file '" << filename << "' (line " << __LINE__ << ")" << std::endl;\
325#define TEST_REAL_EQUAL(a,b) \
326 TEST::this_test = fabs((a) - (b)) < TEST::precision; \
327 TEST::test = TEST::test && TEST::this_test;\
328 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
332 TEST::newline = true;\
333 std::cout << std::endl;\
335 std::cout << " (line " << __LINE__ << " TEST_REAL_EQUAL("<< #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\
336 std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
349#define TEST_EQUAL(a,b) \
351 TEST::this_test = ((a) == (b));\
352 TEST::test = TEST::test && TEST::this_test;\
353 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
357 TEST::newline = true;\
358 std::cout << std::endl;\
360 std::cout << " (line " << __LINE__ << " TEST_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\
361 std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
373#define TEST_NOT_EQUAL(a,b) \
375 TEST::this_test = !((a) == (b));\
376 TEST::test = TEST::test && TEST::this_test;\
377 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
381 TEST::newline = true;\
382 std::cout << std::endl;\
384 std::cout << " (line " << __LINE__ << " TEST_NOT_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", forbidden is " << (b) << ") ";\
385 std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
399#define TEST_EXCEPTION(exception_type, command) \
401 TEST::exception = 0;\
406 catch (exception_type&)\
408 TEST::exception = 1;\
410 catch (::BALL::Exception::GeneralException& e)\
412 TEST::exception = 2;\
413 TEST::exception_name = e.getName();\
417 TEST::exception = 3;\
419 TEST::this_test = (TEST::exception == 1);\
420 TEST::test = TEST::test && TEST::this_test;\
422 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
426 TEST::newline = true;\
427 std::cout << std::endl;\
429 std::cout << " (line " << __LINE__ << " TEST_EXCEPTION(" << #exception_type << ", " << #command << "): ";\
430 switch (TEST::exception)\
432 case 0: std::cout << " ERROR: no exception!) "; break;\
433 case 1: std::cout << " OK) "; break;\
434 case 2: std::cout << " ERROR: wrong exception: " << TEST::exception_name << ") "; break;\
435 case 3: std::cout << " ERROR: wrong exception!) "; break;\
437 std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
450#define TEST_PRECONDITION_EXCEPTION(command) \
452 TEST::exception = 0;\
457 catch (Exception::Precondition&)\
459 TEST::exception = 1;\
461 catch (::BALL::Exception::GeneralException& e)\
463 TEST::exception = 2;\
464 TEST::exception_name = e.getName();\
468 TEST::exception = 3;\
470 TEST::this_test = (TEST::exception == 1);\
471 TEST::test = TEST::test && TEST::this_test;\
473 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
477 TEST::newline = true;\
478 std::cout << std::endl;\
480 std::cout << " (line " << __LINE__ << " TEST_PRECONDITION_EXCEPTION(" << ", " << #command << "): ";\
481 switch (TEST::exception)\
483 case 0: std::cout << " ERROR: no exception!) "; break;\
484 case 1: std::cout << " OK) "; break;\
485 case 2: std::cout << " ERROR: wrong exception: " << TEST::exception_name << ") "; break;\
486 case 3: std::cout << " ERROR: wrong exception!) "; break;\
488 std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
494# define TEST_PRECONDITION_EXCEPTION(command)\
495 if (TEST::verbose > 1)\
497 std::cout << " TEST_EXCEPTION_PRECONDITION(" #command ") : (DEBUG mode disabled!)" << std::endl;\
507#define ABORT_IF(condition) \
508 if (condition) break;
517#define TEST_FILE(filename, templatename) \
519 TEST::equal_files = true;\
520 TEST::infile.open(filename, std::ios::in);\
521 TEST::templatefile.open(templatename, std::ios::in);\
523 if (TEST::infile.good() && TEST::templatefile.good())\
525 String TEST_FILE__template_line;\
526 String TEST_FILE__line;\
528 while (TEST::infile.good() && TEST::templatefile.good())\
530 TEST_FILE__template_line.getline(TEST::templatefile);\
531 TEST_FILE__line.getline(TEST::infile);\
533 TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line);\
534 if (TEST_FILE__template_line != TEST_FILE__line)\
536 if (TEST::verbose > 0)\
540 TEST::newline = true;\
541 std::cout << std::endl;\
544 std::cout << " TEST_FILE: line mismatch:\n got: '" << TEST_FILE__line << "'\n expected: '" << TEST_FILE__template_line << "'" << std::endl;\
549 TEST::equal_files = false;\
551 if (TEST::verbose > 0)\
555 TEST::newline = true;\
556 std::cout << std::endl;\
559 std::cout << " (line " << __LINE__ << ": TEST_FILE(" << #filename << ", " << #templatename ;\
560 std::cout << ") : " << " cannot open file: \"";\
561 if (!TEST::infile.good())\
563 std::cout << filename << "\" (input file) ";\
565 if (!TEST::templatefile.good())\
567 std::cout << templatename << "\" (template file) ";\
569 std::cout << std::endl;\
573 TEST::infile.close();\
574 TEST::templatefile.close();\
575 TEST::infile.clear();\
576 TEST::templatefile.clear();\
578 TEST::this_test = TEST::equal_files;\
579 TEST::test = TEST::test && TEST::this_test;\
580 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
584 TEST::newline = true;\
585 std::cout << std::endl;\
587 std::cout << " (line " << __LINE__ << ": TEST_FILE("<< #filename << ", " << #templatename << "): ";\
588 std::cout << (TEST::this_test ? "true + " : "false - ") << std::endl;\
601#define TEST_FILE_REGEXP(filename, templatename) \
603 TEST::equal_files = true;\
604 TEST::infile.open(filename, std::ios::in);\
605 TEST::templatefile.open(templatename, std::ios::in);\
607 if (TEST::infile.good() && TEST::templatefile.good())\
609 String TEST_FILE__template_line;\
610 String TEST_FILE__line;\
612 while (TEST::infile.good() && TEST::templatefile.good())\
614 TEST_FILE__template_line.getline(TEST::templatefile);\
615 TEST_FILE__line.getline(TEST::infile);\
617 if ((TEST_FILE__template_line.size() > 0) && (TEST_FILE__template_line[0] == '/') && (TEST_FILE__template_line[1] != '/'))\
619 RegularExpression expression(TEST_FILE__template_line(1));\
620 bool match = expression.match(TEST_FILE__line);\
621 TEST::equal_files &= match;\
624 if (TEST::verbose > 0)\
628 TEST::newline = true;\
629 std::cout << std::endl;\
632 std::cout << " TEST_FILE_REGEXP: regexp mismatch: " << TEST_FILE__line << " did not match " << TEST_FILE__template_line(1) << "." << std::endl;\
636 TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line);\
637 if (TEST_FILE__template_line != TEST_FILE__line)\
639 if (TEST::verbose > 0)\
643 TEST::newline = true;\
644 std::cout << std::endl;\
647 std::cout << " TEST_FILE: line mismatch:\n got: '" << TEST_FILE__line << "'\n expected: '" << TEST_FILE__template_line << "'" << std::endl;\
653 TEST::equal_files = false;\
655 if (TEST::verbose > 0)\
659 TEST::newline = true;\
660 std::cout << std::endl;\
663 std::cout << " (line " << __LINE__ << ": TEST_FILE_REGEXP(" << #filename << ", " << #templatename ;\
664 std::cout << ") : " << " cannot open file: \"";\
665 if (!TEST::infile.good())\
667 std::cout << filename << "\" (input file) ";\
669 if (!TEST::templatefile.good())\
671 std::cout << templatename << "\" (template file) ";\
673 std::cout << std::endl;\
677 TEST::infile.close();\
678 TEST::templatefile.close();\
679 TEST::infile.clear();\
680 TEST::templatefile.clear();\
682 TEST::this_test = TEST::equal_files;\
683 TEST::test = TEST::test && TEST::this_test;\
684 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
688 TEST::newline = true;\
689 std::cout << std::endl;\
691 std::cout << " (line " << __LINE__ << ": TEST_FILE_REGEXP("<< #filename << ", " << #templatename << "): ";\
692 std::cout << (TEST::this_test ? "true + " : "false - ") << std::endl;\
709#define CAPTURE_OUTPUT_LEVEL(level) \
711 std::ostringstream TEST_strstr;\
712 Log.remove(std::cout);\
713 Log.remove(std::cerr);\
714 Log.insert(TEST_strstr, level, level);
728#define CAPTURE_OUTPUT_LEVEL_RANGE(minlevel, maxlevel) \
730 std::ostringstream TEST_strstr;\
731 Log.remove(std::cout);\
732 Log.remove(std::cerr);\
733 Log.insert(TEST_strstr, minlevel, maxlevel);
739#define COMPARE_OUTPUT(text) \
740 Log.remove(TEST_strstr);\
741 Log.insert(std::cout, LogStream::INFORMATION_LEVEL, LogStream::ERROR_LEVEL - 1);\
742 Log.insert(std::cerr, LogStream::ERROR_LEVEL);\
743 TEST::this_test = (::strncmp(TEST_strstr.str().c_str(), text, TEST_strstr.str().size()) == 0);\
744 TEST::test = TEST::test && TEST::this_test;\
746 if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
749 char* TEST_strstr_contents = new char[TEST_strstr.str().size() + 1];\
750 ::strncpy(TEST_strstr_contents, TEST_strstr.str().c_str(), TEST_strstr.str().size());\
751 TEST_strstr_contents[TEST_strstr.str().size()] = '\0';\
755 TEST::newline = true;\
756 std::cout << std::endl;\
758 std::cout << " (line " << __LINE__ << " COMPARE_OUTPUT(" << #text << "): got '" << (TEST_strstr_contents) << "', expected '" << (text) << ") ";\
759 std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
760 delete [] TEST_strstr_contents;\
void printException(T e, bool subtest)
const char * version_string
void printErrorMessage(BALL::Exception::FileNotFound &e, bool subtest)
list< string > tmp_file_list
std::ifstream templatefile
const char * getFile() const
Returns the file where it occurred.
int getLine() const
Returns the line number where it occurred.
const char * getMessage() const
Returns the error message of the exception.
const char * getName() const
Returns the name of the exception.
String getFilename() const