#ifndef _test_common_n_ #define _test_common_n_ #pragma once #include #include #include #include struct TestFailure : public std::runtime_error { using std::runtime_error::runtime_error; }; #define CHECK(cond, msg) do { if (!(cond)) throw TestFailure(msg); } while (0) #define CHECK_EQ(a,b,msg) do { if (!((a)==(b))) { throw TestFailure(std::string(msg) + " (" #a " != " #b ")"); } } while (0) #define TEST_CASE(name) \ static void name(); \ struct name##_registrar { name##_registrar(){ TestRegistry::add(#name, &name);} } name##_registrar_instance; \ static void name() struct TestRegistry { using Fn = void(*)(); static std::vector>& list() { static std::vector> v; return v; } static void add(const std::string& name, Fn fn) { list().push_back({name, fn}); } }; // Default test runner main() #ifdef TEST_MAIN int main() { int fails = 0; for (auto& t : TestRegistry::list()) { try { t.second(); //std::cout << "[PASS] " << t.first << "\n"; } catch (const TestFailure& e) { std::cerr << "[FAIL] " << t.first << " -> " << e.what() << "\n"; ++fails; } catch (const std::exception& e) { std::cerr << "[ERROR] " << t.first << " -> " << e.what() << "\n"; ++fails; } } std::cout << (fails ? "Some tests failed ❌\n" : "All tests passed ✅\n"); return fails ? 1 : 0; } #endif #endif // _test_common_n_