Loading...
Searching...
No Matches
classTest.h
Go to the documentation of this file.
#ifndef BALL_CONCEPT_CLASSTEST_H
#define BALL_CONCEPT_CLASSTEST_H
#include <BALL/CONCEPT/autoDeletable.h>
#include <BALL/SYSTEM/file.h>
#include <BALL/DATATYPE/regularExpression.h>
#include <chrono>
#include <cmath>
#include <list>
#include <string>
#include <thread>
/* define a special namespace for all internal variables */\
/* to avoid potential collisions */\
namespace TEST
{
int verbose = 0;
bool all_tests = true;
bool test = true;
bool this_test;
int exception = 0;
string exception_name = "";
const char* version_string = BALL_RELEASE_STRING;
bool newline = false;
list<string> tmp_file_list;
std::ifstream infile;
std::ifstream templatefile;
bool equal_files;
double precision = 1e-6;
template<class T>
void printErrorMessage(T &, bool subtest)
{
std::cout << std::endl
<< " (caught unidentified and unexpected exception"
<< (subtest ? "" : " outside a subtest") << "!)"
<< std::endl;
}
template<>
void printErrorMessage(std::exception& e, bool subtest)
{
std::cout << std::endl
<< " (caught expected STL exception"
<< (subtest ? "" : " outside a subtest")
<< ": " << e.what() << ")"
<< std::endl;
}
template<>
void printErrorMessage(BALL::Exception::GeneralException& e, bool subtest)
{
std::cout << std::endl
<< " (caught exception of type "
<< e.getName();
if ((e.getLine() > 0) && e.getFile()[0] != '\0')
{
std::cout << (subtest ? "" : " outside a subtest")
<< ", which was thrown in line "
<< e.getLine() << " of file " << e.getFile();
}
std::cout << " - unexpected!) "
<< std::endl
<< " (message is: " << e.getMessage() << ")"
<< std::endl;
}
template<>
void printErrorMessage(BALL::Exception::FileNotFound& e, bool subtest)
{
std::cout << std::endl
<< " (caught exception of type "
<< e.getName();
if ((e.getLine() > 0) && e.getFile()[0] != '\0')
{
std::cout << (subtest ? "" : " outside a subtest")
<< ", which was thrown in line "
<< e.getLine() << " of file " << e.getFile();
}
std::cout << " while looking for file " << e.getFilename()
<< " - unexpected!) "
<< std::endl;
}
template<class T>
void printException(T e, bool subtest)
{
TEST::this_test = false;
TEST::test = false;
TEST::all_tests = false;
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))
{
if(!TEST::newline)
{
TEST::newline = true;
std::cout << std::endl;
}
printErrorMessage(e, subtest);
}
}
}
#define PRECISION(a) \
TEST::precision = (a);
#define START_TEST(class_name)\
\
int main(int argc, char **argv)\
{\
\
if (argc == 2) {\
if (!strcmp(argv[1], "-v"))\
TEST::verbose = 1;\
if (!strcmp(argv[1], "-V"))\
TEST::verbose = 2;\
};\
\
if ((argc > 2) || ((argc == 2) && (TEST::verbose == 0))) {\
std::cerr << "Checks " #class_name " class" << std::endl;\
\
std::cerr << "On successful operation it simply returns OK," << std::endl;\
std::cerr << "otherwise FAILURE is printed." << std::endl;\
std::cerr << "If called with an argument of -v, " << argv[0] << " prints detailed" << std::endl;\
std::cerr << "information about individual tests." << std::endl;\
std::cerr << "Option -V provides verbose information on" << std::endl;\
std::cerr << "every subtest." << std::endl;\
return 1;\
}\
\
if (TEST::verbose > 0)\
std::cout << "Version: " << TEST::version_string << std::endl;\
\
try {\
#define END_TEST \
/* global try block */\
}\
catch (BALL::Exception::FileNotFound& e) { TEST::printException(e, false); }\
catch (BALL::Exception::GeneralException& e) { TEST::printException(e, false); }\
catch (std::exception& e) { TEST::printException(e, false); }\
catch (...) { TEST::printException(0, false); }\
\
/* clean up all temporary files */\
while (TEST::tmp_file_list.size() > 0 && TEST::verbose < 1)\
{\
::BALL::File::remove(TEST::tmp_file_list.back().c_str());\
TEST::tmp_file_list.pop_back();\
}\
/* check for exit code */\
std::cout << (TEST::all_tests ? "PASSED" : "FAILED") << std::endl;\
return !TEST::all_tests;\
}\
#define CHECK(test_name) \
TEST::test = true;\
TEST::newline = false;\
if (TEST::verbose > 0)\
std::cout << "checking " << #test_name << "... " << std::flush;\
try\
{\
while (true)\
{\
#define STATUS(message)\
if (TEST::verbose > 1)\
{\
if (!TEST::newline) \
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " status (line " << __LINE__ << "): " << message << std::endl;\
}\
#define RESULT \
break;\
}\
}\
/* catch FileNotFound exceptions to print out the file name */\
catch (BALL::Exception::FileNotFound& e) { TEST::printException(e, true); }\
catch (::BALL::Exception::GeneralException& e) { TEST::printException(e, true); }\
catch (std::exception& e) { TEST::printException(e, true); }\
catch (...) { TEST::printException(0, true); }\
\
TEST::all_tests = TEST::all_tests && TEST::test;\
if (TEST::verbose > 0){\
if (TEST::newline)\
std::cout << " ";\
std::cout << (TEST::test ? "passed" : "FAILED") << std::endl;\
}\
#define SLEEP_FOR_MSECS(ms) std::this_thread::sleep_for(std::chrono::milliseconds(ms))
#define NEW_TMP_FILE(filename)\
::BALL::File::createTemporaryFilename(filename);\
TEST::tmp_file_list.push_back(filename);\
if (TEST::verbose > 1)\
{\
if (!TEST::newline) \
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " creating new temporary file '" << filename << "' (line " << __LINE__ << ")" << std::endl;\
}\
#define NEW_TMP_FILE_WITH_SUFFIX(filename, suffix)\
::BALL::File::createTemporaryFilename(filename, suffix);\
TEST::tmp_file_list.push_back(filename);\
if (TEST::verbose > 1)\
{\
if (!TEST::newline) \
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " creating new temporary file '" << filename << "' (line " << __LINE__ << ")" << std::endl;\
}\
#define TEST_REAL_EQUAL(a,b) \
TEST::this_test = fabs((a) - (b)) < TEST::precision; \
TEST::test = TEST::test && TEST::this_test;\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << " TEST_REAL_EQUAL("<< #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\
std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
}\
#define TEST_EQUAL(a,b) \
{\
TEST::this_test = ((a) == (b));\
TEST::test = TEST::test && TEST::this_test;\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << " TEST_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\
std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
}\
}\
#define TEST_NOT_EQUAL(a,b) \
{\
TEST::this_test = !((a) == (b));\
TEST::test = TEST::test && TEST::this_test;\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << " TEST_NOT_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", forbidden is " << (b) << ") ";\
std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
}\
}\
#define TEST_EXCEPTION(exception_type, command) \
{\
TEST::exception = 0;\
try\
{\
command;\
}\
catch (exception_type&)\
{\
TEST::exception = 1;\
}\
catch (::BALL::Exception::GeneralException& e)\
{\
TEST::exception = 2;\
TEST::exception_name = e.getName();\
}\
catch (...)\
{ \
TEST::exception = 3;\
}\
TEST::this_test = (TEST::exception == 1);\
TEST::test = TEST::test && TEST::this_test;\
\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << " TEST_EXCEPTION(" << #exception_type << ", " << #command << "): ";\
switch (TEST::exception)\
{\
case 0: std::cout << " ERROR: no exception!) "; break;\
case 1: std::cout << " OK) "; break;\
case 2: std::cout << " ERROR: wrong exception: " << TEST::exception_name << ") "; break;\
case 3: std::cout << " ERROR: wrong exception!) "; break;\
}\
std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
}\
}\
#ifdef BALL_DEBUG
#define TEST_PRECONDITION_EXCEPTION(command) \
{\
TEST::exception = 0;\
try\
{\
command;\
}\
catch (Exception::Precondition&)\
{\
TEST::exception = 1;\
}\
catch (::BALL::Exception::GeneralException& e)\
{\
TEST::exception = 2;\
TEST::exception_name = e.getName();\
}\
catch (...)\
{ \
TEST::exception = 3;\
}\
TEST::this_test = (TEST::exception == 1);\
TEST::test = TEST::test && TEST::this_test;\
\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << " TEST_PRECONDITION_EXCEPTION(" << ", " << #command << "): ";\
switch (TEST::exception)\
{\
case 0: std::cout << " ERROR: no exception!) "; break;\
case 1: std::cout << " OK) "; break;\
case 2: std::cout << " ERROR: wrong exception: " << TEST::exception_name << ") "; break;\
case 3: std::cout << " ERROR: wrong exception!) "; break;\
}\
std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
}\
}\
#else
# define TEST_PRECONDITION_EXCEPTION(command)\
if (TEST::verbose > 1)\
{\
std::cout << " TEST_EXCEPTION_PRECONDITION(" #command ") : (DEBUG mode disabled!)" << std::endl;\
}\
#endif // BALL_DEBUG
#define ABORT_IF(condition) \
if (condition) break;
#define TEST_FILE(filename, templatename) \
{\
TEST::equal_files = true;\
TEST::infile.open(filename, std::ios::in);\
TEST::templatefile.open(templatename, std::ios::in);\
\
if (TEST::infile.good() && TEST::templatefile.good())\
{\
String TEST_FILE__template_line;\
String TEST_FILE__line;\
\
while (TEST::infile.good() && TEST::templatefile.good())\
{\
TEST_FILE__template_line.getline(TEST::templatefile);\
TEST_FILE__line.getline(TEST::infile);\
\
TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line);\
if (TEST_FILE__template_line != TEST_FILE__line)\
{\
if (TEST::verbose > 0)\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
\
std::cout << " TEST_FILE: line mismatch:\n got: '" << TEST_FILE__line << "'\n expected: '" << TEST_FILE__template_line << "'" << std::endl;\
}\
}\
}\
} else {\
TEST::equal_files = false;\
\
if (TEST::verbose > 0)\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
\
std::cout << " (line " << __LINE__ << ": TEST_FILE(" << #filename << ", " << #templatename ;\
std::cout << ") : " << " cannot open file: \"";\
if (!TEST::infile.good())\
{\
std::cout << filename << "\" (input file) ";\
}\
if (!TEST::templatefile.good())\
{\
std::cout << templatename << "\" (template file) ";\
}\
std::cout << std::endl;\
\
}\
}\
TEST::infile.close();\
TEST::templatefile.close();\
TEST::infile.clear();\
TEST::templatefile.clear();\
\
TEST::this_test = TEST::equal_files;\
TEST::test = TEST::test && TEST::this_test;\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << ": TEST_FILE("<< #filename << ", " << #templatename << "): ";\
std::cout << (TEST::this_test ? "true + " : "false - ") << std::endl;\
}\
}
#define TEST_FILE_REGEXP(filename, templatename) \
{\
TEST::equal_files = true;\
TEST::infile.open(filename, std::ios::in);\
TEST::templatefile.open(templatename, std::ios::in);\
\
if (TEST::infile.good() && TEST::templatefile.good())\
{\
String TEST_FILE__template_line;\
String TEST_FILE__line;\
\
while (TEST::infile.good() && TEST::templatefile.good())\
{\
TEST_FILE__template_line.getline(TEST::templatefile);\
TEST_FILE__line.getline(TEST::infile);\
\
if ((TEST_FILE__template_line.size() > 0) && (TEST_FILE__template_line[0] == '/') && (TEST_FILE__template_line[1] != '/'))\
{\
RegularExpression expression(TEST_FILE__template_line(1));\
bool match = expression.match(TEST_FILE__line);\
TEST::equal_files &= match;\
if (!match)\
{\
if (TEST::verbose > 0)\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
\
std::cout << " TEST_FILE_REGEXP: regexp mismatch: " << TEST_FILE__line << " did not match " << TEST_FILE__template_line(1) << "." << std::endl;\
}\
}\
} else {\
TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line);\
if (TEST_FILE__template_line != TEST_FILE__line)\
{\
if (TEST::verbose > 0)\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
\
std::cout << " TEST_FILE: line mismatch:\n got: '" << TEST_FILE__line << "'\n expected: '" << TEST_FILE__template_line << "'" << std::endl;\
}\
}\
}\
}\
} else {\
TEST::equal_files = false;\
\
if (TEST::verbose > 0)\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
\
std::cout << " (line " << __LINE__ << ": TEST_FILE_REGEXP(" << #filename << ", " << #templatename ;\
std::cout << ") : " << " cannot open file: \"";\
if (!TEST::infile.good())\
{\
std::cout << filename << "\" (input file) ";\
}\
if (!TEST::templatefile.good())\
{\
std::cout << templatename << "\" (template file) ";\
}\
std::cout << std::endl;\
\
}\
}\
TEST::infile.close();\
TEST::templatefile.close();\
TEST::infile.clear();\
TEST::templatefile.clear();\
\
TEST::this_test = TEST::equal_files;\
TEST::test = TEST::test && TEST::this_test;\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << ": TEST_FILE_REGEXP("<< #filename << ", " << #templatename << "): ";\
std::cout << (TEST::this_test ? "true + " : "false - ") << std::endl;\
}\
}
#define CAPTURE_OUTPUT_LEVEL(level) \
{\
std::ostringstream TEST_strstr;\
Log.remove(std::cout);\
Log.remove(std::cerr);\
Log.insert(TEST_strstr, level, level);
#define CAPTURE_OUTPUT_LEVEL_RANGE(minlevel, maxlevel) \
{\
std::ostringstream TEST_strstr;\
Log.remove(std::cout);\
Log.remove(std::cerr);\
Log.insert(TEST_strstr, minlevel, maxlevel);
#define COMPARE_OUTPUT(text) \
Log.remove(TEST_strstr);\
Log.insert(std::cout, LogStream::INFORMATION_LEVEL, LogStream::ERROR_LEVEL - 1);\
Log.insert(std::cerr, LogStream::ERROR_LEVEL);\
TEST::this_test = (::strncmp(TEST_strstr.str().c_str(), text, TEST_strstr.str().size()) == 0);\
TEST::test = TEST::test && TEST::this_test;\
\
if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
{\
/* reserve space for the null-terminated content of the strstrem */\
char* TEST_strstr_contents = new char[TEST_strstr.str().size() + 1];\
::strncpy(TEST_strstr_contents, TEST_strstr.str().c_str(), TEST_strstr.str().size());\
TEST_strstr_contents[TEST_strstr.str().size()] = '\0';\
\
if (!TEST::newline)\
{\
TEST::newline = true;\
std::cout << std::endl;\
}\
std::cout << " (line " << __LINE__ << " COMPARE_OUTPUT(" << #text << "): got '" << (TEST_strstr_contents) << "', expected '" << (text) << ") ";\
std::cout << (TEST::this_test ? " + " : " - ") << std::endl;\
delete [] TEST_strstr_contents;\
}\
}
#endif // BALL_CONCEPT_CLASSTEST_H
autoDeletable.h
BALL::Exception::FileNotFound
Definition COMMON/exception.h:361
BALL::Exception::FileNotFound::getFilename
String getFilename() const
BALL::Exception::GeneralException
Definition COMMON/exception.h:61
BALL::Exception::GeneralException::getFile
const char * getFile() const
Returns the file where it occurred.
BALL::Exception::GeneralException::getLine
int getLine() const
Returns the line number where it occurred.
BALL::Exception::GeneralException::getMessage
const char * getMessage() const
Returns the error message of the exception.
BALL::Exception::GeneralException::getName
const char * getName() const
Returns the name of the exception.
file.h
TEST
Definition classTest.h:17
TEST::exception_name
string exception_name
Definition classTest.h:23
TEST::printException
void printException(T e, bool subtest)
Definition classTest.h:87
TEST::exception
int exception
Definition classTest.h:22
TEST::printErrorMessage
void printErrorMessage(T &, bool subtest)
Definition classTest.h:33
TEST::version_string
const char * version_string
Definition classTest.h:24
TEST::newline
bool newline
Definition classTest.h:25
TEST::this_test
bool this_test
Definition classTest.h:21
TEST::infile
std::ifstream infile
Definition classTest.h:27
TEST::tmp_file_list
list< string > tmp_file_list
Definition classTest.h:26
TEST::templatefile
std::ifstream templatefile
Definition classTest.h:28
TEST::all_tests
bool all_tests
Definition classTest.h:19
TEST::test
bool test
Definition classTest.h:20
TEST::precision
double precision
Definition classTest.h:30
TEST::verbose
int verbose
Definition classTest.h:18
TEST::equal_files
bool equal_files
Definition classTest.h:29
regularExpression.h