#pragma once #include #include #include #include #include #define ASSERT_EQ(expected, actual) \ do { \ auto e = (expected); \ auto a = (actual); \ if (e != a) { \ std::cerr << "Assertion failed: " << #expected << " == " << #actual << "\n" \ << " Expected: " << e << "\n" \ << " Actual: " << a << "\n" \ << " File: " << __FILE__ << ":" << __LINE__ << "\n"; \ throw std::runtime_error("Assertion failed"); \ } \ } while (0) #define ASSERT_TRUE(condition) \ do { \ if (!(condition)) { \ std::cerr << "Assertion failed: " << #condition << "\n" \ << " File: " << __FILE__ << ":" << __LINE__ << "\n"; \ throw std::runtime_error("Assertion failed"); \ } \ } while (0) class TestRunner { public: static TestRunner& instance() { static TestRunner instance; return instance; } void register_test(const std::string& name, std::function test) { tests_.push_back({name, test}); } int run_all() { int passed = 0; int failed = 0; std::cout << "Running " << tests_.size() << " tests...\n"; for (const auto& [name, test] : tests_) { try { test(); std::cout << "[PASS] " << name << "\n"; passed++; } catch (const std::exception& e) { std::cout << "[FAIL] " << name << ": " << e.what() << "\n"; failed++; } catch (...) { std::cout << "[FAIL] " << name << ": Unknown error\n"; failed++; } } std::cout << "\nResults: " << passed << " passed, " << failed << " failed.\n"; return failed > 0 ? 1 : 0; } private: std::vector>> tests_; }; struct AutoRegister { AutoRegister(const std::string& name, std::function test) { TestRunner::instance().register_test(name, test); } }; #define TEST(name) \ void test_##name(); \ AutoRegister reg_##name(#name, test_##name); \ void test_##name()