#ifndef RA3TEST_HPP #define RA3TEST_HPP // A tiny dependency-free test harness (registry + CHECK macros). Each unit-test // executable compiles test_main.cpp and links the sources under test. #include #include #include #include #include namespace ra3test { struct test_case { std::string name; std::function fn; }; inline auto registry() -> std::vector & { static std::vector tests; return tests; } inline auto failure_count() -> int & { static int count = 0; return count; } struct registrar { registrar(std::string name, std::function fn) { registry().push_back({std::move(name), std::move(fn)}); } }; inline auto report_failure(const std::string &expr, const std::string &file, int line) -> void { ++failure_count(); std::cerr << " FAIL " << file << ':' << line << " " << expr << '\n'; } inline auto check(bool condition, const std::string &expr, const std::string &file, int line) -> void { if (!condition) report_failure(expr, file, line); } inline auto run_all() -> int { int passed = 0; for (auto &test: registry()) { const int before = failure_count(); std::cout << "[ RUN ] " << test.name << '\n'; try { test.fn(); } catch (const std::exception &exc) { report_failure(std::string("uncaught exception: ") + exc.what(), __FILE__, __LINE__); } if (failure_count() == before) { ++passed; std::cout << "[ OK ] " << test.name << '\n'; } } std::cout << "\n" << passed << '/' << registry().size() << " tests passed, " << failure_count() << " failure(s)\n"; return failure_count() == 0 ? 0 : 1; } } // namespace ra3test #define TEST(name) \ static void name(); \ static ::ra3test::registrar ra3test_reg_##name(#name, name); \ static void name() #define CHECK(cond) ::ra3test::check((cond), #cond, __FILE__, __LINE__) #define CHECK_EQ(a, b) ::ra3test::check_eq((a), (b), #a, #b, __FILE__, __LINE__) namespace ra3test { template auto check_eq(const A &a, const B &b, const std::string &ea, const std::string &eb, const std::string &file, int line) -> void { if (!(a == b)) { std::ostringstream os; os << ea << " == " << eb; report_failure(os.str(), file, line); } } } #endif // RA3TEST_HPP