mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Squashed commit of the following:
commit70c5ef9eedAuthor: Phil Nash <github@philnash.me> Date: Tue Nov 13 21:46:01 2012 +0000 Regen single include commit4ea535e505Author: Phil Nash <github@philnash.me> Date: Tue Nov 13 09:56:30 2012 +0000 Tidied up result enums commit7717c29072Author: Phil Nash <github@philnash.me> Date: Tue Nov 13 09:45:29 2012 +0000 Implemented CHECK_NOFAIL Previous commit missed some files commitd539da9030Author: Phil Nash <github@philnash.me> Date: Tue Nov 13 09:44:52 2012 +0000 Implemented CHECK_NO_FAIL commitaf1a321860Author: Phil Nash <github@philnash.me> Date: Sat Nov 10 18:46:39 2012 +0000 Regen single include commitf54ac5625eAuthor: Phil Nash <github@philnash.me> Date: Sat Nov 10 18:44:12 2012 +0000 New (combined) baselines commitdefca58566Author: Phil Nash <github@philnash.me> Date: Sat Nov 10 18:43:23 2012 +0000 negate() -> endExpression(), takes ResultDisposition commitb2ef998825Author: Phil Nash <github@philnash.me> Date: Sat Nov 10 10:35:09 2012 +0000 Changed shouldNegate boolean to use part of ResultDisposition enum commit1af13dba97Author: Phil Nash <github@philnash.me> Date: Sat Nov 10 10:20:08 2012 +0000 Changed StopOnFailure boolean to an enum commita1dc7e312cAuthor: Phil Nash <github@philnash.me> Date: Tue Nov 6 19:34:35 2012 +0000 Regen single include commit20e59ce9d1Author: Phil Nash <github@philnash.me> Date: Tue Nov 6 19:34:10 2012 +0000 Added tags docs commitb5b1b1e430Author: Phil Nash <github@philnash.me> Date: Tue Nov 6 19:13:25 2012 +0000 Some expression/ evaluation clean-up commitec5956f471Author: Phil Nash <github@philnash.me> Date: Tue Nov 6 07:52:28 2012 +0000 Fix for #134 The INTERNAL_CATCH_MSG macro, which is used by INFO, WARN and FAIL places its lines in a do…while block so it can be used after an if statement with no block commit88b70828f2Author: Phil Nash <github@philnash.me> Date: Sun Nov 4 21:39:38 2012 +0000 Regen single include commitb323fc7e6cAuthor: Phil Nash <github@philnash.me> Date: Sun Nov 4 21:39:16 2012 +0000 Fixed line/no regression for SECTIONs Unexpected exceptions within a section now get the SECTION's line no. again (instead of TEST_CASE line/no) commit78fba28c4bAuthor: Phil Nash <github@philnash.me> Date: Sun Nov 4 21:11:59 2012 +0000 Added className to TestCaseInfo className is passed through from class based test methods and held in the TestCaseInfo. For free-function based test cases it is set to "global". The JUnit reporter uses the className value to populate he class attribute. commit81cb69ef18Author: Phil Nash <github@philnash.me> Date: Sun Nov 4 21:09:22 2012 +0000 AssertionInfo captures more info (for test cases and sections) commita4e088c999Author: Phil Nash <github@philnash.me> Date: Fri Nov 2 08:29:03 2012 +0000 Removed __FUNCTION__ from SourceLineInfo commit2a1e8bfc6eAuthor: Phil Nash <github@philnash.me> Date: Thu Nov 1 08:16:15 2012 +0000 Updated colour comments commitf0f407fc3eAuthor: Phil Nash <github@philnash.me> Date: Wed Oct 31 18:28:21 2012 +0000 Manually applied merge #133 from Master commit355b95fda1Author: Phil Nash <github@philnash.me> Date: Wed Oct 31 18:04:22 2012 +0000 Cleaned up ANSI colour code impl a bit commit778f9c4fc7Author: Phil Nash <github@philnash.me> Date: Tue Oct 30 09:09:30 2012 +0000 Removed "no-" from Wno-global-constructors when disabling commit5efa4bcb8aAuthor: Phil Nash <github@philnash.me> Date: Mon Oct 29 20:49:22 2012 +0000 Regenerated single_include commit108f1937d8Author: Phil Nash <github@philnash.me> Date: Mon Oct 29 20:46:45 2012 +0000 Added terminal colour codes for POSIX With thanks to Adam Strzelecki commit8f4cc541d5Author: Phil Nash <github@philnash.me> Date: Mon Oct 29 19:55:34 2012 +0000 Added regression test baselines commit2e203a1834Author: Phil Nash <github@philnash.me> Date: Mon Oct 29 19:55:13 2012 +0000 Fixed remaining reporting regressions commit134e45b3adAuthor: Phil Nash <github@philnash.me> Date: Sun Oct 28 20:57:21 2012 +0000 Fixed #132 commit2f92db9898Author: Phil Nash <github@philnash.me> Date: Sun Oct 28 12:15:34 2012 +0000 Updated the readme specifically for the Integration branch commit82acc2ca05Author: Phil Nash <github@philnash.me> Date: Sun Oct 28 12:07:17 2012 +0000 Regenerated single include commitfe1d7c1d08Author: Phil Nash <github@philnash.me> Date: Sun Oct 28 10:27:44 2012 +0000 Small fixes and tweaks commit355b5e546dAuthor: Phil Nash <github@philnash.me> Date: Fri Oct 26 09:05:36 2012 +0100 Some tidy-up commitf847186ebbAuthor: Phil Nash <github@philnash.me> Date: Fri Oct 26 08:45:23 2012 +0100 AssertionResultBuilder -> ExpressionResultBuilder commit8cca2f1369Author: Phil Nash <github@philnash.me> Date: Wed Oct 24 22:09:01 2012 +0100 ExpressionBuilder ->ExpressionDecomposer Expression -> ExpressionLhs commite04e74f896Author: Phil Nash <github@philnash.me> Date: Wed Oct 24 21:59:47 2012 +0100 More AssertionResult refactoring commit1dd56d4d2bAuthor: Phil Nash <github@philnash.me> Date: Fri Oct 19 08:01:34 2012 +0100 AssertionResultBuilder can be constructed from result type commitf2d5f1b3e4Author: Phil Nash <github@philnash.me> Date: Fri Oct 19 08:01:05 2012 +0100 Expression has its own result builder - not passed in from expression builder commite3b111a39aAuthor: Phil Nash <github@philnash.me> Date: Thu Oct 18 22:59:16 2012 +0100 streamlined acceptResult commit3ad13256e1Author: Phil Nash <github@philnash.me> Date: Thu Oct 18 08:39:44 2012 +0100 Refactored assertion builder stuff out of expression builder commitc96f9330a0Author: Phil Nash <github@philnash.me> Date: Wed Oct 17 08:14:22 2012 +0100 Collect assertion info up front commita5fa78284dAuthor: Phil Nash <github@philnash.me> Date: Tue Oct 16 08:33:13 2012 +0100 ResultData -> AssertionResultData commitc597a893faAuthor: Phil Nash <github@philnash.me> Date: Tue Oct 16 08:31:05 2012 +0100 ResultInfo -> AssertionResult filenames and variables commitd16955f63aAuthor: Phil Nash <github@philnash.me> Date: Tue Oct 16 08:27:21 2012 +0100 Renamed ResultInfo -> AssertionResult commit175da3ef64Author: Phil Nash <github@philnash.me> Date: Fri Oct 12 18:39:22 2012 +0100 regen test 3
This commit is contained in:
		| @@ -16,18 +16,15 @@ namespace Catch { | ||||
|     struct AssertionInfo | ||||
|     { | ||||
|         AssertionInfo() {} | ||||
|         AssertionInfo( const std::string& _macroName, const SourceLineInfo& _lineInfo, const std::string& _capturedExpression, bool _shouldNegate ) | ||||
|         :   macroName( _macroName ), | ||||
|             lineInfo( _lineInfo ), | ||||
|             capturedExpression( _capturedExpression ) | ||||
|         { | ||||
|             if( _shouldNegate ) | ||||
|                 capturedExpression = "!" + _capturedExpression; | ||||
|         } | ||||
|         AssertionInfo(  const std::string& _macroName, | ||||
|                         const SourceLineInfo& _lineInfo, | ||||
|                         const std::string& _capturedExpression, | ||||
|                         ResultDisposition::Flags _resultDisposition ); | ||||
|  | ||||
|         std::string macroName; | ||||
|         SourceLineInfo lineInfo; | ||||
|         std::string capturedExpression; | ||||
|         ResultDisposition::Flags resultDisposition; | ||||
|     }; | ||||
|  | ||||
|     struct AssertionResultData | ||||
| @@ -45,7 +42,8 @@ namespace Catch { | ||||
|         AssertionResult( const AssertionInfo& info, const AssertionResultData& data ); | ||||
|         ~AssertionResult(); | ||||
|          | ||||
|         bool ok() const; | ||||
|         bool isOk() const; | ||||
|         bool succeeded() const; | ||||
|         ResultWas::OfType getResultType() const; | ||||
|         bool hasExpression() const; | ||||
|         bool hasMessage() const; | ||||
|   | ||||
| @@ -12,6 +12,20 @@ | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|  | ||||
|     AssertionInfo::AssertionInfo(   const std::string& _macroName, | ||||
|                                     const SourceLineInfo& _lineInfo, | ||||
|                                     const std::string& _capturedExpression, | ||||
|                                     ResultDisposition::Flags _resultDisposition ) | ||||
|     :   macroName( _macroName ), | ||||
|         lineInfo( _lineInfo ), | ||||
|         capturedExpression( _capturedExpression ), | ||||
|         resultDisposition( _resultDisposition ) | ||||
|     { | ||||
|         if( shouldNegate( resultDisposition ) ) | ||||
|             capturedExpression = "!" + _capturedExpression; | ||||
|     } | ||||
|  | ||||
|     AssertionResult::AssertionResult() {} | ||||
|  | ||||
|     AssertionResult::AssertionResult( const AssertionInfo& info, const AssertionResultData& data ) | ||||
| @@ -21,8 +35,14 @@ namespace Catch { | ||||
|  | ||||
|     AssertionResult::~AssertionResult() {} | ||||
|  | ||||
|     bool AssertionResult::ok() const { | ||||
|         return isOk( m_resultData.resultType ); | ||||
|     // Result was a success | ||||
|     bool AssertionResult::succeeded() const { | ||||
|         return Catch::isOk( m_resultData.resultType ); | ||||
|     } | ||||
|  | ||||
|     // Result was a success, or failure is suppressed | ||||
|     bool AssertionResult::isOk() const { | ||||
|         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); | ||||
|     } | ||||
|  | ||||
|     ResultWas::OfType AssertionResult::getResultType() const { | ||||
|   | ||||
| @@ -74,7 +74,7 @@ public: | ||||
| private: | ||||
|     ExpressionResultBuilder m_resultBuilder; | ||||
| }; | ||||
|          | ||||
|  | ||||
| // This is just here to avoid compiler warnings with macro constants and boolean literals | ||||
| inline bool isTrue( bool value ){ return value; } | ||||
|  | ||||
| @@ -84,109 +84,113 @@ inline bool isTrue( bool value ){ return value; } | ||||
| #define INTERNAL_CATCH_ASSERTIONINFO_NAME INTERNAL_CATCH_UNIQUE_NAME( __assertionInfo ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, stopOnFailure, originalExpr ) \ | ||||
| #define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, resultDisposition, originalExpr ) \ | ||||
|     if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME )  ) { \ | ||||
|         if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \ | ||||
|         if( internal_catch_action & Catch::ResultAction::Abort ) throw Catch::TestFailureException(); \ | ||||
|         if( Catch::isTrue( stopOnFailure ) ) throw Catch::TestFailureException(); \ | ||||
|         if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \ | ||||
|         if( Catch::isTrue( false ) ){ bool this_is_here_to_invoke_warnings = ( originalExpr ); Catch::isTrue( this_is_here_to_invoke_warnings ); } \ | ||||
|     } | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_ACCEPT_INFO( expr, macroName, shouldNegate ) \ | ||||
|     Catch::AssertionInfo INTERNAL_CATCH_ASSERTIONINFO_NAME( macroName, CATCH_INTERNAL_LINEINFO, expr, shouldNegate ); | ||||
| // !TBD    Catch::getResultCapture().acceptAssertionInfo( INTERNAL_CATCH_ASSERTIONINFO_NAME ) | ||||
| #define INTERNAL_CATCH_ACCEPT_INFO( expr, macroName, resultDisposition ) \ | ||||
|     Catch::AssertionInfo INTERNAL_CATCH_ASSERTIONINFO_NAME( macroName, CATCH_INTERNAL_LINEINFO, expr, resultDisposition ); | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_TEST( expr, shouldNegate, stopOnFailure, macroName ) \ | ||||
| #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ | ||||
|     do { \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, shouldNegate ); \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ | ||||
|         try { \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionDecomposer()->*expr ).negate( shouldNegate ), stopOnFailure, expr ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionDecomposer()->*expr ).endExpression( resultDisposition ), resultDisposition, expr ); \ | ||||
|         } catch( Catch::TestFailureException& ) { \ | ||||
|             throw; \ | ||||
|         } catch( ... ) { \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), false, expr ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), \ | ||||
|                 resultDisposition | Catch::ResultDisposition::ContinueOnFailure, expr ); \ | ||||
|             throw; \ | ||||
|         } \ | ||||
|     } while( Catch::isTrue( false ) ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_IF( expr, shouldNegate, stopOnFailure, macroName ) \ | ||||
|     INTERNAL_CATCH_TEST( expr, shouldNegate, stopOnFailure, macroName ); \ | ||||
|     if( Catch::getResultCapture().getLastResult()->ok() ) | ||||
| #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ | ||||
|     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ | ||||
|     if( Catch::getResultCapture().getLastResult()->succeeded() ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_ELSE( expr, shouldNegate, stopOnFailure, macroName ) \ | ||||
|     INTERNAL_CATCH_TEST( expr, shouldNegate, stopOnFailure, macroName ); \ | ||||
|     if( !Catch::getResultCapture().getLastResult()->ok() ) | ||||
| #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ | ||||
|     INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ | ||||
|     if( !Catch::getResultCapture().getLastResult()->succeeded() ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_NO_THROW( expr, stopOnFailure, macroName ) \ | ||||
| #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ | ||||
|     do { \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, false ); \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ | ||||
|         try { \ | ||||
|             expr; \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), stopOnFailure, false ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \ | ||||
|         } \ | ||||
|         catch( ... ) { \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), stopOnFailure, false ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException(), resultDisposition, false ); \ | ||||
|         } \ | ||||
| } while( Catch::isTrue( false ) ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, stopOnFailure ) \ | ||||
| #define INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \ | ||||
|     try { \ | ||||
|         if( Catch::getCurrentContext().getConfig()->allowThrows() ) { \ | ||||
|             expr; \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::DidntThrowException ), stopOnFailure, false ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::DidntThrowException ), resultDisposition, false ); \ | ||||
|         } \ | ||||
|     } \ | ||||
|     catch( Catch::TestFailureException& ) { \ | ||||
|         throw; \ | ||||
|     } \ | ||||
|     catch( exceptionType ) { \ | ||||
|         INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), stopOnFailure, false ); \ | ||||
|         INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( Catch::ResultWas::Ok ), resultDisposition, false ); \ | ||||
|     } | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_THROWS( expr, exceptionType, stopOnFailure, macroName ) \ | ||||
| #define INTERNAL_CATCH_THROWS( expr, exceptionType, resultDisposition, macroName ) \ | ||||
|     do { \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, false ); \ | ||||
|         INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, stopOnFailure ) \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ | ||||
|         INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \ | ||||
|     } while( Catch::isTrue( false ) ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, stopOnFailure, macroName ) \ | ||||
| #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ | ||||
|     do { \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, false ); \ | ||||
|         INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, stopOnFailure ) \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, resultDisposition ); \ | ||||
|         INTERNAL_CATCH_THROWS_IMPL( expr, exceptionType, resultDisposition ) \ | ||||
|         catch( ... ) { \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), stopOnFailure, false ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \ | ||||
|                 resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \ | ||||
|         } \ | ||||
|     } while( Catch::isTrue( false ) ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_MSG( reason, resultType, stopOnFailure, macroName ) \ | ||||
|     INTERNAL_CATCH_ACCEPT_INFO( "", macroName, false ); \ | ||||
|     INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( resultType ) << reason, stopOnFailure, true ); | ||||
| #define INTERNAL_CATCH_MSG( reason, resultType, resultDisposition, macroName ) \ | ||||
|     do { \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( "", macroName, resultDisposition ); \ | ||||
|         INTERNAL_CATCH_ACCEPT_EXPR( Catch::ExpressionResultBuilder( resultType ) << reason, resultDisposition, true ) \ | ||||
|     } while( Catch::isTrue( false ) ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_SCOPED_INFO( log, macroName ) \ | ||||
|     INTERNAL_CATCH_ACCEPT_INFO( "", macroName, false ); \ | ||||
|     INTERNAL_CATCH_ACCEPT_INFO( "", macroName, Catch::ResultDisposition::Normal ); \ | ||||
|     Catch::ScopedInfo INTERNAL_CATCH_UNIQUE_NAME( info ); \ | ||||
|     INTERNAL_CATCH_UNIQUE_NAME( info ) << log | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CHECK_THAT( arg, matcher, stopOnFailure, macroName ) \ | ||||
| #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ | ||||
|     do { \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, false ); \ | ||||
|         INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, resultDisposition ); \ | ||||
|         try { \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::expressionResultBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), stopOnFailure, false ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::expressionResultBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), resultDisposition, false ); \ | ||||
|         } catch( Catch::TestFailureException& ) { \ | ||||
|             throw; \ | ||||
|         } catch( ... ) { \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), false, false ); \ | ||||
|             INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionResultBuilder( Catch::ResultWas::ThrewException ) << Catch::translateActiveException() ), \ | ||||
|                 resultDisposition | Catch::ResultDisposition::ContinueOnFailure, false ); \ | ||||
|             throw; \ | ||||
|         } \ | ||||
|     } while( Catch::isTrue( false ) ) | ||||
|   | ||||
| @@ -282,7 +282,14 @@ namespace Catch { | ||||
|             // subsequently wrapped lines | ||||
|             virtual std::string optionDescription() const { | ||||
|                 return | ||||
|                 "!TBD"; | ||||
|                 "This option allows one or more tags or tag patterns to be specified.\n" | ||||
|                 "Each tag is enclosed in square brackets. A series of tags form an AND expression " | ||||
|                 "wheras a comma seperated sequence forms an OR expression. e.g.:\n\n" | ||||
|                 "    -g [one][two],[three]\n\n" | ||||
|                 "This matches all tests tagged [one] and [two], as well as all tests tagged [three].\n\n" | ||||
|                 "Tags can be negated with the ~ character. This removes matching tests from the set. e.g.:\n\n" | ||||
|                 "    -g [one]~[two]\n\n" | ||||
|                 "matches all tests tagged [one], except those also tagged [two]"; | ||||
|             } | ||||
|              | ||||
|             virtual void parseIntoConfig( const Command& cmd, ConfigData& config ) { | ||||
|   | ||||
| @@ -94,7 +94,7 @@ namespace Catch { | ||||
|         friend std::ostream& operator << ( std::ostream& os, const pluralise& pluraliser ) { | ||||
|             os << pluraliser.m_count << " " << pluraliser.m_label; | ||||
|             if( pluraliser.m_count != 1 ) | ||||
|             os << "s"; | ||||
|                 os << "s"; | ||||
|             return os; | ||||
|         } | ||||
|  | ||||
| @@ -109,24 +109,17 @@ namespace Catch { | ||||
|         :   file( _file ), | ||||
|             line( _line ) | ||||
|         {} | ||||
|         SourceLineInfo( const std::string& _function, const std::string& _file, std::size_t _line ) | ||||
|         :   function( _function ), | ||||
|             file( _file ), | ||||
|             line( _line ) | ||||
|         {} | ||||
|         SourceLineInfo( const SourceLineInfo& other ) | ||||
|         :   file( other.file ), | ||||
|             line( other.line ) | ||||
|         {} | ||||
|         void swap( SourceLineInfo& other ){ | ||||
|             file.swap( other.file ); | ||||
|             std::swap( line, other.line ); | ||||
|         bool empty() const { | ||||
|             return file.empty(); | ||||
|         } | ||||
|         bool empty() const { | ||||
|             return file.empty(); | ||||
|         } | ||||
|          | ||||
|         std::string function; | ||||
|         std::string file; | ||||
|         std::size_t line;         | ||||
|     }; | ||||
|   | ||||
| @@ -69,18 +69,21 @@ namespace Internal { | ||||
|             return const_cast<T1&>( lhs ) <= const_cast<T2&>( rhs ); | ||||
|         } | ||||
|     }; | ||||
|      | ||||
|  | ||||
|     template<Operator Op, typename T1, typename T2> | ||||
|     bool applyEvaluator( const T1& lhs, const T2& rhs ) { | ||||
|         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     // This level of indirection allows us to specialise for integer types | ||||
|     // to avoid signed/ unsigned warnings | ||||
|  | ||||
|     // "base" overload | ||||
|     template<Operator Op, typename T1, typename T2> | ||||
|     bool compare( const T1& lhs, const T2& rhs ) { | ||||
|         return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     // unsigned X to int | ||||
|     template<Operator Op> bool compare( unsigned int lhs, int rhs ) { | ||||
|         return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); | ||||
| @@ -126,44 +129,18 @@ namespace Internal { | ||||
|     } | ||||
|  | ||||
|     // pointer to long (when comparing against NULL) | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( long lhs, const T* rhs ) { | ||||
|         return Evaluator<const T*, const T*, Op>::evaluate( reinterpret_cast<const T*>( lhs ), rhs ); | ||||
|     } | ||||
|      | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( long lhs, T* rhs ) { | ||||
|     template<Operator Op, typename T> bool compare( long lhs, T* rhs ) { | ||||
|         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); | ||||
|     } | ||||
|  | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( const T* lhs, long rhs ) { | ||||
|         return Evaluator<const T*, const T*, Op>::evaluate( lhs, reinterpret_cast<const T*>( rhs ) ); | ||||
|     } | ||||
|      | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( T* lhs, long rhs ) { | ||||
|     template<Operator Op, typename T> bool compare( T* lhs, long rhs ) { | ||||
|         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); | ||||
|     } | ||||
|      | ||||
|     // pointer to int (when comparing against NULL) | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( int lhs, const T* rhs ) { | ||||
|         return Evaluator<const T*, const T*, Op>::evaluate( reinterpret_cast<const T*>( lhs ), rhs ); | ||||
|     } | ||||
|      | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( int lhs, T* rhs ) { | ||||
|     template<Operator Op, typename T> bool compare( int lhs, T* rhs ) { | ||||
|         return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); | ||||
|     } | ||||
|  | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( const T* lhs, int rhs ) { | ||||
|         return Evaluator<const T*, const T*, Op>::evaluate( lhs, reinterpret_cast<const T*>( rhs ) ); | ||||
|     } | ||||
|      | ||||
|     template<Operator Op, typename T> | ||||
|     bool compare( T* lhs, int rhs ) { | ||||
|     template<Operator Op, typename T> bool compare( T* lhs, int rhs ) { | ||||
|         return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); | ||||
|     } | ||||
|          | ||||
|   | ||||
| @@ -22,7 +22,7 @@ class ExpressionLhs { | ||||
| 	void operator = ( const ExpressionLhs& ); | ||||
|  | ||||
| public: | ||||
|     ExpressionLhs( T lhs ) : m_lhs( lhs ) {} | ||||
|     ExpressionLhs( const T& lhs ) : m_lhs( lhs ) {} | ||||
|  | ||||
|     template<typename RhsT> | ||||
|     ExpressionResultBuilder& operator == ( const RhsT& rhs ) { | ||||
| @@ -62,12 +62,12 @@ public: | ||||
|         return captureExpression<Internal::IsNotEqualTo>( rhs ); | ||||
|     } | ||||
|      | ||||
|     ExpressionResultBuilder& negate( bool shouldNegate ) { | ||||
|     ExpressionResultBuilder& endExpression( ResultDisposition::Flags resultDisposition ) { | ||||
|         bool value = m_lhs ? true : false; | ||||
|         return m_result | ||||
|             .setLhs( Catch::toString( value ) ) | ||||
|             .setResultType( value ) | ||||
|             .negate( shouldNegate ); | ||||
|             .endExpression( resultDisposition ); | ||||
|     } | ||||
|  | ||||
|     // Only simple binary expressions are allowed on the LHS. | ||||
|   | ||||
| @@ -31,7 +31,7 @@ public: | ||||
|     ExpressionResultBuilder& setRhs( const std::string& rhs ); | ||||
|     ExpressionResultBuilder& setOp( const std::string& op ); | ||||
|  | ||||
|     ExpressionResultBuilder& negate( bool shouldNegate ); | ||||
|     ExpressionResultBuilder& endExpression( ResultDisposition::Flags resultDisposition ); | ||||
|  | ||||
|     template<typename T> | ||||
|     ExpressionResultBuilder& operator << ( const T& value ) { | ||||
|   | ||||
| @@ -38,8 +38,8 @@ namespace Catch { | ||||
|         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; | ||||
|         return *this; | ||||
|     } | ||||
|     ExpressionResultBuilder& ExpressionResultBuilder::negate( bool shouldNegate ) { | ||||
|         m_exprComponents.shouldNegate = shouldNegate; | ||||
|     ExpressionResultBuilder& ExpressionResultBuilder::endExpression( ResultDisposition::Flags resultDisposition ) { | ||||
|         m_exprComponents.shouldNegate = shouldNegate( resultDisposition ); | ||||
|         return *this; | ||||
|     } | ||||
|     ExpressionResultBuilder& ExpressionResultBuilder::setLhs( const std::string& lhs ) { | ||||
|   | ||||
| @@ -35,7 +35,6 @@ namespace Catch { | ||||
|         virtual void popScopedInfo( ScopedInfo* scopedInfo ) = 0; | ||||
|         virtual bool shouldDebugBreak() const = 0; | ||||
|          | ||||
|         virtual void acceptAssertionInfo( const AssertionInfo& assertionInfo ) = 0; | ||||
|         virtual ResultAction::Value acceptExpression( const ExpressionResultBuilder& assertionResult, const AssertionInfo& assertionInfo ) = 0; | ||||
|          | ||||
|         virtual std::string getCurrentTestName() const = 0;         | ||||
|   | ||||
| @@ -17,8 +17,6 @@ namespace Catch { | ||||
|     :   m_lineInfo( lineInfo ) { | ||||
|         std::ostringstream oss; | ||||
|         oss << lineInfo << "function "; | ||||
|         if( !lineInfo.function.empty() ) | ||||
|             oss << lineInfo.function << " "; | ||||
|         oss << "not implemented"; | ||||
|         m_what = oss.str(); | ||||
|     } | ||||
|   | ||||
| @@ -10,35 +10,54 @@ | ||||
|  | ||||
| namespace Catch {     | ||||
|  | ||||
| struct ResultWas { enum OfType { | ||||
|     Unknown = -1, | ||||
|     Ok = 0, | ||||
|     Info = 1, | ||||
|     Warning = 2, | ||||
|      | ||||
|     FailureBit = 0x10, | ||||
|      | ||||
|     ExpressionFailed = FailureBit | 1, | ||||
|     ExplicitFailure = FailureBit | 2, | ||||
|      | ||||
|     Exception = 0x100 | FailureBit, | ||||
|      | ||||
|     ThrewException = Exception | 1, | ||||
|     DidntThrowException = Exception | 2 | ||||
|      | ||||
| }; }; | ||||
|     // ResultWas::OfType enum | ||||
|     struct ResultWas { enum OfType { | ||||
|         Unknown = -1, | ||||
|         Ok = 0, | ||||
|         Info = 1, | ||||
|         Warning = 2, | ||||
|          | ||||
|         FailureBit = 0x10, | ||||
|          | ||||
|         ExpressionFailed = FailureBit | 1, | ||||
|         ExplicitFailure = FailureBit | 2, | ||||
|          | ||||
|         Exception = 0x100 | FailureBit, | ||||
|          | ||||
|         ThrewException = Exception | 1, | ||||
|         DidntThrowException = Exception | 2 | ||||
|          | ||||
|     }; }; | ||||
|  | ||||
| inline bool isOk( ResultWas::OfType resultType ) { | ||||
|     return ( resultType & ResultWas::FailureBit ) == 0; | ||||
| } | ||||
|     inline bool isOk( ResultWas::OfType resultType ) { | ||||
|         return ( resultType & ResultWas::FailureBit ) == 0; | ||||
|     } | ||||
|  | ||||
| struct ResultAction { enum Value { | ||||
|     None, | ||||
|     Failed = 1, // Failure - but no debug break if Debug bit not set | ||||
|     Debug = 2,  // If this bit is set, invoke the debugger | ||||
|     Abort = 4   // Test run should abort     | ||||
| }; }; | ||||
|      | ||||
| } | ||||
|     // ResultAction::Value enum | ||||
|     struct ResultAction { enum Value { | ||||
|         None, | ||||
|         Failed = 1, // Failure - but no debug break if Debug bit not set | ||||
|         Debug = 2,  // If this bit is set, invoke the debugger | ||||
|         Abort = 4   // Test run should abort     | ||||
|     }; }; | ||||
|  | ||||
|     // ResultDisposition::Flags enum | ||||
|     struct ResultDisposition { enum Flags { | ||||
|             Normal = 0x00, | ||||
|  | ||||
|             ContinueOnFailure = 0x01,   // Failures fail test, but execution continues | ||||
|             NegateResult = 0x02,        // Prefix expressiom with ! | ||||
|             SuppressFail = 0x04         // Failures are reported but do not fail the test | ||||
|     }; }; | ||||
|  | ||||
|     inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { | ||||
|         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); | ||||
|     } | ||||
|  | ||||
|     inline bool shouldContinueOnFailure( int flags ) { return flags & ResultDisposition::ContinueOnFailure; } | ||||
|     inline bool shouldNegate( int flags ) { return flags & ResultDisposition::NegateResult; } | ||||
|     inline bool shouldSuppressFailure( int flags ) { return flags & ResultDisposition::SuppressFail; } | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED | ||||
|   | ||||
| @@ -46,7 +46,7 @@ namespace Catch { | ||||
|         std::ostringstream m_oss; | ||||
|         std::string& m_targetString; | ||||
|     }; | ||||
|      | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|     class Runner : public IResultCapture, public IRunner { | ||||
| @@ -109,7 +109,6 @@ namespace Catch { | ||||
|  | ||||
|             do { | ||||
|                 do { | ||||
|                     m_assertionInfo.lineInfo = m_runningTest->getTestCaseInfo().getLineInfo(); | ||||
|                     runCurrentTest( redirectedCout, redirectedCerr ); | ||||
|                 } | ||||
|                 while( m_runningTest->hasUntestedSections() && !aborting() ); | ||||
| @@ -131,28 +130,23 @@ namespace Catch { | ||||
|          | ||||
|     private: // IResultCapture | ||||
|  | ||||
|         virtual void acceptAssertionInfo( const AssertionInfo& assertionInfo ) { | ||||
|             m_assertionInfo = assertionInfo; | ||||
|         } | ||||
|          | ||||
|         virtual ResultAction::Value acceptExpression( const ExpressionResultBuilder& assertionResult, const AssertionInfo& assertionInfo ) { | ||||
|             m_assertionInfo = assertionInfo; | ||||
|             m_currentResult = assertionResult; | ||||
|             return actOnCurrentResult(); | ||||
|             m_lastAssertionInfo = assertionInfo; | ||||
|             return actOnCurrentResult( assertionResult.buildResult( assertionInfo ) ); | ||||
|         } | ||||
|  | ||||
|         virtual void testEnded( const AssertionResult& result ) { | ||||
|             if( result.getResultType() == ResultWas::Ok ) { | ||||
|                 m_totals.assertions.passed++; | ||||
|             } | ||||
|             else if( !result.ok() ) { | ||||
|             else if( !result.isOk() ) { | ||||
|                 m_totals.assertions.failed++; | ||||
|  | ||||
|                 { | ||||
|                     std::vector<ScopedInfo*>::const_iterator it = m_scopedInfos.begin(); | ||||
|                     std::vector<ScopedInfo*>::const_iterator itEnd = m_scopedInfos.end(); | ||||
|                     for(; it != itEnd; ++it ) | ||||
|                         m_reporter->Result( (*it)->buildResult( m_assertionInfo ) ); | ||||
|                         m_reporter->Result( (*it)->buildResult( m_lastAssertionInfo ) ); | ||||
|                 } | ||||
|                 { | ||||
|                     std::vector<AssertionResult>::const_iterator it = m_assertionResults.begin(); | ||||
| @@ -179,10 +173,12 @@ namespace Catch { | ||||
|             std::ostringstream oss; | ||||
|             oss << name << "@" << lineInfo; | ||||
|  | ||||
|  | ||||
|             if( !m_runningTest->addSection( oss.str() ) ) | ||||
|                 return false; | ||||
|  | ||||
|             m_assertionInfo.lineInfo = lineInfo; | ||||
|             m_lastAssertionInfo.lineInfo = lineInfo; | ||||
|  | ||||
|             m_reporter->StartSection( name, description ); | ||||
|             assertions = m_totals.assertions; | ||||
|              | ||||
| @@ -233,16 +229,13 @@ namespace Catch { | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         ResultAction::Value actOnCurrentResult() { | ||||
|             m_lastResult = m_currentResult.buildResult( m_assertionInfo ); | ||||
|         ResultAction::Value actOnCurrentResult( const AssertionResult& result ) { | ||||
|             m_lastResult = result; | ||||
|             testEnded( m_lastResult ); | ||||
|  | ||||
|             m_currentResult = ExpressionResultBuilder(); | ||||
|             m_assertionInfo = AssertionInfo(); | ||||
|  | ||||
|             ResultAction::Value action = ResultAction::None; | ||||
|              | ||||
|             if( !m_lastResult.ok() ) { | ||||
|             if( !m_lastResult.isOk() ) { | ||||
|                 action = ResultAction::Failed; | ||||
|                 if( shouldDebugBreak() ) | ||||
|                     action = (ResultAction::Value)( action | ResultAction::Debug ); | ||||
| @@ -254,6 +247,7 @@ namespace Catch { | ||||
|  | ||||
|         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { | ||||
|             try { | ||||
|                 m_lastAssertionInfo = AssertionInfo( "TEST_CASE", m_runningTest->getTestCaseInfo().getLineInfo(), "", ResultDisposition::Normal ); | ||||
|                 m_runningTest->reset(); | ||||
|                 Counts prevAssertions = m_totals.assertions; | ||||
|                 if( m_reporter->shouldRedirectStdout() ) { | ||||
| @@ -277,10 +271,9 @@ namespace Catch { | ||||
|                 // This just means the test was aborted due to failure | ||||
|             } | ||||
|             catch(...) { | ||||
|                 m_currentResult | ||||
|                     .setResultType( ResultWas::ThrewException ) | ||||
|                     << translateActiveException(); | ||||
|                 actOnCurrentResult(); | ||||
|                 ExpressionResultBuilder exResult( ResultWas::ThrewException ); | ||||
|                 exResult << translateActiveException(); | ||||
|                 actOnCurrentResult( exResult.buildResult( m_lastAssertionInfo )  ); | ||||
|             } | ||||
|             m_assertionResults.clear(); | ||||
|         } | ||||
| @@ -288,7 +281,6 @@ namespace Catch { | ||||
|     private: | ||||
|         IMutableContext& m_context; | ||||
|         RunningTest* m_runningTest; | ||||
|         ExpressionResultBuilder m_currentResult; | ||||
|         AssertionResult m_lastResult; | ||||
|  | ||||
|         const Config& m_config; | ||||
| @@ -299,7 +291,7 @@ namespace Catch { | ||||
|         IRunner* m_prevRunner; | ||||
|         IResultCapture* m_prevResultCapture; | ||||
|         const IConfig* m_prevConfig; | ||||
|         AssertionInfo m_assertionInfo; | ||||
|         AssertionInfo m_lastAssertionInfo; | ||||
|     }; | ||||
|      | ||||
| } // end namespace Catch | ||||
|   | ||||
| @@ -83,12 +83,12 @@ namespace Catch { | ||||
|     class Tag { | ||||
|     public: | ||||
|         Tag() | ||||
|         : m_isNegated( false ) | ||||
|         :   m_isNegated( false ) | ||||
|         {} | ||||
|  | ||||
|         Tag( const std::string& name, bool isNegated ) | ||||
|         :   m_name( name ), | ||||
|         m_isNegated( isNegated ) | ||||
|             m_isNegated( isNegated ) | ||||
|         {} | ||||
|  | ||||
|         std::string getName() const { | ||||
|   | ||||
| @@ -22,8 +22,9 @@ namespace Catch { | ||||
|         TestCaseInfo(); | ||||
|  | ||||
|         TestCaseInfo(   ITestCase* testCase, | ||||
|                         const char* name,  | ||||
|                         const char* description, | ||||
|                         const std::string& className, | ||||
|                         const std::string& name, | ||||
|                         const std::string& description, | ||||
|                         const SourceLineInfo& lineInfo ); | ||||
|  | ||||
|  | ||||
| @@ -31,6 +32,8 @@ namespace Catch { | ||||
|         TestCaseInfo( const TestCaseInfo& other ); | ||||
|  | ||||
|         void invoke() const; | ||||
|  | ||||
|         const std::string& getClassName() const; | ||||
|         const std::string& getName() const; | ||||
|         const std::string& getDescription() const; | ||||
|         const SourceLineInfo& getLineInfo() const; | ||||
| @@ -46,6 +49,7 @@ namespace Catch { | ||||
|  | ||||
|     private: | ||||
|         Ptr<ITestCase> m_test; | ||||
|         std::string m_className; | ||||
|         std::string m_name; | ||||
|         std::string m_description; | ||||
|         std::set<std::string> m_tags; | ||||
|   | ||||
| @@ -16,10 +16,12 @@ namespace Catch { | ||||
|  | ||||
|      | ||||
|     TestCaseInfo::TestCaseInfo( ITestCase* testCase, | ||||
|                                 const char* name, | ||||
|                                 const char* description, | ||||
|                                 const std::string& className, | ||||
|                                 const std::string& name, | ||||
|                                 const std::string& description, | ||||
|                                 const SourceLineInfo& lineInfo ) | ||||
|     :   m_test( testCase ), | ||||
|         m_className( className ), | ||||
|         m_name( name ), | ||||
|         m_description( description ), | ||||
|         m_lineInfo( lineInfo ), | ||||
| @@ -32,6 +34,7 @@ namespace Catch { | ||||
|  | ||||
|     TestCaseInfo::TestCaseInfo() | ||||
|     :   m_test( NULL ), | ||||
|         m_className(), | ||||
|         m_name(), | ||||
|         m_description(), | ||||
|         m_isHidden( false ) | ||||
| @@ -39,6 +42,7 @@ namespace Catch { | ||||
|  | ||||
|     TestCaseInfo::TestCaseInfo( const TestCaseInfo& other, const std::string& name ) | ||||
|     :   m_test( other.m_test ), | ||||
|         m_className( other.m_className ), | ||||
|         m_name( name ), | ||||
|         m_description( other.m_description ), | ||||
|         m_tags( other.m_tags ), | ||||
| @@ -48,6 +52,7 @@ namespace Catch { | ||||
|  | ||||
|     TestCaseInfo::TestCaseInfo( const TestCaseInfo& other ) | ||||
|     :   m_test( other.m_test ), | ||||
|         m_className( other.m_className ), | ||||
|         m_name( other.m_name ), | ||||
|         m_description( other.m_description ), | ||||
|         m_tags( other.m_tags ), | ||||
| @@ -59,14 +64,15 @@ namespace Catch { | ||||
|         m_test->invoke(); | ||||
|     } | ||||
|  | ||||
|     const std::string& TestCaseInfo::getClassName() const { | ||||
|         return m_className; | ||||
|     } | ||||
|     const std::string& TestCaseInfo::getName() const { | ||||
|         return m_name; | ||||
|     } | ||||
|  | ||||
|     const std::string& TestCaseInfo::getDescription() const { | ||||
|         return m_description; | ||||
|     } | ||||
|  | ||||
|     const SourceLineInfo& TestCaseInfo::getLineInfo() const { | ||||
|         return m_lineInfo; | ||||
|     } | ||||
| @@ -89,13 +95,16 @@ namespace Catch { | ||||
|  | ||||
|     void TestCaseInfo::swap( TestCaseInfo& other ) { | ||||
|         m_test.swap( other.m_test ); | ||||
|         m_className.swap( other.m_className ); | ||||
|         m_name.swap( other.m_name ); | ||||
|         m_description.swap( other.m_description ); | ||||
|         m_lineInfo.swap( other.m_lineInfo ); | ||||
|         std::swap( m_lineInfo, other.m_lineInfo ); | ||||
|     } | ||||
|  | ||||
|     bool TestCaseInfo::operator == ( const TestCaseInfo& other ) const { | ||||
|         return m_test.get() == other.m_test.get() && m_name == other.m_name; | ||||
|         return  m_test.get() == other.m_test.get() && | ||||
|                 m_name == other.m_name && | ||||
|                 m_className == other.m_className; | ||||
|     } | ||||
|  | ||||
|     bool TestCaseInfo::operator < ( const TestCaseInfo& other ) const { | ||||
|   | ||||
| @@ -107,23 +107,38 @@ namespace Catch { | ||||
|  | ||||
|         TestFunction m_fun; | ||||
|     }; | ||||
|          | ||||
|  | ||||
|     inline std::string extractClassName( const std::string& classOrQualifiedMethodName ) { | ||||
|         std::string className = classOrQualifiedMethodName; | ||||
|         if( className[0] == '&' ) | ||||
|         { | ||||
|             std::size_t lastColons = className.rfind( "::" ); | ||||
|             std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); | ||||
|             if( penultimateColons == std::string::npos ) | ||||
|                 penultimateColons = 1; | ||||
|             className = className.substr( penultimateColons, lastColons-penultimateColons ); | ||||
|         } | ||||
|         return className; | ||||
|     } | ||||
|      | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|      | ||||
|     AutoReg::AutoReg(   TestFunction function,  | ||||
|                         const char* name, | ||||
|                         const char* description, | ||||
|                         const SourceLineInfo& lineInfo ) { | ||||
|         registerTestCase( new FreeFunctionTestCase( function ), name, description, lineInfo ); | ||||
|         registerTestCase( new FreeFunctionTestCase( function ), "global", name, description, lineInfo ); | ||||
|     }     | ||||
|      | ||||
|     AutoReg::~AutoReg() {} | ||||
|      | ||||
|     void AutoReg::registerTestCase( ITestCase* testCase,  | ||||
|                                     const char* name,  | ||||
|     void AutoReg::registerTestCase( ITestCase* testCase, | ||||
|                                     const char* classOrQualifiedMethodName, | ||||
|                                     const char* name, | ||||
|                                     const char* description, | ||||
|                                     const SourceLineInfo& lineInfo ) { | ||||
|         getMutableRegistryHub().registerTest( TestCaseInfo( testCase, name, description, lineInfo ) ); | ||||
|          | ||||
|         getMutableRegistryHub().registerTest( TestCaseInfo( testCase, extractClassName( classOrQualifiedMethodName ), name, description, lineInfo ) ); | ||||
|     } | ||||
|      | ||||
| } // end namespace Catch | ||||
|   | ||||
| @@ -34,21 +34,23 @@ typedef void(*TestFunction)(); | ||||
|      | ||||
| struct AutoReg { | ||||
|  | ||||
|     AutoReg(    TestFunction function,  | ||||
|     AutoReg(    TestFunction function, | ||||
|                 const char* name,  | ||||
|                 const char* description, | ||||
|                 const SourceLineInfo& lineInfo ); | ||||
|      | ||||
|     template<typename C> | ||||
|     AutoReg(    void (C::*method)(),  | ||||
|     AutoReg(    void (C::*method)(), | ||||
|                 const char* className, | ||||
|                 const char* name,  | ||||
|                 const char* description, | ||||
|                 const SourceLineInfo& lineInfo ) { | ||||
|         registerTestCase( new MethodTestCase<C>( method ), name, description, lineInfo ); | ||||
|         registerTestCase( new MethodTestCase<C>( method ), className, name, description, lineInfo ); | ||||
|     } | ||||
|      | ||||
|     void registerTestCase(  ITestCase* testCase,  | ||||
|                             const char* name,  | ||||
|                             const char* className, | ||||
|                             const char* name, | ||||
|                             const char* description, | ||||
|                             const SourceLineInfo& lineInfo ); | ||||
|      | ||||
| @@ -75,7 +77,7 @@ private: | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ | ||||
|     namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, Name, Desc, CATCH_INTERNAL_LINEINFO ); } | ||||
|     namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Name, Desc, CATCH_INTERNAL_LINEINFO ); } | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define TEST_CASE_METHOD( ClassName, TestName, Desc )\ | ||||
| @@ -83,7 +85,7 @@ private: | ||||
|         struct INTERNAL_CATCH_UNIQUE_NAME( TestCaseMethod_catch_internal_ ) : ClassName{ \ | ||||
|             void test(); \ | ||||
|         }; \ | ||||
|         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( TestCaseMethod_catch_internal_ )::test, TestName, Desc, CATCH_INTERNAL_LINEINFO ); \ | ||||
|         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( TestCaseMethod_catch_internal_ )::test, #ClassName, TestName, Desc, CATCH_INTERNAL_LINEINFO ); \ | ||||
|     } \ | ||||
|     void INTERNAL_CATCH_UNIQUE_NAME( TestCaseMethod_catch_internal_ )::test() | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash