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"
12 #include "catch_interfaces_testcase.h"
13 #include "catch_compiler_capabilities.h"
14 #include "catch_stringref.h"
15 
16 namespace Catch {
17 
18 template<typename C>
19 class TestInvokerAsMethod : public ITestInvoker {
20     void (C::*m_testAsMethod)();
21 public:
TestInvokerAsMethod(void (C::* testAsMethod)())22     TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}
23 
invoke()24     void invoke() const override {
25         C obj;
26         (obj.*m_testAsMethod)();
27     }
28 };
29 
30 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;
31 
32 template<typename C>
33 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {
34     return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );
35 }
36 
37 struct NameAndTags {
38     NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;
39     StringRef name;
40     StringRef tags;
41 };
42 
43 struct AutoReg : NonCopyable {
44     AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;
45     ~AutoReg();
46 };
47 
48 } // end namespace Catch
49 
50 #if defined(CATCH_CONFIG_DISABLE)
51     #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \
52         static void TestName()
53     #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \
54         namespace{                        \
55             struct TestName : ClassName { \
56                 void test();              \
57             };                            \
58         }                                 \
59         void TestName::test()
60 
61 #endif
62 
63     ///////////////////////////////////////////////////////////////////////////////
64     #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
65         static void TestName(); \
66         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
67         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
68         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
69         static void TestName()
70     #define INTERNAL_CATCH_TESTCASE( ... ) \
71         INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ )
72 
73     ///////////////////////////////////////////////////////////////////////////////
74     #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
75         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
76         namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \
77         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
78 
79     ///////////////////////////////////////////////////////////////////////////////
80     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\
81         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
82         namespace{ \
83             struct TestName : ClassName{ \
84                 void test(); \
85             }; \
86             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
87         } \
88         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \
89         void TestName::test()
90     #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \
91         INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ )
92 
93     ///////////////////////////////////////////////////////////////////////////////
94     #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
95         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
96         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \
97         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS
98 
99 
100 #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
101