39 _tests.emplace_back(name, cb);
43 for (
auto& test : _tests) {
44 std::cout <<
"### Running test: " << test._name <<
"\n";
45 _running_test_name = test._name;
46 auto start = std::chrono::steady_clock::now();
49 }
catch (std::exception&
e) {
51 std::cerr <<
"Aborting test, exception thrown in \"" << test._name <<
"\":" << std::endl
52 << e.what() << std::endl;
55 std::cerr <<
"Aborting all tests, uncaught exception!" << std::endl;
58 auto end = std::chrono::steady_clock::now();
59 std::cout <<
"## " << test._name <<
" complete in " << std::chrono::duration <double, std::nano> (end-start).count() / 1e6 <<
" ms" << std::endl;
62 std::cout <<
"# Tests complete with " << _error_counter <<
" errors" << std::endl;
63 return _error_counter > 0;
66 template<
class L,
class R>
67 void check_equal(
const L& l,
const R& r, std::string file,
int line, std::string Lname, std::string Rname) {
70 std::cerr << file <<
"(" << line <<
"): error in \"" << _running_test_name <<
"\": check " << Lname <<
" == " << Rname <<
" failed, " << l <<
" != " << r << std::endl;
74 void check(
bool l, std::string file,
int line, std::string Lname) {
77 std::cerr << file <<
"(" << line <<
"): error in \"" << _running_test_name <<
"\": check " << Lname <<
" failed" << std::endl;
81 template<
class L,
class R,
class Tol_t>
82 void check_close(L l, R r, std::string file,
int line, std::string Lname, std::string Rname, Tol_t tol)
90 if (difference <= tol)
return;
93 std::cerr << file <<
"(" << line <<
"): error in \"" << _running_test_name <<
"\": difference (" << difference*100 <<
"%) between " << Lname <<
"{"<<l<<
"} and " << Rname <<
"{"<<r<<
"} exceeds " << tol*100.00 <<
"%" << std::endl;
96 template<
class T,
class Tol_t>
97 void check_small(T l, std::string file,
int line, std::string Lname, Tol_t tol) {
100 std::cerr << file <<
"(" << line <<
"): error in \"" << _running_test_name <<
"\": absolute value of " << Lname <<
"{"<<l<<
"} exceeds " << tol << std::endl;
104 void error(std::string msg, std::string file,
int line) {
106 std::cerr << file <<
"(" << line <<
"): error in \"" << _running_test_name <<
"\": " << msg << std::endl;
111 Test(std::string name, std::function<
void()> cb): _name(name), _callback(cb) {}
114 std::function<void()> _callback;
117 std::vector<Test> _tests;
119 std::string _running_test_name;
121 size_t _error_counter;
130 #define UNIT_TEST(A) void A(); UnitTestRegisterer A ## _reg(#A, A); void A() 132 #define UNIT_TEST_CHECK_EQUAL(A, B) UnitTests::get().check_equal(A, B, __FILE__, __LINE__, #A, #B) 133 #define UNIT_TEST_CHECK(Expr) UnitTests::get().check(Expr, __FILE__, __LINE__, #Expr) 134 #define UNIT_TEST_CHECK_CLOSE(A, B, TOL) UnitTests::get().check_close(A, B, __FILE__, __LINE__, #A, #B, TOL) 135 #define UNIT_TEST_CHECK_SMALL(A, TOL) UnitTests::get().check_small(A, __FILE__, __LINE__, #A, TOL) 136 #define UNIT_TEST_ERROR(MSG) UnitTests::get().error(MSG, __FILE__, __LINE__) 141 }
catch (
const std::exception&
e) {
142 std::cerr <<
"Unit tests aborting due to exception:\n" << e.what() << std::endl;
void check(bool l, std::string file, int line, std::string Lname)
detail::C_wrap< stator::constant_ratio::e >::type e
A symbolic/compile-time rational approximation of .
UnitTestRegisterer(std::string name, std::function< void()> cb)
void register_test(std::string name, std::function< void()> cb)
void check_close(L l, R r, std::string file, int line, std::string Lname, std::string Rname, Tol_t tol)
void error(std::string msg, std::string file, int line)
void check_equal(const L &l, const R &r, std::string file, int line, std::string Lname, std::string Rname)
constexpr C<(1 - 2 *(num< 0)) *num,(1 - 2 *(den< 0)) *den > abs(const C< num, den > &a)
void check_small(T l, std::string file, int line, std::string Lname, Tol_t tol)