mirror of
https://github.com/catchorg/Catch2.git
synced 2025-08-01 12:55:40 +02:00
Add support for templated tests
This adds support for templated tests and test methods via `TEMPLATE_TEST_CASE` and `TEMPLATE_TEST_CASE_METHOD` macros. These work mostly just like their regular counterparts*, but take an unlimited** number of types as their last arguments. * Unlike the plain `TEST_CASE*` macros, the `TEMPLATE*` variants require a tag string. ** In practice there is limit of about 300 types.
This commit is contained in:

committed by
Martin Hořeňovský

parent
489a41012e
commit
2d906a92cb
@@ -145,6 +145,15 @@
|
||||
|
||||
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
|
||||
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
|
||||
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
|
||||
#else
|
||||
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
|
||||
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
|
||||
#define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ )
|
||||
#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ )
|
||||
@@ -214,6 +223,15 @@
|
||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
|
||||
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )
|
||||
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )
|
||||
#else
|
||||
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )
|
||||
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)
|
||||
#define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )
|
||||
#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" )
|
||||
@@ -292,6 +310,14 @@ using Catch::Detail::Approx;
|
||||
|
||||
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
|
||||
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
|
||||
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
|
||||
#else
|
||||
#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
|
||||
#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
|
||||
#endif
|
||||
|
||||
// "BDD-style" convenience wrappers
|
||||
#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
|
||||
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className )
|
||||
@@ -355,6 +381,13 @@ using Catch::Detail::Approx;
|
||||
#define SUCCEED( ... ) (void)(0)
|
||||
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
|
||||
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) )
|
||||
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className )
|
||||
#else
|
||||
#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) )
|
||||
#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) )
|
||||
#endif
|
||||
|
||||
#define STATIC_REQUIRE( ... ) (void)(0)
|
||||
#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
|
||||
|
@@ -136,6 +136,13 @@
|
||||
# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH
|
||||
# endif
|
||||
|
||||
// MSVC traditional preprocessor needs some workaround for __VA_ARGS__
|
||||
// _MSVC_TRADITIONAL == 0 means new conformant preprocessor
|
||||
// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor
|
||||
# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)
|
||||
# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
# endif
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -254,6 +261,9 @@
|
||||
#define CATCH_CATCH_ANON(type) catch (type)
|
||||
#endif
|
||||
|
||||
#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)
|
||||
#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
|
||||
|
||||
|
74
include/internal/catch_preprocessor.hpp
Normal file
74
include/internal/catch_preprocessor.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Created by Jozef on 12/11/2018.
|
||||
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED
|
||||
|
||||
#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__
|
||||
#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))
|
||||
#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))
|
||||
#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))
|
||||
#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))
|
||||
#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))
|
||||
|
||||
#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__
|
||||
// MSVC needs more evaluations
|
||||
#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))
|
||||
#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))
|
||||
#else
|
||||
#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define CATCH_REC_END(...)
|
||||
#define CATCH_REC_OUT
|
||||
|
||||
#define CATCH_EMPTY()
|
||||
#define CATCH_DEFER(id) id CATCH_EMPTY()
|
||||
|
||||
#define CATCH_REC_GET_END2() 0, CATCH_REC_END
|
||||
#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2
|
||||
#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1
|
||||
#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT
|
||||
#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)
|
||||
#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)
|
||||
|
||||
#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
|
||||
#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )
|
||||
#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )
|
||||
|
||||
#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
|
||||
#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )
|
||||
#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )
|
||||
|
||||
// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,
|
||||
// and passes userdata as the first parameter to each invocation,
|
||||
// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)
|
||||
#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
|
||||
|
||||
#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))
|
||||
|
||||
#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
|
||||
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
|
||||
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
|
||||
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
|
||||
|
||||
#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)
|
||||
|
||||
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__)
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__
|
||||
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))
|
||||
#else
|
||||
// MSVC is adding extra space and needs more calls to properly remove ()
|
||||
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__
|
||||
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__)
|
||||
#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED
|
@@ -12,6 +12,8 @@
|
||||
#include "catch_interfaces_testcase.h"
|
||||
#include "catch_compiler_capabilities.h"
|
||||
#include "catch_stringref.h"
|
||||
#include "catch_type_traits.hpp"
|
||||
#include "catch_preprocessor.hpp"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -47,22 +49,28 @@ struct AutoReg : NonCopyable {
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)
|
||||
#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__
|
||||
#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__
|
||||
#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF
|
||||
|
||||
#if defined(CATCH_CONFIG_DISABLE)
|
||||
#define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
|
||||
static void TestName()
|
||||
#define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
|
||||
namespace{ \
|
||||
struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
|
||||
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
|
||||
void test(); \
|
||||
}; \
|
||||
} \
|
||||
void TestName::test()
|
||||
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... ) \
|
||||
template<typename TestType> \
|
||||
static void TestName()
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
|
||||
namespace{ \
|
||||
template<typename TestType> \
|
||||
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
|
||||
void test(); \
|
||||
}; \
|
||||
} \
|
||||
template<typename TestType> \
|
||||
void TestName::test()
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -85,7 +93,7 @@ struct AutoReg : NonCopyable {
|
||||
#define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
namespace{ \
|
||||
struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \
|
||||
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
|
||||
void test(); \
|
||||
}; \
|
||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||
@@ -101,5 +109,75 @@ struct AutoReg : NonCopyable {
|
||||
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
|
||||
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
template<typename TestType> \
|
||||
static void TestFunc();\
|
||||
namespace {\
|
||||
template<typename...Types> \
|
||||
struct TestName{\
|
||||
template<typename...Ts> \
|
||||
TestName(Ts...names){\
|
||||
CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
|
||||
using expander = int[];\
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
|
||||
}\
|
||||
};\
|
||||
INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
|
||||
}\
|
||||
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
|
||||
template<typename TestType> \
|
||||
static void TestFunc()
|
||||
|
||||
#if defined(CATCH_CPP17_OR_GREATER)
|
||||
#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
|
||||
#else
|
||||
#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
|
||||
#endif
|
||||
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
|
||||
INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ )
|
||||
#else
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
|
||||
INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) )
|
||||
#endif
|
||||
|
||||
#define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
|
||||
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
|
||||
TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
|
||||
return 0;\
|
||||
}();
|
||||
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
|
||||
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
|
||||
namespace{ \
|
||||
template<typename TestType> \
|
||||
struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
|
||||
void test();\
|
||||
};\
|
||||
template<typename...Types> \
|
||||
struct TestNameClass{\
|
||||
template<typename...Ts> \
|
||||
TestNameClass(Ts...names){\
|
||||
CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
|
||||
using expander = int[];\
|
||||
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
|
||||
}\
|
||||
};\
|
||||
INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
|
||||
}\
|
||||
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
|
||||
template<typename TestType> \
|
||||
void TestName<TestType>::test()
|
||||
|
||||
#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
|
||||
INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ )
|
||||
#else
|
||||
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
|
||||
INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) )
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
|
||||
|
38
include/internal/catch_type_traits.hpp
Normal file
38
include/internal/catch_type_traits.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Created by Jozef on 12/11/2018.
|
||||
* Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
|
||||
|
||||
namespace Catch{
|
||||
|
||||
#ifdef CATCH_CPP17_OR_GREATER
|
||||
template <typename...>
|
||||
inline constexpr auto is_unique = std::true_type{};
|
||||
|
||||
template <typename T, typename... Rest>
|
||||
inline constexpr auto is_unique<T, Rest...> = std::bool_constant<
|
||||
(!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
|
||||
>{};
|
||||
#else
|
||||
|
||||
template <typename...>
|
||||
struct is_unique : std::true_type{};
|
||||
|
||||
template <typename T0, typename T1, typename... Rest>
|
||||
struct is_unique<T0, T1, Rest...> : std::integral_constant
|
||||
<bool,
|
||||
!std::is_same<T0, T1>::value
|
||||
&& is_unique<T0, Rest...>::value
|
||||
&& is_unique<T1, Rest...>::value
|
||||
>{};
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED
|
Reference in New Issue
Block a user