Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
catch_test_registry.h
Go to the documentation of this file.
1/*
2 * Created by Phil on 18/10/2010.
3 * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
4 *
5 * Distributed under the Boost Software License, Version 1.0. (See accompanying
6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 */
8#ifndef TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
9#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
10
11#include "catch_common.h"
14#include "catch_stringref.h"
15#include "catch_type_traits.hpp"
17#include "catch_meta.hpp"
18
19namespace Catch {
20
21template<typename C>
22class TestInvokerAsMethod : public ITestInvoker {
23 void (C::*m_testAsMethod)();
24public:
25 TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
26
27 void invoke() const override {
28 C obj;
29 (obj.*m_testAsMethod)();
30 }
31};
32
33auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
34
35template<typename C>
36auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
37 return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
38}
39
40struct NameAndTags {
41 NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
44};
45
46struct AutoReg : NonCopyable {
47 AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
49};
50
51} // end namespace Catch
52
53#if defined(CATCH_CONFIG_DISABLE)
54 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
55 static void TestName()
56 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
57 namespace{ \
58 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
59 void test(); \
60 }; \
61 } \
62 void TestName::test()
63 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... ) \
64 template<typename TestType> \
65 static void TestName()
66 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
67 namespace{ \
68 template<typename TestType> \
69 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
70 void test(); \
71 }; \
72 } \
73 template<typename TestType> \
74 void TestName::test()
75#endif
76
78 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
79 static void TestName(); \
80 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
81 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
82 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
83 static void TestName()
84 #define INTERNAL_CATCH_TESTCASE( ... ) \
85 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
86
88 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
89 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
90 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
91 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
92
94 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
95 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
96 namespace{ \
97 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
98 void test(); \
99 }; \
100 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
101 } \
102 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
103 void TestName::test()
104 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
105 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
106
108 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
109 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
110 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
111 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
112
114 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\
115 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
116 template<typename TestType> \
117 static void TestFunc();\
118 namespace {\
119 template<typename...Types> \
120 struct TestName{\
121 template<typename...Ts> \
122 TestName(Ts...names){\
123 CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
124 using expander = int[];\
125 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
126 }\
127 };\
128 INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \
129 }\
130 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
131 template<typename TestType> \
132 static void TestFunc()
133
134#if defined(CATCH_CPP17_OR_GREATER)
135#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case");
136#else
137#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case");
138#endif
139
140#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
141 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
142 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__ )
143#else
144 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \
145 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__ ) )
146#endif
147
148 #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\
149 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
150 TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\
151 return 0;\
152 }();
153
154 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, TmplTypes, TypesList) \
155 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
156 template<typename TestType> static void TestFuncName(); \
157 namespace { \
158 template<typename... Types> \
159 struct TestName { \
160 TestName() { \
161 CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...) \
162 int index = 0; \
163 using expander = int[]; \
164 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
165 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
166 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
167 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\
168 } \
169 }; \
170 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
171 using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)> \
172 ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestName>::type; \
173 TestInit(); \
174 return 0; \
175 }(); \
176 } \
177 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
178 template<typename TestType> \
179 static void TestFuncName()
180
181#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
182 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
183 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(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__)
184#else
185 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\
186 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( 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__ ) )
187#endif
188
189 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \
190 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
191 namespace{ \
192 template<typename TestType> \
193 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
194 void test();\
195 };\
196 template<typename...Types> \
197 struct TestNameClass{\
198 template<typename...Ts> \
199 TestNameClass(Ts...names){\
200 CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \
201 using expander = int[];\
202 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \
203 }\
204 };\
205 INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\
206 }\
207 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\
208 template<typename TestType> \
209 void TestName<TestType>::test()
210
211#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
212 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
213 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__ )
214#else
215 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \
216 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__ ) )
217#endif
218
219 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, TmplTypes, TypesList)\
220 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
221 template<typename TestType> \
222 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \
223 void test();\
224 };\
225 namespace {\
226 template<typename...Types>\
227 struct TestNameClass{\
228 TestNameClass(){\
229 CATCH_INTERNAL_CHECK_UNIQUE_TYPES(Types...)\
230 int index = 0;\
231 using expander = int[];\
232 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
233 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
234 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
235 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \
236 }\
237 };\
238 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
239 using TestInit = Catch::combine<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>\
240 ::with_types<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(TypesList)>::into<TestNameClass>::type;\
241 TestInit();\
242 return 0;\
243 }(); \
244 }\
245 CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
246 template<typename TestType> \
247 void TestName<TestType>::test()
248
249#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR
250 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
251 INTERNAL_CATCH_TEMPLATE_PRODUCT_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____ ), 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____ ), ClassName, Name, Tags, __VA_ARGS__ )
252#else
253 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\
254 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_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____ ), 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____ ), ClassName, Name, Tags, __VA_ARGS__ ) )
255#endif
256
257#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
TestInvokerAsMethod(void(C::*testAsMethod)()) noexcept
void invoke() const override
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:364
auto makeTestInvoker(void(*testAsFunction)()) noexcept -> ITestInvoker *
NameAndTags(StringRef const &name_=StringRef(), StringRef const &tags_=StringRef()) noexcept
yubihsm_pkcs11_object_template template