#pragma once #include using namespace std::string_literals; using ::testing::ValuesIn; using ::testing::Values; class klXlTestRunner : public testing::Test { protected: static void SetUpTestSuite() { } static void TearDownTestSuite() { } void SetUp() override { } void TearDown() override { } }; class XlTest : public klXlTestRunner { public: explicit XlTest(int _) : data(_) {} void TestBody() override { } private: int data; }; // Utility functions to help SuiteApiResolver using SetUpTearDownSuiteFuncType = void (*)(); inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull( SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) { return a == def ? nullptr : a; } template // Note that SuiteApiResolver inherits from T because // SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way // SuiteApiResolver can access them. struct SuiteApiResolver : T { // testing::Test is only forward declared at this point. So we make it a // dependend class for the compiler to be OK with it. using Test = typename std::conditional::type; static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename, int line_num) { SetUpTearDownSuiteFuncType test_case_fp = GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase); GTEST_CHECK_(!test_case_fp) << "Test can not provide both SetUpTestSuite and SetUpTestCase, please " "make sure there is only one present at " << filename << ":" << line_num; return test_case_fp; } static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename, int line_num) { SetUpTearDownSuiteFuncType test_case_fp = GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase); GTEST_CHECK_(!test_case_fp ) << "Test can not provide both TearDownTestSuite and TearDownTestCase," " please make sure there is only one present at" << filename << ":" << line_num; return test_case_fp; } }; template testing::TestInfo* RegisterTest(const char* test_suite_name, const char* test_name, const char* type_param, const char* value_param, const char* file, int line, Factory factory) { using TestT = typename std::remove_pointer::type; class FactoryImpl : public ::testing::internal::TestFactoryBase { public: explicit FactoryImpl(Factory f) : factory_(std::move(f)) {} ::testing::Test* CreateTest() override { return factory_(); } private: Factory factory_; }; return MakeAndRegisterTestInfo(test_suite_name, test_name, type_param, value_param, #ifndef GTEST_1_7_0 ::testing::internal::CodeLocation(__FILE__, __LINE__), #endif // GTEST_1_7_0 ::testing::internal::GetTypeId(), SuiteApiResolver::GetSetUpCaseOrSuite(file, line), SuiteApiResolver::GetTearDownCaseOrSuite(file, line), new FactoryImpl{ std::move(factory) }); }