Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:29

0001 
0002 //              Copyright Catch2 Authors
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //   (See accompanying file LICENSE.txt or copy at
0005 //        https://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // SPDX-License-Identifier: BSL-1.0
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 // GCC 5 and older do not properly handle disabling unused-variable warning
0021 // with a _Pragma. This means that we have to leak the suppression to the
0022 // user code as well :-(
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 } // end namespace Catch
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__ } ); } /* NOLINT */ \
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  // ^^ !CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT | vv CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
0121 
0122 
0123 // Dummy registrator for the dumy test case macros
0124 namespace Catch {
0125     namespace Detail {
0126         struct DummyUse {
0127             DummyUse( void ( * )( int ), Catch::NameAndTags const& );
0128         };
0129     } // namespace Detail
0130 } // namespace Catch
0131 
0132 // Note that both the presence of the argument and its exact name are
0133 // necessary for the section support.
0134 
0135 // We provide a shadowed variable so that a `SECTION` inside non-`TEST_CASE`
0136 // tests can compile. The redefined `TEST_CASE` shadows this with param.
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 // CATCH_CONFIG_EXPERIMENTAL_STATIC_ANALYSIS_SUPPORT
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__ } ); /* NOLINT */ \
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__ } ); /* NOLINT */             \
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     } /* NOLINT */ \
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__ } ); /* NOLINT */ \
0218             CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \
0219         } while(false)
0220 
0221 
0222 #endif // CATCH_TEST_REGISTRY_HPP_INCLUDED