Files
Renderive/Kernel/tests/compat/gtest/gtest.h
T
2026-08-04 16:24:41 +08:00

76 lines
4.1 KiB
C++

#pragma once
#include <cmath>
#include <exception>
#include <functional>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
namespace testing {
struct Test_Info {
std::string suite;
std::string name;
std::function<void()> function;
};
inline std::vector<Test_Info>& registry() {
static std::vector<Test_Info> tests;
return tests;
}
inline int& current_failures() {
static thread_local int failures{};
return failures;
}
class Fatal_Failure {};
inline bool register_test(const char* suite, const char* name, std::function<void()> function) {
registry().push_back({suite, name, std::move(function)});
return true;
}
inline void fail(const char* file, int line, const char* expression, bool fatal) {
++current_failures();
std::cerr << file << ':' << line << ": failure: " << expression << '\n';
if (fatal) {
throw Fatal_Failure{};
}
}
inline void InitGoogleTest(int*, char**) {}
inline int Run_All_Tests() {
int failed_tests{};
for (const Test_Info& test : registry()) {
if (test.suite.starts_with("DISABLED_") || test.name.starts_with("DISABLED_")) {
std::cout << "[ DISABLED ] " << test.suite << '.' << test.name << '\n';
continue;
}
current_failures() = 0;
try {
test.function();
} catch (const Fatal_Failure&) {
} catch (const std::exception& exception) {
fail(__FILE__, __LINE__, exception.what(), false);
} catch (...) {
fail(__FILE__, __LINE__, "unknown exception", false);
}
if (current_failures() != 0) {
++failed_tests;
std::cerr << "[ FAILED ] " << test.suite << '.' << test.name << '\n';
} else {
std::cout << "[ OK ] " << test.suite << '.' << test.name << '\n';
}
}
std::cout << registry().size() << " tests, " << failed_tests << " failed\n";
return failed_tests == 0 ? 0 : 1;
}
}
#define TEST(suite, name) static void suite##_##name##_test(); static const bool suite##_##name##_registered = ::testing::register_test(#suite, #name, suite##_##name##_test); static void suite##_##name##_test()
#define EXPECT_TRUE(value) do { if (!(value)) ::testing::fail(__FILE__, __LINE__, "EXPECT_TRUE(" #value ")", false); } while (false)
#define EXPECT_FALSE(value) do { if ((value)) ::testing::fail(__FILE__, __LINE__, "EXPECT_FALSE(" #value ")", false); } while (false)
#define ASSERT_TRUE(value) do { if (!(value)) ::testing::fail(__FILE__, __LINE__, "ASSERT_TRUE(" #value ")", true); } while (false)
#define EXPECT_EQ(left, right) do { if (!((left) == (right))) ::testing::fail(__FILE__, __LINE__, "EXPECT_EQ(" #left ", " #right ")", false); } while (false)
#define EXPECT_NE(left, right) do { if (!((left) != (right))) ::testing::fail(__FILE__, __LINE__, "EXPECT_NE(" #left ", " #right ")", false); } while (false)
#define EXPECT_GT(left, right) do { if (!((left) > (right))) ::testing::fail(__FILE__, __LINE__, "EXPECT_GT(" #left ", " #right ")", false); } while (false)
#define EXPECT_GE(left, right) do { if (!((left) >= (right))) ::testing::fail(__FILE__, __LINE__, "EXPECT_GE(" #left ", " #right ")", false); } while (false)
#define EXPECT_DOUBLE_EQ(left, right) do { double gtest_left = static_cast<double>(left); double gtest_right = static_cast<double>(right); if (!(std::fabs(gtest_left - gtest_right) <= 1e-12 || (std::isnan(gtest_left) && std::isnan(gtest_right)))) ::testing::fail(__FILE__, __LINE__, "EXPECT_DOUBLE_EQ(" #left ", " #right ")", false); } while (false)
#define EXPECT_THROW(statement, exception_type) do { bool gtest_thrown = false; try { statement; } catch (const exception_type&) { gtest_thrown = true; } catch (...) {} if (!gtest_thrown) ::testing::fail(__FILE__, __LINE__, "EXPECT_THROW(" #statement ", " #exception_type ")", false); } while (false)
#define EXPECT_NO_THROW(statement) do { bool gtest_thrown = false; try { statement; } catch (...) { gtest_thrown = true; } if (gtest_thrown) ::testing::fail(__FILE__, __LINE__, "EXPECT_NO_THROW(" #statement ")", false); } while (false)
#define SUCCEED() do {} while (false)
#define RUN_ALL_TESTS() ::testing::Run_All_Tests()