76 lines
4.1 KiB
C++
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()
|