1 //----------------------------------------------------------------------------- 2 /** @file libboardgame_test/Test.h 3 Provides functionality similar to Boost.Test. 4 @author Markus Enzenberger 5 @copyright GNU General Public License version 3 or later */ 6 //----------------------------------------------------------------------------- 7 8 #ifndef LIBBOARDGAME_TEST_TEST_H 9 #define LIBBOARDGAME_TEST_TEST_H 10 11 #include <cmath> 12 #include <functional> 13 #include <sstream> 14 #include <stdexcept> 15 #include <string> 16 17 namespace libboardgame_test { 18 19 using namespace std; 20 21 //----------------------------------------------------------------------------- 22 23 using TestFunction = function<void()>; 24 25 //----------------------------------------------------------------------------- 26 27 class TestFail 28 : public logic_error 29 { 30 public: 31 TestFail(const char* file, int line, const string& s); 32 }; 33 34 //----------------------------------------------------------------------------- 35 36 void add_test(const string& name, const TestFunction& function); 37 38 bool run_all_tests(); 39 40 bool run_test(const string& name); 41 42 //----------------------------------------------------------------------------- 43 44 /** Helper class that automatically adds a test when an instance is 45 declared. */ 46 struct TestRegistrar 47 { TestRegistrarTestRegistrar48 TestRegistrar(const string& name, const TestFunction& function) 49 { 50 add_test(name, function); 51 } 52 }; 53 54 //----------------------------------------------------------------------------- 55 56 } // namespace libboardgame_test 57 58 //----------------------------------------------------------------------------- 59 60 #define LIBBOARDGAME_TEST_CASE(name) \ 61 static void name(); \ 62 static libboardgame_test::TestRegistrar name##_registrar(#name, name); \ 63 void name() 64 65 66 #define LIBBOARDGAME_CHECK(expr) \ 67 if (! (expr)) \ 68 throw libboardgame_test::TestFail(__FILE__, __LINE__, "check failed") 69 70 #define LIBBOARDGAME_CHECK_EQUAL(expr1, expr2) \ 71 { \ 72 using libboardgame_test::TestFail; \ 73 const auto& result1 = (expr1); \ 74 const auto& result2 = (expr2); \ 75 if (result1 != result2) \ 76 { \ 77 ostringstream msg; \ 78 msg << "'" << result1 << "' != '" << result2 << "'"; \ 79 throw TestFail(__FILE__, __LINE__, msg.str()); \ 80 } \ 81 } 82 83 #define LIBBOARDGAME_CHECK_THROW(expr, exception) \ 84 { \ 85 using libboardgame_test::TestFail; \ 86 bool was_thrown = false; \ 87 try \ 88 { \ 89 expr; \ 90 } \ 91 catch (const exception&) \ 92 { \ 93 was_thrown = true; \ 94 } \ 95 if (! was_thrown) \ 96 { \ 97 ostringstream msg; \ 98 msg << "Exception '" << #exception << "' was not thrown"; \ 99 throw TestFail(__FILE__, __LINE__, msg.str()); \ 100 } \ 101 } 102 103 #define LIBBOARDGAME_CHECK_NO_THROW(expr) \ 104 { \ 105 using libboardgame_test::TestFail; \ 106 try \ 107 { \ 108 expr; \ 109 } \ 110 catch (...) \ 111 { \ 112 throw TestFail(__FILE__, __LINE__, \ 113 "Unexpected exception was thrown"); \ 114 } \ 115 } 116 117 /** Compare floating points using a tolerance in percent. */ 118 #define LIBBOARDGAME_CHECK_CLOSE(expr1, expr2, tolerance) \ 119 { \ 120 using libboardgame_test::TestFail; \ 121 auto result1 = (expr1); \ 122 auto result2 = (expr2); \ 123 if (fabs(result1 - result2) > (tolerance) * result1 / 100) \ 124 { \ 125 ostringstream msg; \ 126 msg << "Difference between " << result1 << " and " \ 127 << result2 << " exceeds " << ((tolerance) / 100 ) \ 128 << " percent"; \ 129 throw TestFail(__FILE__, __LINE__, msg.str()); \ 130 } \ 131 } 132 133 /** Compare floating points using an epsilon. */ 134 #define LIBBOARDGAME_CHECK_CLOSE_EPS(expr1, expr2, epsilon) \ 135 { \ 136 using libboardgame_test::TestFail; \ 137 auto result1 = (expr1); \ 138 auto result2 = (expr2); \ 139 if (fabs(result1 - result2) > (epsilon)) \ 140 { \ 141 ostringstream msg; \ 142 msg << "Difference between " << result1 << " and " \ 143 << result2 << " exceeds " << (epsilon); \ 144 throw TestFail(__FILE__, __LINE__, msg.str()); \ 145 } \ 146 } 147 148 //----------------------------------------------------------------------------- 149 150 #endif // LIBBOARDGAME_TEST_TEST_H 151