2010-11-10 00:24:00 +01:00
/*
* Created by Phil on 18 / 10 / 2010.
* Copyright 2010 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)
*/
2012-09-17 07:42:29 +02:00
# ifndef TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
# define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
2010-11-10 00:24:00 +01:00
# include "catch_common.h"
2011-01-07 20:57:32 +01:00
# include "catch_interfaces_testcase.h"
2015-03-04 08:08:53 +01:00
# include "catch_compiler_capabilities.h"
2017-07-12 23:39:31 +02:00
# include "catch_stringref.h"
2018-11-08 07:26:39 +01:00
# include "catch_type_traits.hpp"
# include "catch_preprocessor.hpp"
2010-11-10 00:24:00 +01:00
2012-05-16 09:02:20 +02:00
namespace Catch {
2013-07-03 20:14:59 +02:00
2010-11-10 00:24:00 +01:00
template < typename C >
2017-07-12 19:01:54 +02:00
class TestInvokerAsMethod : public ITestInvoker {
void ( C : : * m_testAsMethod ) ( ) ;
2012-05-10 22:46:46 +02:00
public :
2017-07-13 09:25:47 +02:00
TestInvokerAsMethod ( void ( C : : * testAsMethod ) ( ) ) noexcept : m_testAsMethod ( testAsMethod ) { }
2013-07-03 20:14:59 +02:00
2017-07-12 19:01:54 +02:00
void invoke ( ) const override {
2010-11-10 00:24:00 +01:00
C obj ;
2017-07-12 19:01:54 +02:00
( obj . * m_testAsMethod ) ( ) ;
2010-11-10 00:24:00 +01:00
}
} ;
2011-01-07 20:57:32 +01:00
2017-07-13 09:25:47 +02:00
auto makeTestInvoker ( void ( * testAsFunction ) ( ) ) noexcept - > ITestInvoker * ;
2013-03-16 21:18:52 +01:00
2017-07-12 23:39:31 +02:00
template < typename C >
2017-07-13 09:25:47 +02:00
auto makeTestInvoker ( void ( C : : * testAsMethod ) ( ) ) noexcept - > ITestInvoker * {
return new ( std : : nothrow ) TestInvokerAsMethod < C > ( testAsMethod ) ;
2017-07-12 23:39:31 +02:00
}
2013-03-16 21:18:52 +01:00
2017-07-12 23:39:31 +02:00
struct NameAndTags {
2018-03-02 16:22:18 +01:00
NameAndTags ( StringRef const & name_ = StringRef ( ) , StringRef const & tags_ = StringRef ( ) ) noexcept ;
2017-07-12 23:39:31 +02:00
StringRef name ;
StringRef tags ;
2010-11-10 00:24:00 +01:00
} ;
2013-07-03 20:14:59 +02:00
2017-07-12 23:39:31 +02:00
struct AutoReg : NonCopyable {
2018-03-02 16:22:18 +01:00
AutoReg ( ITestInvoker * invoker , SourceLineInfo const & lineInfo , StringRef const & classOrMethod , NameAndTags const & nameAndTags ) noexcept ;
2017-09-07 16:51:33 +02:00
~ AutoReg ( ) ;
2017-07-12 23:39:31 +02:00
} ;
2015-11-20 17:54:07 +01:00
2010-11-10 00:24:00 +01:00
} // end namespace Catch
2017-08-27 17:03:32 +02:00
# 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 { \
2018-11-08 07:26:39 +01:00
struct TestName : INTERNAL_CATCH_REMOVE_PARENS ( ClassName ) { \
2017-08-27 17:03:32 +02:00
void test ( ) ; \
} ; \
} \
void TestName : : test ( )
2018-11-08 07:26:39 +01:00
# 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 ( )
2017-08-27 17:03:32 +02:00
# endif
2013-03-16 21:18:52 +01:00
///////////////////////////////////////////////////////////////////////////////
2015-12-15 08:50:51 +01:00
# define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName ( ) ; \
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2018-07-22 14:06:21 +02:00
namespace { Catch : : AutoReg INTERNAL_CATCH_UNIQUE_NAME ( autoRegistrar ) ( Catch : : makeTestInvoker ( & TestName ) , CATCH_INTERNAL_LINEINFO , Catch : : StringRef ( ) , Catch : : NameAndTags { __VA_ARGS__ } ) ; } /* NOLINT */ \
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
2015-12-15 08:50:51 +01:00
static void TestName ( )
2013-03-16 21:18:52 +01:00
# define INTERNAL_CATCH_TESTCASE( ... ) \
2015-12-15 08:50:51 +01:00
INTERNAL_CATCH_TESTCASE2 ( INTERNAL_CATCH_UNIQUE_NAME ( ____C_A_T_C_H____T_E_S_T____ ) , __VA_ARGS__ )
2013-03-16 21:18:52 +01:00
///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2017-08-10 11:34:26 +02:00
namespace { Catch : : AutoReg INTERNAL_CATCH_UNIQUE_NAME ( autoRegistrar ) ( Catch : : makeTestInvoker ( & QualifiedMethod ) , CATCH_INTERNAL_LINEINFO , " & " # QualifiedMethod , Catch : : NameAndTags { __VA_ARGS__ } ) ; } /* NOLINT */ \
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
2013-03-16 21:18:52 +01:00
///////////////////////////////////////////////////////////////////////////////
2015-12-15 08:50:51 +01:00
# define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2013-03-16 21:18:52 +01:00
namespace { \
2018-11-08 07:26:39 +01:00
struct TestName : INTERNAL_CATCH_REMOVE_PARENS ( ClassName ) { \
2013-03-16 21:18:52 +01:00
void test ( ) ; \
} ; \
2017-08-10 11:34:26 +02:00
Catch : : AutoReg INTERNAL_CATCH_UNIQUE_NAME ( autoRegistrar ) ( Catch : : makeTestInvoker ( & TestName : : test ) , CATCH_INTERNAL_LINEINFO , # ClassName , Catch : : NameAndTags { __VA_ARGS__ } ) ; /* NOLINT */ \
2013-03-16 21:18:52 +01:00
} \
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
2015-12-15 08:50:51 +01:00
void TestName : : test ( )
# define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
INTERNAL_CATCH_TEST_CASE_METHOD2 ( INTERNAL_CATCH_UNIQUE_NAME ( ____C_A_T_C_H____T_E_S_T____ ) , ClassName , __VA_ARGS__ )
2013-03-16 21:18:52 +01:00
2015-11-20 17:54:07 +01:00
///////////////////////////////////////////////////////////////////////////////
# define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
2018-07-22 14:06:21 +02:00
Catch : : AutoReg INTERNAL_CATCH_UNIQUE_NAME ( autoRegistrar ) ( Catch : : makeTestInvoker ( Function ) , CATCH_INTERNAL_LINEINFO , Catch : : StringRef ( ) , Catch : : NameAndTags { __VA_ARGS__ } ) ; /* NOLINT */ \
2017-09-07 16:51:33 +02:00
CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
2015-11-20 17:54:07 +01:00
2018-11-08 07:26:39 +01:00
///////////////////////////////////////////////////////////////////////////////
# 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
2010-12-27 21:51:06 +01:00
2012-09-17 07:42:29 +02:00
# endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED