#pragma once #include "tl/string.h" #include "tl/vector.h" #include "tl/format.h" #include "tl/utest.h" struct ExpectedAssertGuard { ExpectedAssertGuard(tl::string msg, int* utest_result) { s_utest_results.push_back(utest_result); s_msgs.push_back(std::move(msg)); s_oldHandlers.push_back(tl::assert::set_handler(assertHandler)); } ~ExpectedAssertGuard() { tl::assert::set_handler(s_oldHandlers.back()); s_oldHandlers.pop_back(); s_msgs.pop_back(); s_utest_results.pop_back(); } private: static tl::assert::response assertHandler(const char* condition, const char* file, int line, const char* msg) { int* utest_result = s_utest_results.back(); EXPECT_EQ(s_msgs.back(), msg); return tl::assert::response::CONTINUE; } static tl::vector s_utest_results; static tl::vector s_msgs; static tl::vector s_oldHandlers; }; #define EXPECTED_ASSERT_GUARD(msg) ExpectedAssertGuard eassert##__LINE__(msg, utest_result) struct NoAssertGuard { NoAssertGuard(int* utest_result) { s_utest_results.push_back(utest_result); s_oldHandlers.push_back(tl::assert::set_handler(assertHandler)); } ~NoAssertGuard() { tl::assert::set_handler(s_oldHandlers.back()); s_oldHandlers.pop_back(); s_utest_results.pop_back(); } private: static tl::assert::response assertHandler(const char* condition, const char* file, int line, const char* msg) { int* utest_result = s_utest_results.back(); EXPECT_FALSE_MSG(true, tl::format("Unexpected assert: [{}] {}({}): {}", condition ? condition : "", file ? file : "", line, msg ? msg : "").c_str()); return tl::assert::response::CONTINUE; } static tl::vector s_utest_results; static tl::vector s_oldHandlers; }; #define NO_ASSERT_GUARD NoAssertGuard noassert##__LINE__(utest_result) struct ExpectedCrashGuard { ExpectedCrashGuard(tl::string msg, int* utest_result) { s_utest_results.push_back(utest_result); s_msgs.push_back(std::move(msg)); s_oldHandlers.push_back(tl::crash::set_handler(crashHandler)); } ~ExpectedCrashGuard() { tl::crash::set_handler(s_oldHandlers.back()); s_oldHandlers.pop_back(); s_msgs.pop_back(); s_utest_results.pop_back(); } private: static tl::crash::response crashHandler(const char* file, int line, const char* msg) { int* utest_result = s_utest_results.back(); EXPECT_EQ(s_msgs.back(), msg); return tl::crash::response::CONTINUE; } static tl::vector s_utest_results; static tl::vector s_msgs; static tl::vector s_oldHandlers; }; #define EXPECTED_CRASH_GUARD(msg) ExpectedCrashGuard ecrash##__LINE__(msg, utest_result) //struct NoCrashesGuard //{ // NoCrashesGuard() // { // s_oldHandlers.push_back(tl::crash::set_handler(crashHandler)); // } // // ~NoCrashesGuard() // { // tl::crash::set_handler(s_oldHandlers.back()); // s_oldHandlers.pop_back(); // } // //private: // static tl::crash::response crashHandler(const char* file, int line, const char* msg) // { // EXPECT_TRUE_MSG(false, tl::format("Unexpected crash: {}({}): {}", file ? file : "", line, msg ? msg : "").c_str()); // return tl::crash::response::CONTINUE; // } // // static tl::vector s_oldHandlers; //};