#pragma once #include #include #include #include // macro to help adding tests #define TEST(N) {#N, N} // macro to help with the main.cpp #define TEST_SET(N) namespace N { extern fuc2::Set TESTS; } namespace fuc2 { using Func = std::function; using Case = std::pair; struct Options { bool fail_fast = false; bool verbose = false; bool disabled = false; std::string matching{}; }; struct Set { std::string name; Options options{}; std::vector tests; std::source_location location = std::source_location::current(); }; std::string craft_error( const std::string& type, const std::string& test, const std::string &message, const std::source_location location, const std::source_location test_sig = std::source_location::current()); void CHECK(bool test, const std::string &message="", const std::source_location location = std::source_location::current()); void EQUAL(auto v1, auto v2, const std::string &message="", const std::source_location location = std::source_location::current()) { if(v1 != v2) { auto test_value = fmt::format("{} != {}", v1, v2); throw std::runtime_error(craft_error("EQUAL", test_value, message, location)); } } void NOT_EQUAL(auto v1, auto v2, const std::string &message="", const std::source_location location = std::source_location::current()) { if(v1 == v2) { auto test_value = fmt::format("{} == {}", v1, v2); throw std::runtime_error(craft_error("NOT_EQUAL", test_value, message, location)); } } void ALMOST_EQUAL(auto v1, auto v2, int decimal_places, const std::string &message="", const std::source_location location = std::source_location::current()) { double multiplier = std::pow(10.0, decimal_places); auto r_v1 = std::round(v1 * multiplier) / multiplier; auto r_v2 = std::round(v2 * multiplier) / multiplier; if(r_v1 != r_v2) { auto test_value = fmt::format("{} != {} rounded {} places {} != {}", v1, v2, decimal_places, r_v1, r_v2); throw std::runtime_error(craft_error("ALMOST_EQUAL", test_value, message, location)); } } void BLOWS_UP(std::function cb, const std::string &message="", const std::source_location location = std::source_location::current()); }