File indexing completed on 2025-09-17 08:53:29
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_TEST_REGISTRY_HPP_INCLUDED
0009 #define CATCH_TEST_REGISTRY_HPP_INCLUDED
0010
0011 #include <catch2/internal/catch_config_static_analysis_support.hpp>
0012 #include <catch2/internal/catch_source_line_info.hpp>
0013 #include <catch2/internal/catch_noncopyable.hpp>
0014 #include <catch2/interfaces/catch_interfaces_test_invoker.hpp>
0015 #include <catch2/internal/catch_stringref.hpp>
0016 #include <catch2/internal/catch_unique_ptr.hpp>
0017 #include <catch2/internal/catch_unique_name.hpp>
0018 #include <catch2/internal/catch_preprocessor_remove_parens.hpp>
0019
0020
0021
0022
0023 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
0024 #pragma GCC diagnostic ignored "-Wunused-variable"
0025 #endif
0026
0027
0028
0029 namespace Catch {
0030
0031 template<typename C>
0032 class TestInvokerAsMethod : public ITestInvoker {
0033 void (C::*m_testAsMethod)();
0034 public:
0035 constexpr TestInvokerAsMethod( void ( C::*testAsMethod )() ) noexcept:
0036 m_testAsMethod( testAsMethod ) {}
0037
0038 void invoke() const override {
0039 C obj;
0040 (obj.*m_testAsMethod)();
0041 }
0042 };
0043
0044 Detail::unique_ptr<ITestInvoker> makeTestInvoker( void(*testAsFunction)() );
0045
0046 template<typename C>
0047 Detail::unique_ptr<ITestInvoker> makeTestInvoker( void (C::*testAsMethod)() ) {
0048 return Detail::make_unique<TestInvokerAsMethod<C>>( testAsMethod );
0049 }
0050
0051 template <typename C>
0052 class TestInvokerFixture : public ITestInvoker {
0053 void ( C::*m_testAsMethod )() const;
0054 Detail::unique_ptr<C> m_fixture = nullptr;
0055
0056 public:
0057 constexpr TestInvokerFixture( void ( C::*testAsMethod )() const ) noexcept:
0058 m_testAsMethod( testAsMethod ) {}
0059
0060 void prepareTestCase() override {
0061 m_fixture = Detail::make_unique<C>();
0062 }
0063
0064 void tearDownTestCase() override {
0065 m_fixture.reset();
0066 }
0067
0068 void invoke() const override {
0069 auto* f = m_fixture.get();
0070 ( f->*m_testAsMethod )();
0071 }
0072 };
0073
0074 template<typename C>
0075 Detail::unique_ptr<ITestInvoker> makeTestInvokerFixture( void ( C::*testAsMethod )() const ) {
0076 return Detail::make_unique<TestInvokerFixture<C>>( testAsMethod );
0077 }
0078
0079 struct NameAndTags {
0080 constexpr NameAndTags( StringRef name_ = StringRef(),
0081 StringRef tags_ = StringRef() ) noexcept:
0082 name( name_ ), tags( tags_ ) {}
0083 StringRef name;
0084 StringRef tags;
0085 };
0086
0087 struct AutoReg : Detail::NonCopyable {
0088 AutoReg( Detail::unique_ptr<ITestInvoker> invoker, SourceLineInfo const& lineInfo, StringRef classOrMethod, NameAndTags const& nameAndTags ) noexcept;
0089 };
0090
0091 }
0092
0093 #if defined(CATCH_CONFIG_DISABLE)
0094 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
0095 static inline void TestName()
0096 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
0097 namespace{ \
0098 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
0099 void test(); \
0100 }; \
0101 } \
0102 void TestName::test()
0103 #endif
0104
0105
0106 #if !defined(CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT)
0107
0108
0109 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
0110 static void TestName(); \
0111 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0112 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0113 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
0114 namespace{ const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } \
0115 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
0116 static void TestName()
0117 #define INTERNAL_CATCH_TESTCASE( ... ) \
0118 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )
0119
0120 #else
0121
0122
0123
0124 namespace Catch {
0125 namespace Detail {
0126 struct DummyUse {
0127 DummyUse( void ( * )( int ), Catch::NameAndTags const& );
0128 };
0129 }
0130 }
0131
0132
0133
0134
0135
0136
0137 static int catchInternalSectionHint = 0;
0138
0139 # define INTERNAL_CATCH_TESTCASE2( fname, ... ) \
0140 static void fname( int ); \
0141 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0142 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0143 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
0144 static const Catch::Detail::DummyUse INTERNAL_CATCH_UNIQUE_NAME( \
0145 dummyUser )( &(fname), Catch::NameAndTags{ __VA_ARGS__ } ); \
0146 CATCH_INTERNAL_SUPPRESS_SHADOW_WARNINGS \
0147 static void fname( [[maybe_unused]] int catchInternalSectionHint ) \
0148 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
0149 # define INTERNAL_CATCH_TESTCASE( ... ) \
0150 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( dummyFunction ), __VA_ARGS__ )
0151
0152
0153 #endif
0154
0155
0156 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
0157 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0158 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0159 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
0160 namespace{ \
0161 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \
0162 void test(); \
0163 }; \
0164 const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
0165 Catch::makeTestInvoker( &TestName::test ), \
0166 CATCH_INTERNAL_LINEINFO, \
0167 #ClassName##_catch_sr, \
0168 Catch::NameAndTags{ __VA_ARGS__ } ); \
0169 } \
0170 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
0171 void TestName::test()
0172 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
0173 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ )
0174
0175
0176 #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2( TestName, ClassName, ... ) \
0177 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0178 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0179 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
0180 namespace { \
0181 struct TestName : INTERNAL_CATCH_REMOVE_PARENS( ClassName ) { \
0182 void test() const; \
0183 }; \
0184 const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
0185 Catch::makeTestInvokerFixture( &TestName::test ), \
0186 CATCH_INTERNAL_LINEINFO, \
0187 #ClassName##_catch_sr, \
0188 Catch::NameAndTags{ __VA_ARGS__ } ); \
0189 } \
0190 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
0191 void TestName::test() const
0192 #define INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE( ClassName, ... ) \
0193 INTERNAL_CATCH_TEST_CASE_PERSISTENT_FIXTURE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), ClassName, __VA_ARGS__ )
0194
0195
0196
0197 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
0198 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0199 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0200 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
0201 namespace { \
0202 const Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( \
0203 Catch::makeTestInvoker( &QualifiedMethod ), \
0204 CATCH_INTERNAL_LINEINFO, \
0205 "&" #QualifiedMethod##_catch_sr, \
0206 Catch::NameAndTags{ __VA_ARGS__ } ); \
0207 } \
0208 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
0209
0210
0211
0212 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
0213 do { \
0214 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0215 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0216 CATCH_INTERNAL_SUPPRESS_UNUSED_VARIABLE_WARNINGS \
0217 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); \
0218 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
0219 } while(false)
0220
0221
0222 #endif