Added support for manually registering test functions.

As discussed in #421
This commit is contained in:
Phil Nash 2015-11-20 16:54:07 +00:00
parent e4fa62a14e
commit 0e64973f55
8 changed files with 95 additions and 40 deletions

View File

@ -99,6 +99,7 @@
#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define CATCH_REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
@ -106,6 +107,7 @@
#define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
#define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
#define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
#define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
#define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
@ -166,6 +168,7 @@
#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
#define REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
#define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
@ -173,6 +176,7 @@
#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
#define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
#define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
#define REGISTER_TEST_CASE( ... ) INTERNAL_CATCH_REGISTER_TESTCASE( __VA_ARGS__ )
#define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
#define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )

View File

@ -152,28 +152,37 @@ namespace Catch {
return className; return className;
} }
/////////////////////////////////////////////////////////////////////////// void registerTestCase
( ITestCase* testCase,
AutoReg::AutoReg( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc ) {
registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
}
AutoReg::~AutoReg() {}
void AutoReg::registerTestCase( ITestCase* testCase,
char const* classOrQualifiedMethodName, char const* classOrQualifiedMethodName,
NameAndDesc const& nameAndDesc, NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo ) { SourceLineInfo const& lineInfo ) {
getMutableRegistryHub().registerTest getMutableRegistryHub().registerTest
( makeTestCase( testCase, ( makeTestCase
( testCase,
extractClassName( classOrQualifiedMethodName ), extractClassName( classOrQualifiedMethodName ),
nameAndDesc.name, nameAndDesc.name,
nameAndDesc.description, nameAndDesc.description,
lineInfo ) ); lineInfo ) );
} }
void registerTestCaseFunction
( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc ) {
registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
}
///////////////////////////////////////////////////////////////////////////
AutoReg::AutoReg
( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc ) {
registerTestCaseFunction( function, lineInfo, nameAndDesc );
}
AutoReg::~AutoReg() {}
} // end namespace Catch } // end namespace Catch

View File

@ -42,28 +42,33 @@ struct NameAndDesc {
const char* description; const char* description;
}; };
void registerTestCase
( ITestCase* testCase,
char const* className,
NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo );
struct AutoReg { struct AutoReg {
AutoReg( TestFunction function, AutoReg
( TestFunction function,
SourceLineInfo const& lineInfo, SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc ); NameAndDesc const& nameAndDesc );
template<typename C> template<typename C>
AutoReg( void (C::*method)(), AutoReg
( void (C::*method)(),
char const* className, char const* className,
NameAndDesc const& nameAndDesc, NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo ) { SourceLineInfo const& lineInfo ) {
registerTestCase( new MethodTestCase<C>( method ),
registerTestCase
( new MethodTestCase<C>( method ),
className, className,
nameAndDesc, nameAndDesc,
lineInfo ); lineInfo );
} }
void registerTestCase( ITestCase* testCase,
char const* className,
NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo );
~AutoReg(); ~AutoReg();
private: private:
@ -71,6 +76,11 @@ private:
void operator= ( AutoReg const& ); void operator= ( AutoReg const& );
}; };
void registerTestCaseFunction
( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc );
} // end namespace Catch } // end namespace Catch
#ifdef CATCH_CONFIG_VARIADIC_MACROS #ifdef CATCH_CONFIG_VARIADIC_MACROS
@ -94,6 +104,10 @@ private:
} \ } \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
#else #else
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
@ -115,6 +129,9 @@ private:
} \ } \
void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
#endif #endif
#endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED

View File

@ -830,6 +830,6 @@ with expansion:
"first" == "second" "first" == "second"
=============================================================================== ===============================================================================
test cases: 166 | 123 passed | 42 failed | 1 failed as expected test cases: 167 | 124 passed | 42 failed | 1 failed as expected
assertions: 913 | 817 passed | 83 failed | 13 failed as expected assertions: 914 | 818 passed | 83 failed | 13 failed as expected

View File

@ -6004,6 +6004,17 @@ with expansion:
************************ ************************
... message truncated due to excessive size ... message truncated due to excessive size
-------------------------------------------------------------------------------
ManuallyRegistered
-------------------------------------------------------------------------------
TestMain.cpp:<line number>
...............................................................................
TestMain.cpp:<line number>:
PASSED:
with message:
was called
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Parsing a std::pair Parsing a std::pair
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -9034,6 +9045,6 @@ with expansion:
1 > 0 1 > 0
=============================================================================== ===============================================================================
test cases: 166 | 122 passed | 43 failed | 1 failed as expected test cases: 167 | 123 passed | 43 failed | 1 failed as expected
assertions: 915 | 817 passed | 85 failed | 13 failed as expected assertions: 916 | 818 passed | 85 failed | 13 failed as expected

View File

@ -1,5 +1,5 @@
<testsuites> <testsuites>
<testsuite name="CatchSelfTest" errors="13" failures="72" tests="915" hostname="tbd" time="{duration}" timestamp="tbd"> <testsuite name="CatchSelfTest" errors="13" failures="72" tests="916" hostname="tbd" time="{duration}" timestamp="tbd">
<testcase classname="global" name="toString(enum)" time="{duration}"/> <testcase classname="global" name="toString(enum)" time="{duration}"/>
<testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/> <testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/>
<testcase classname="global" name="toString(enum class)" time="{duration}"/> <testcase classname="global" name="toString(enum class)" time="{duration}"/>
@ -547,6 +547,7 @@ hello
</testcase> </testcase>
<testcase classname="global" name="Text can be formatted using the Text class" time="{duration}"/> <testcase classname="global" name="Text can be formatted using the Text class" time="{duration}"/>
<testcase classname="global" name="Long text is truncted" time="{duration}"/> <testcase classname="global" name="Long text is truncted" time="{duration}"/>
<testcase classname="global" name="ManuallyRegistered" time="{duration}"/>
<testcase classname="global" name="Parsing a std::pair" time="{duration}"/> <testcase classname="global" name="Parsing a std::pair" time="{duration}"/>
<testcase classname="global" name="Where there is more to the expression after the RHS" time="{duration}"/> <testcase classname="global" name="Where there is more to the expression after the RHS" time="{duration}"/>
<testcase classname="global" name="Where the LHS is not a simple value" time="{duration}"/> <testcase classname="global" name="Where the LHS is not a simple value" time="{duration}"/>

View File

@ -6284,6 +6284,9 @@ there"
</Expression> </Expression>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<TestCase name="ManuallyRegistered">
<OverallResult success="true"/>
</TestCase>
<TestCase name="Parsing a std::pair"> <TestCase name="Parsing a std::pair">
<Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" > <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
<Original> <Original>
@ -9502,7 +9505,7 @@ there"
</Section> </Section>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<OverallResults successes="817" failures="85" expectedFailures="13"/> <OverallResults successes="818" failures="85" expectedFailures="13"/>
</Group> </Group>
<OverallResults successes="817" failures="85" expectedFailures="13"/> <OverallResults successes="818" failures="85" expectedFailures="13"/>
</Catch> </Catch>

View File

@ -449,3 +449,13 @@ TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) ); CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) );
} }
inline void manuallyRegisteredTestFunction() {
SUCCEED( "was called" );
}
struct AutoTestReg {
AutoTestReg() {
REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered", "" );
}
};
AutoTestReg autoTestReg;