Squashed commit of the following:

commit 70c5ef9eed
Author: Phil Nash <github@philnash.me>
Date:   Tue Nov 13 21:46:01 2012 +0000

    Regen single include

commit 4ea535e505
Author: Phil Nash <github@philnash.me>
Date:   Tue Nov 13 09:56:30 2012 +0000

    Tidied up result enums

commit 7717c29072
Author: Phil Nash <github@philnash.me>
Date:   Tue Nov 13 09:45:29 2012 +0000

    Implemented CHECK_NOFAIL

    Previous commit missed some files

commit d539da9030
Author: Phil Nash <github@philnash.me>
Date:   Tue Nov 13 09:44:52 2012 +0000

    Implemented CHECK_NO_FAIL

commit af1a321860
Author: Phil Nash <github@philnash.me>
Date:   Sat Nov 10 18:46:39 2012 +0000

    Regen single include

commit f54ac5625e
Author: Phil Nash <github@philnash.me>
Date:   Sat Nov 10 18:44:12 2012 +0000

    New (combined) baselines

commit defca58566
Author: Phil Nash <github@philnash.me>
Date:   Sat Nov 10 18:43:23 2012 +0000

    negate() -> endExpression(), takes ResultDisposition

commit b2ef998825
Author: Phil Nash <github@philnash.me>
Date:   Sat Nov 10 10:35:09 2012 +0000

    Changed shouldNegate boolean to use part of ResultDisposition enum

commit 1af13dba97
Author: Phil Nash <github@philnash.me>
Date:   Sat Nov 10 10:20:08 2012 +0000

    Changed StopOnFailure boolean to an enum

commit a1dc7e312c
Author: Phil Nash <github@philnash.me>
Date:   Tue Nov 6 19:34:35 2012 +0000

    Regen single include

commit 20e59ce9d1
Author: Phil Nash <github@philnash.me>
Date:   Tue Nov 6 19:34:10 2012 +0000

    Added tags docs

commit b5b1b1e430
Author: Phil Nash <github@philnash.me>
Date:   Tue Nov 6 19:13:25 2012 +0000

    Some expression/ evaluation clean-up

commit ec5956f471
Author: 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

commit 88b70828f2
Author: Phil Nash <github@philnash.me>
Date:   Sun Nov 4 21:39:38 2012 +0000

    Regen single include

commit b323fc7e6c
Author: 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)

commit 78fba28c4b
Author: 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.

commit 81cb69ef18
Author: Phil Nash <github@philnash.me>
Date:   Sun Nov 4 21:09:22 2012 +0000

    AssertionInfo captures more info (for test cases and sections)

commit a4e088c999
Author: Phil Nash <github@philnash.me>
Date:   Fri Nov 2 08:29:03 2012 +0000

    Removed __FUNCTION__ from SourceLineInfo

commit 2a1e8bfc6e
Author: Phil Nash <github@philnash.me>
Date:   Thu Nov 1 08:16:15 2012 +0000

    Updated colour comments

commit f0f407fc3e
Author: Phil Nash <github@philnash.me>
Date:   Wed Oct 31 18:28:21 2012 +0000

    Manually applied merge #133 from Master

commit 355b95fda1
Author: Phil Nash <github@philnash.me>
Date:   Wed Oct 31 18:04:22 2012 +0000

    Cleaned up ANSI colour code impl a bit

commit 778f9c4fc7
Author: Phil Nash <github@philnash.me>
Date:   Tue Oct 30 09:09:30 2012 +0000

    Removed "no-" from Wno-global-constructors when disabling

commit 5efa4bcb8a
Author: Phil Nash <github@philnash.me>
Date:   Mon Oct 29 20:49:22 2012 +0000

    Regenerated single_include

commit 108f1937d8
Author: 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

commit 8f4cc541d5
Author: Phil Nash <github@philnash.me>
Date:   Mon Oct 29 19:55:34 2012 +0000

    Added regression test baselines

commit 2e203a1834
Author: Phil Nash <github@philnash.me>
Date:   Mon Oct 29 19:55:13 2012 +0000

    Fixed remaining reporting regressions

commit 134e45b3ad
Author: Phil Nash <github@philnash.me>
Date:   Sun Oct 28 20:57:21 2012 +0000

    Fixed #132

commit 2f92db9898
Author: Phil Nash <github@philnash.me>
Date:   Sun Oct 28 12:15:34 2012 +0000

    Updated the readme specifically for the Integration branch

commit 82acc2ca05
Author: Phil Nash <github@philnash.me>
Date:   Sun Oct 28 12:07:17 2012 +0000

    Regenerated single include

commit fe1d7c1d08
Author: Phil Nash <github@philnash.me>
Date:   Sun Oct 28 10:27:44 2012 +0000

    Small fixes and tweaks

commit 355b5e546d
Author: Phil Nash <github@philnash.me>
Date:   Fri Oct 26 09:05:36 2012 +0100

    Some tidy-up

commit f847186ebb
Author: Phil Nash <github@philnash.me>
Date:   Fri Oct 26 08:45:23 2012 +0100

    AssertionResultBuilder -> ExpressionResultBuilder

commit 8cca2f1369
Author: Phil Nash <github@philnash.me>
Date:   Wed Oct 24 22:09:01 2012 +0100

    ExpressionBuilder ->ExpressionDecomposer
    Expression -> ExpressionLhs

commit e04e74f896
Author: Phil Nash <github@philnash.me>
Date:   Wed Oct 24 21:59:47 2012 +0100

    More AssertionResult refactoring

commit 1dd56d4d2b
Author: Phil Nash <github@philnash.me>
Date:   Fri Oct 19 08:01:34 2012 +0100

    AssertionResultBuilder can be constructed from result type

commit f2d5f1b3e4
Author: 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

commit e3b111a39a
Author: Phil Nash <github@philnash.me>
Date:   Thu Oct 18 22:59:16 2012 +0100

    streamlined acceptResult

commit 3ad13256e1
Author: Phil Nash <github@philnash.me>
Date:   Thu Oct 18 08:39:44 2012 +0100

    Refactored assertion builder stuff out of expression builder

commit c96f9330a0
Author: Phil Nash <github@philnash.me>
Date:   Wed Oct 17 08:14:22 2012 +0100

    Collect assertion info up front

commit a5fa78284d
Author: Phil Nash <github@philnash.me>
Date:   Tue Oct 16 08:33:13 2012 +0100

    ResultData -> AssertionResultData

commit c597a893fa
Author: Phil Nash <github@philnash.me>
Date:   Tue Oct 16 08:31:05 2012 +0100

    ResultInfo -> AssertionResult filenames and variables

commit d16955f63a
Author: Phil Nash <github@philnash.me>
Date:   Tue Oct 16 08:27:21 2012 +0100

    Renamed ResultInfo -> AssertionResult

commit 175da3ef64
Author: Phil Nash <github@philnash.me>
Date:   Fri Oct 12 18:39:22 2012 +0100

    regen test 3
This commit is contained in:
Phil Nash
2012-11-13 21:59:50 +00:00
parent 4f13f5b7d3
commit 42d1b45386
29 changed files with 937 additions and 241 deletions

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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 ) )

View File

@@ -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 ) {

View File

@@ -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;
};

View File

@@ -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 ) );
}

View File

@@ -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.

View File

@@ -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 ) {

View File

@@ -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 ) {

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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

View File

@@ -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()