inc/testrunnerswitcher.h (216 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 TESTRUNNERSWITCHER_H
#define TESTRUNNERSWITCHER_H
#include "macro_utils/macro_utils.h"
#ifdef __cplusplus
#include <cstring>
#include <cstdint>
#else
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <wchar.h>
#endif
#include "cppunittest_mutex_fixtures.h"
typedef void* TEST_MUTEX_HANDLE;
// a macro useful for disabling tests while debugging
#define DISABLED_TEST_FUNCTION(name) void name(void)
#ifdef USE_CTEST
#define TEST_DEFINE_ENUM_TYPE(type, ...) CTEST_DEFINE_ENUM_TYPE(type, __VA_ARGS__)
#define TEST_DEFINE_ENUM_TYPE_WITHOUT_INVALID(type, ...) CTEST_DEFINE_ENUM_TYPE_WITHOUT_INVALID(type, __VA_ARGS__)
// if both are defined do not forget to include the ctest to cpp unit test
#ifdef CPP_UNITTEST
#include "ctest_2_cppunittest.h"
#define TEST_SUITE_INITIALIZE(name) CTEST_SUITE_INITIALIZE(name, cppunittest_mutex_fixtures_suite_init)
#define TEST_SUITE_CLEANUP(name) CTEST_SUITE_CLEANUP(name, cppunittest_mutex_fixtures_suite_cleanup)
#define TEST_FUNCTION_INITIALIZE(name) CTEST_FUNCTION_INITIALIZE(name, cppunittest_mutex_fixtures_function_init)
#define TEST_FUNCTION_CLEANUP(name) CTEST_FUNCTION_CLEANUP(name, cppunittest_mutex_fixtures_function_cleanup)
#else
#define TEST_SUITE_INITIALIZE(name) CTEST_SUITE_INITIALIZE(name)
#define TEST_SUITE_CLEANUP(name) CTEST_SUITE_CLEANUP(name)
#define TEST_FUNCTION_INITIALIZE(name) CTEST_FUNCTION_INITIALIZE(name)
#define TEST_FUNCTION_CLEANUP(name) CTEST_FUNCTION_CLEANUP(name)
#endif
#include "ctest.h" // IWYU pragma: export
#define BEGIN_TEST_SUITE(name) CTEST_BEGIN_TEST_SUITE(name)
#define END_TEST_SUITE(name) CTEST_END_TEST_SUITE(name)
#define TEST_FUNCTION(name) CTEST_FUNCTION(name)
#define ASSERT_ARE_EQUAL CTEST_ASSERT_ARE_EQUAL
#define ASSERT_ARE_NOT_EQUAL CTEST_ASSERT_ARE_NOT_EQUAL
#define ASSERT_FAIL CTEST_ASSERT_FAIL
#define ASSERT_IS_NULL CTEST_ASSERT_IS_NULL
#define ASSERT_IS_NOT_NULL CTEST_ASSERT_IS_NOT_NULL
#define ASSERT_IS_TRUE CTEST_ASSERT_IS_TRUE
#define ASSERT_IS_FALSE CTEST_ASSERT_IS_FALSE
#define RUN_TEST_SUITE(...) CTEST_RUN_TEST_SUITE(__VA_ARGS__)
#define RUN_TEST_SUITE_WITH_LEAK_CHECK_RETRIES(...) CTEST_RUN_TEST_SUITE_WITH_LEAK_CHECK_RETRIES(__VA_ARGS__)
#define TEST_MUTEX_CREATE() (TEST_MUTEX_HANDLE)1
// the strlen check is simply to shut the compiler up and not create a hell of #pragma warning suppress
#define TEST_MUTEX_ACQUIRE(mutex) (strlen("a") == 0)
#define TEST_MUTEX_RELEASE(mutex)
#define TEST_MUTEX_DESTROY(mutex)
#elif defined CPP_UNITTEST
#ifdef _MSC_VER
#pragma warning(disable:4505)
#endif
#include "CppUnitTest.h"
#include "testmutex.h"
#include "ctrs_sprintf.h"
#include "ctest.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
typedef char* char_ptr;
typedef wchar_t* wchar_ptr;
typedef void* void_ptr;
#ifdef CPPUNITTEST_SYMBOL
extern "C" void CPPUNITTEST_SYMBOL(void) {}
#endif
#define BEGIN_TEST_SUITE(name) TEST_CLASS(name) {
#define END_TEST_SUITE(name) };
#define TEST_SUITE_INITIALIZE(name) TEST_CLASS_INITIALIZE(name)
#define TEST_SUITE_CLEANUP(name) TEST_CLASS_CLEANUP(name)
#define TEST_FUNCTION_INITIALIZE(name) TEST_METHOD_INITIALIZE(name)
#define TEST_FUNCTION_CLEANUP(name) TEST_METHOD_CLEANUP(name)
#define TEST_FUNCTION(name) TEST_METHOD(name)
// these are generic macros for formatting the optional message
// they can be used in all the ASSERT macros without repeating the code over and over again
#define CONSTRUCT_CTRS_MESSAGE_FORMATTED(format, ...) \
MU_IF(MU_COUNT_ARG(__VA_ARGS__), ctrs_sprintf_char(format, __VA_ARGS__), ctrs_sprintf_char(format));
#define CONSTRUCT_CTRS_MESSAGE_FORMATTED_EMPTY(...) \
NULL
#define CONSTRUCT_CTRS_MESSAGE(...) \
MU_IF(MU_COUNT_ARG(__VA_ARGS__), CONSTRUCT_CTRS_MESSAGE_FORMATTED, CONSTRUCT_CTRS_MESSAGE_FORMATTED_EMPTY)(__VA_ARGS__)
#define ASSERT_ARE_EQUAL(type, A, B, ...) \
do \
{ \
char* ctrs_message = CONSTRUCT_CTRS_MESSAGE(__VA_ARGS__); \
std::wstring cppUnitTestMessage = ToString(ctrs_message); \
ctrs_sprintf_free(ctrs_message); \
Assert::AreEqual((type)(A), (type)(B), cppUnitTestMessage.c_str()); \
} while ((void)0, 0)
#define ASSERT_ARE_NOT_EQUAL(type, A, B, ...) \
do \
{ \
char* ctrs_message = CONSTRUCT_CTRS_MESSAGE(__VA_ARGS__); \
std::wstring cppUnitTestMessage = ToString(ctrs_message); \
ctrs_sprintf_free(ctrs_message); \
Assert::AreNotEqual((type)(A), (type)(B), cppUnitTestMessage.c_str()); \
} while ((void)0, 0)
#define ASSERT_FAIL(...) \
do \
{ \
char* ctrs_message = CONSTRUCT_CTRS_MESSAGE(__VA_ARGS__); \
std::wstring cppUnitTestMessage = ToString(ctrs_message); \
ctrs_sprintf_free(ctrs_message); \
Assert::Fail(cppUnitTestMessage.c_str()); \
} while ((void)0, 0)
#define ASSERT_IS_TRUE(expression, ...) \
do \
{ \
char* ctrs_message = CONSTRUCT_CTRS_MESSAGE(__VA_ARGS__); \
std::wstring cppUnitTestMessage = ToString(ctrs_message); \
ctrs_sprintf_free(ctrs_message); \
Assert::IsTrue((expression), cppUnitTestMessage.c_str()); \
} while ((void)0, 0)
#define ASSERT_IS_FALSE(expression, ...) \
do \
{ \
char* ctrs_message = CONSTRUCT_CTRS_MESSAGE(__VA_ARGS__); \
std::wstring cppUnitTestMessage = ToString(ctrs_message); \
ctrs_sprintf_free(ctrs_message); \
Assert::IsFalse((expression), cppUnitTestMessage.c_str()); \
} while ((void)0, 0)
#define ASSERT_IS_NOT_NULL(value, ...) \
do \
{ \
char* ctrs_message = CONSTRUCT_CTRS_MESSAGE(__VA_ARGS__); \
std::wstring cppUnitTestMessage = ToString(ctrs_message); \
ctrs_sprintf_free(ctrs_message); \
Assert::IsNotNull((value), cppUnitTestMessage.c_str()); \
} while ((void)0, 0)
#define ASSERT_IS_NULL(value, ...) \
do \
{ \
char* ctrs_message = CONSTRUCT_CTRS_MESSAGE(__VA_ARGS__); \
std::wstring cppUnitTestMessage = ToString(ctrs_message); \
ctrs_sprintf_free(ctrs_message); \
Assert::IsNull((value), cppUnitTestMessage.c_str()); \
} while ((void)0, 0)
#define RUN_TEST_SUITE(...)
#define RUN_TEST_SUITE_WITH_LEAK_CHECK_RETRIES(...)
#define TEST_MUTEX_CREATE() testmutex_create()
#define TEST_MUTEX_ACQUIRE(mutex) testmutex_acquire(mutex)
#define TEST_MUTEX_RELEASE(mutex) testmutex_release(mutex)
#define TEST_MUTEX_DESTROY(mutex) testmutex_destroy(mutex)
#define TEST_USE_CTEST_FUNCTIONS_FOR_TYPE(my_type) \
namespace Microsoft \
{ \
namespace VisualStudio \
{ \
namespace CppUnitTestFramework \
{ \
template<> \
inline std::wstring ToString<my_type>(const my_type& value) \
{ \
char temp_str[1024]; \
std::wstring result; \
MU_C2(my_type,_ToString)(temp_str, sizeof(temp_str), value); \
int size_needed_in_chars = MultiByteToWideChar(CP_UTF8, 0, &temp_str[0], -1, NULL, 0); \
if (size_needed_in_chars == 0) \
{ \
result = L""; \
} \
else \
{ \
WCHAR* widechar_string = (WCHAR*)malloc(size_needed_in_chars * sizeof(WCHAR)); \
if (widechar_string == NULL) \
{ \
result = L""; \
} \
else \
{ \
if (MultiByteToWideChar(CP_UTF8, 0, temp_str, -1, widechar_string, size_needed_in_chars) == 0) \
{ \
result = L""; \
} \
else \
{ \
result = std::wstring(widechar_string); \
} \
free(widechar_string); \
} \
} \
return result; \
} \
template<> \
static void Assert::AreEqual<my_type>(const my_type& expected, const my_type& actual, const wchar_t* message, const __LineInfo* pLineInfo) \
{ \
FailOnCondition((MU_C2(my_type,_Compare)(expected, actual) == 0), EQUALS_MESSAGE(expected, actual, message), pLineInfo); \
} \
} \
} \
} \
#define TEST_DEFINE_ENUM_TYPE(type, ...) \
CTEST_DEFINE_ENUM_TYPE(type, __VA_ARGS__) \
TEST_USE_CTEST_FUNCTIONS_FOR_TYPE(type)
#define TEST_DEFINE_ENUM_TYPE_WITHOUT_INVALID(type, ...) \
CTEST_DEFINE_ENUM_TYPE_WITHOUT_INVALID(type, __VA_ARGS__) \
TEST_USE_CTEST_FUNCTIONS_FOR_TYPE(type)
/*because for some reason this is not defined by Visual Studio, it is defined here, so it is not multiplied in every single other unittest*/
namespace Microsoft
{
namespace VisualStudio
{
namespace CppUnitTestFramework
{
/*Visual Studio 2019 version 16.1.0 has in C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\VS\UnitTest\include\CppUnitTestAssert.h the same template*/
#if _MSC_VER < 1921
template<> inline std::wstring ToString<int64_t>(const int64_t& t)
{
RETURN_WIDE_STRING(t);
}
#endif
/*Visual Studio 2022 version 17.5.3 has in C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\VS\UnitTest\include\CppUnitTestAssert.h the same template*/
#if _MSC_VER < 1935
template<> inline std::wstring ToString<uint16_t>(const uint16_t& t)
{
RETURN_WIDE_STRING(t);
}
#endif
}
}
}
#else
#error No test runner defined
#endif
#endif