inc/ctest_2_cppunittest.h (75 lines of code) (raw):

// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. #ifndef CTEST_2_CPPUNITTEST_H #define CTEST_2_CPPUNITTEST_H #ifdef CPP_UNITTEST #include "macro_utils/macro_utils.h" #ifdef __cplusplus extern "C" { #endif // This structure matches 100% the structure used by CppUnitTest to store its metadata in the shared section where the metadata is stored typedef struct CTEST_2_CPPUNITTEST_MethodMetadata_TAG { const wchar_t* tag; const wchar_t* methodName; const unsigned char* helpMethodName; const unsigned char* helpMethodDecoratedName; const wchar_t* sourceFile; int lineNo; } CTEST_2_CPPUNITTEST_MethodMetadata; typedef enum CTEST_2_CPPUNITTEST_MemberMethodTypes_TAG { TestMethod, TestMethodSetup, TestMethodCleanup, TestObjectSetup, TestObjectCleanup, TestClassSetup, TestClassCleanup, } CTEST_2_CPPUNITTEST_MemberMethodTypes; typedef struct CTEST_2_CPPUNITTEST_MemberMethodInfo_TAG { CTEST_2_CPPUNITTEST_MemberMethodTypes methodType; union { void* pVoidMethod; void* pVoidStaticMethod; } method; const CTEST_2_CPPUNITTEST_MethodMetadata* metadata; } CTEST_2_CPPUNITTEST_MemberMethodInfo; // copied from CppUnitTest, do not have a better solution at the moment #define ALLOCATE_TESTDATA_SECTION_VERSION __declspec(allocate("testvers$")) #define ALLOCATE_TESTDATA_SECTION_CLASS __declspec(allocate("testdata$_A_class")) #define ALLOCATE_TESTDATA_SECTION_METHOD __declspec(allocate("testdata$_B_method")) #define ALLOCATE_TESTDATA_SECTION_ATTRIBUTE __declspec(allocate("testdata$_C_attribute")) // unfortunately we have to create the sections before using them // this code is also taken from CppUnitTest.h #pragma section("testvers$", read, shared) #pragma section("testdata$_A_class", read, shared) #pragma section("testdata$_B_method", read, shared) #pragma section("testdata$_C_attribute", read, shared) // The reader of the metadata really really wants to have in the helperMethodName the class to which the "methods" belong // Based on reverse engineering the code at https://devdiv.visualstudio.com/DevDiv/_git/VS?path=%2Fsrc%2Fvset%2FAgile%2FCppUnit%2FDiscoverer%2FTestMetaDataReaderForLatestVersion.cs&_a=contents&version=GBmain // these macros are used by ctest to generate extra metadata needed by CppUnitTest #define IMPLEMENT_CPP_UNIT_FIXTURE(infoTag, cppunittest_func_name, ctest_func_name, method_type) \ __declspec(dllexport) CTEST_2_CPPUNITTEST_MemberMethodInfo* __stdcall MU_C2(GetTestMethodInfo_, cppunittest_func_name)() \ { \ ALLOCATE_TESTDATA_SECTION_METHOD static const CTEST_2_CPPUNITTEST_MethodMetadata MU_C2(CppUnitTestMethodMetadata_, cppunittest_func_name) = \ { L"" infoTag, L"" MU_TOSTRING(cppunittest_func_name), (const unsigned char*)"DummyTestClass::" MU_TOSTRING(cppunittest_func_name), (const unsigned char*)(__FUNCDNAME__) }; \ static CTEST_2_CPPUNITTEST_MemberMethodInfo s_Info = { method_type, {NULL}, &MU_C2(CppUnitTestMethodMetadata_, cppunittest_func_name) }; \ s_Info.method.pVoidStaticMethod = (void*)ctest_func_name; \ return &s_Info; \ } #define CTEST_CUSTOM_TEST_SUITE_INITIALIZE_CODE(func_name) \ IMPLEMENT_CPP_UNIT_FIXTURE("TestClassInitializeInfo", func_name, TestSuiteInitialize, TestClassSetup) #define CTEST_CUSTOM_TEST_SUITE_CLEANUP_CODE(func_name) \ IMPLEMENT_CPP_UNIT_FIXTURE("TestClassCleanupInfo", func_name, TestSuiteCleanup, TestClassCleanup) #define CTEST_CUSTOM_TEST_FUNCTION_INITIALIZE_CODE(func_name) \ IMPLEMENT_CPP_UNIT_FIXTURE("TestMethodInitializeInfo", func_name, TestFunctionInitialize, TestMethodSetup) #define CTEST_CUSTOM_TEST_FUNCTION_CLEANUP_CODE(func_name) \ IMPLEMENT_CPP_UNIT_FIXTURE("TestMethodCleanupInfo", func_name, TestFunctionCleanup, TestMethodCleanup) #define CTEST_CUSTOM_TEST_FUNCTION_CODE(func_name) \ __declspec(dllexport) CTEST_2_CPPUNITTEST_MemberMethodInfo* __stdcall MU_C2(GetTestMethodInfo_, func_name)() \ { \ ALLOCATE_TESTDATA_SECTION_METHOD static const CTEST_2_CPPUNITTEST_MethodMetadata MU_C2(CppUnitTestMethodMetadata_, func_name) = \ { L"TestMethodInfo", L"" MU_TOSTRING(func_name), (const unsigned char*)("DummyTestClass::__GetTestMethodInfo_" MU_TOSTRING(func_name)), (const unsigned char*)(__FUNCDNAME__), L"" __FILE__, __LINE__ }; \ static CTEST_2_CPPUNITTEST_MemberMethodInfo s_Info = { TestMethod, {NULL}, &MU_C2(CppUnitTestMethodMetadata_, func_name) }; \ s_Info.method.pVoidStaticMethod = (void*)func_name; \ return &s_Info; \ } #ifdef __cplusplus } #endif #endif #endif /* CTEST_2_CPPUNITTEST_H */