More AssertionResult refactoring

This commit is contained in:
Phil Nash 2012-10-24 21:59:47 +01:00
parent 1dd56d4d2b
commit e04e74f896
12 changed files with 95 additions and 112 deletions

View File

@ -71,9 +71,9 @@
#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, false, "CATCH_WARN" ) #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, false, "CATCH_WARN" )
#define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, true, "CATCH_FAIL" ) #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, true, "CATCH_FAIL" )
#define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, false, "CATCH_SUCCEED" ) #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, false, "CATCH_SUCCEED" )
#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg ) #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg, "CATCH_SCOPED_INFO" )
#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, false, "CATCH_CAPTURE" ) #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, false, "CATCH_CAPTURE" )
#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg ) #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg, "CATCH_SCOPED_CAPTURE" )
#define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
@ -116,9 +116,9 @@
#define WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, false, "WARN" ) #define WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, false, "WARN" )
#define FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, true, "FAIL" ) #define FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, true, "FAIL" )
#define SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, false, "SUCCEED" ) #define SUCCEED( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Ok, false, "SUCCEED" )
#define SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg ) #define SCOPED_INFO( msg ) INTERNAL_CATCH_SCOPED_INFO( msg, "SCOPED_INFO" )
#define CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, false, "CAPTURE" ) #define CAPTURE( msg ) INTERNAL_CATCH_MSG( #msg " := " << msg, Catch::ResultWas::Info, false, "CAPTURE" )
#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg ) #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_SCOPED_INFO( #msg " := " << msg, "SCOPED_CAPTURE" )
#define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )

View File

@ -16,11 +16,14 @@ namespace Catch {
struct AssertionInfo struct AssertionInfo
{ {
AssertionInfo() {} AssertionInfo() {}
AssertionInfo( const std::string& _macroName, const SourceLineInfo& _lineInfo, const std::string& _capturedExpression ) AssertionInfo( const std::string& _macroName, const SourceLineInfo& _lineInfo, const std::string& _capturedExpression, bool _shouldNegate )
: macroName( _macroName ), : macroName( _macroName ),
lineInfo( _lineInfo ), lineInfo( _lineInfo ),
capturedExpression( _capturedExpression ) capturedExpression( _capturedExpression )
{} {
if( _shouldNegate )
capturedExpression = "!" + _capturedExpression;
}
std::string macroName; std::string macroName;
SourceLineInfo lineInfo; SourceLineInfo lineInfo;
@ -31,9 +34,6 @@ namespace Catch {
{ {
AssertionResultData() : resultType( ResultWas::Unknown ) {} AssertionResultData() : resultType( ResultWas::Unknown ) {}
std::string macroName;
SourceLineInfo lineInfo;
std::string capturedExpression;
std::string reconstructedExpression; std::string reconstructedExpression;
std::string message; std::string message;
ResultWas::OfType resultType; ResultWas::OfType resultType;
@ -42,7 +42,7 @@ namespace Catch {
class AssertionResult { class AssertionResult {
public: public:
AssertionResult(); AssertionResult();
AssertionResult( const AssertionResultData& data ); AssertionResult( const AssertionInfo& info, const AssertionResultData& data );
~AssertionResult(); ~AssertionResult();
bool ok() const; bool ok() const;
@ -53,12 +53,12 @@ namespace Catch {
bool hasExpandedExpression() const; bool hasExpandedExpression() const;
std::string getExpandedExpression() const; std::string getExpandedExpression() const;
std::string getMessage() const; std::string getMessage() const;
std::string getFilename() const; SourceLineInfo getSourceInfo() const;
std::size_t getLine() const;
std::string getTestMacroName() const; std::string getTestMacroName() const;
protected: protected:
AssertionResultData m_data; AssertionInfo m_info;
AssertionResultData m_resultData;
}; };
} // end namespace Catch } // end namespace Catch

View File

@ -14,28 +14,31 @@ namespace Catch {
AssertionResult::AssertionResult() {} AssertionResult::AssertionResult() {}
AssertionResult::AssertionResult( const AssertionResultData& data ) : m_data( data ) {} AssertionResult::AssertionResult( const AssertionInfo& info, const AssertionResultData& data )
: m_info( info ),
m_resultData( data )
{}
AssertionResult::~AssertionResult() {} AssertionResult::~AssertionResult() {}
bool AssertionResult::ok() const { bool AssertionResult::ok() const {
return isOk( m_data.resultType ); return isOk( m_resultData.resultType );
} }
ResultWas::OfType AssertionResult::getResultType() const { ResultWas::OfType AssertionResult::getResultType() const {
return m_data.resultType; return m_resultData.resultType;
} }
bool AssertionResult::hasExpression() const { bool AssertionResult::hasExpression() const {
return !m_data.capturedExpression.empty(); return !m_info.capturedExpression.empty();
} }
bool AssertionResult::hasMessage() const { bool AssertionResult::hasMessage() const {
return !m_data.message.empty(); return !m_resultData.message.empty();
} }
std::string AssertionResult::getExpression() const { std::string AssertionResult::getExpression() const {
return m_data.capturedExpression; return m_info.capturedExpression;
} }
bool AssertionResult::hasExpandedExpression() const { bool AssertionResult::hasExpandedExpression() const {
@ -43,23 +46,18 @@ namespace Catch {
} }
std::string AssertionResult::getExpandedExpression() const { std::string AssertionResult::getExpandedExpression() const {
return m_data.reconstructedExpression; return m_resultData.reconstructedExpression;
} }
std::string AssertionResult::getMessage() const { std::string AssertionResult::getMessage() const {
return m_data.message; return m_resultData.message;
} }
SourceLineInfo AssertionResult::getSourceInfo() const {
std::string AssertionResult::getFilename() const { return m_info.lineInfo;
return m_data.lineInfo.file;
}
std::size_t AssertionResult::getLine() const {
return m_data.lineInfo.line;
} }
std::string AssertionResult::getTestMacroName() const { std::string AssertionResult::getTestMacroName() const {
return m_data.macroName; return m_info.macroName;
} }
} // end namespace Catch } // end namespace Catch

View File

@ -26,13 +26,12 @@ public:
AssertionResultBuilder& operator=(const AssertionResultBuilder& other ); AssertionResultBuilder& operator=(const AssertionResultBuilder& other );
AssertionResultBuilder& setResultType( ResultWas::OfType result ); AssertionResultBuilder& setResultType( ResultWas::OfType result );
AssertionResultBuilder& setCapturedExpression( const std::string& capturedExpression ); AssertionResultBuilder& setResultType( bool result );
AssertionResultBuilder& setIsFalse( bool isFalse );
AssertionResultBuilder& setLineInfo( const SourceLineInfo& lineInfo );
AssertionResultBuilder& setLhs( const std::string& lhs ); AssertionResultBuilder& setLhs( const std::string& lhs );
AssertionResultBuilder& setRhs( const std::string& rhs ); AssertionResultBuilder& setRhs( const std::string& rhs );
AssertionResultBuilder& setOp( const std::string& op ); AssertionResultBuilder& setOp( const std::string& op );
AssertionResultBuilder& setMacroName( const std::string& macroName );
AssertionResultBuilder& negate( bool shouldNegate );
template<typename T> template<typename T>
AssertionResultBuilder& operator << ( const T& value ) { AssertionResultBuilder& operator << ( const T& value ) {
@ -40,9 +39,9 @@ public:
return *this; return *this;
} }
std::string reconstructExpression() const; std::string reconstructExpression( const AssertionInfo& info ) const;
AssertionResult build() const; AssertionResultData build( const AssertionInfo& info ) const;
// Disable attempts to use || and && in expressions (without parantheses) // Disable attempts to use || and && in expressions (without parantheses)
template<typename RhsT> template<typename RhsT>
@ -53,8 +52,8 @@ public:
private: private:
AssertionResultData m_data; AssertionResultData m_data;
struct ExprComponents { struct ExprComponents {
ExprComponents() : isFalse( false ) {} ExprComponents() : shouldNegate( false ) {}
bool isFalse; bool shouldNegate;
std::string lhs, rhs, op; std::string lhs, rhs, op;
} m_exprComponents; } m_exprComponents;
std::ostringstream m_stream; std::ostringstream m_stream;

View File

@ -34,20 +34,12 @@ namespace Catch {
m_data.resultType = result; m_data.resultType = result;
return *this; return *this;
} }
AssertionResultBuilder& AssertionResultBuilder::setCapturedExpression( const std::string& capturedExpression ) { AssertionResultBuilder& AssertionResultBuilder::setResultType( bool result ) {
m_data.capturedExpression = capturedExpression; m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
return *this; return *this;
} }
AssertionResultBuilder& AssertionResultBuilder::setIsFalse( bool isFalse ) { AssertionResultBuilder& AssertionResultBuilder::negate( bool shouldNegate ) {
m_exprComponents.isFalse = isFalse; m_exprComponents.shouldNegate = shouldNegate;
return *this;
}
AssertionResultBuilder& AssertionResultBuilder::setLineInfo( const SourceLineInfo& lineInfo ) {
m_data.lineInfo = lineInfo;
return *this;
}
AssertionResultBuilder& AssertionResultBuilder::setMacroName( const std::string& macroName ) {
m_data.macroName = macroName;
return *this; return *this;
} }
AssertionResultBuilder& AssertionResultBuilder::setLhs( const std::string& lhs ) { AssertionResultBuilder& AssertionResultBuilder::setLhs( const std::string& lhs ) {
@ -62,35 +54,31 @@ namespace Catch {
m_exprComponents.op = op; m_exprComponents.op = op;
return *this; return *this;
} }
AssertionResult AssertionResultBuilder::build() const AssertionResultData AssertionResultBuilder::build( const AssertionInfo& info ) const
{ {
assert( m_data.resultType != ResultWas::Unknown ); assert( m_data.resultType != ResultWas::Unknown );
AssertionResultData data = m_data; AssertionResultData data = m_data;
// Flip bool results if isFalse is set // Flip bool results if shouldNegate is set
if( m_exprComponents.isFalse && data.resultType == ResultWas::Ok ) if( m_exprComponents.shouldNegate && data.resultType == ResultWas::Ok )
data.resultType = ResultWas::ExpressionFailed; data.resultType = ResultWas::ExpressionFailed;
else if( m_exprComponents.isFalse && data.resultType == ResultWas::ExpressionFailed ) else if( m_exprComponents.shouldNegate && data.resultType == ResultWas::ExpressionFailed )
data.resultType = ResultWas::Ok; data.resultType = ResultWas::Ok;
data.message = m_stream.str(); data.message = m_stream.str();
data.reconstructedExpression = reconstructExpression(); data.reconstructedExpression = reconstructExpression( info );
if( m_exprComponents.isFalse ) { if( m_exprComponents.shouldNegate ) {
if( m_exprComponents.op == "" ) { if( m_exprComponents.op == "" )
data.capturedExpression = "!" + data.capturedExpression;
data.reconstructedExpression = "!" + data.reconstructedExpression; data.reconstructedExpression = "!" + data.reconstructedExpression;
} else
else {
data.capturedExpression = "!(" + data.capturedExpression + ")";
data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
}
} }
return AssertionResult( data ); return data;
} }
std::string AssertionResultBuilder::reconstructExpression() const { std::string AssertionResultBuilder::reconstructExpression( const AssertionInfo& info ) const {
if( m_exprComponents.op == "" ) if( m_exprComponents.op == "" )
return m_exprComponents.lhs.empty() ? m_data.capturedExpression : m_exprComponents.op + m_exprComponents.lhs; return m_exprComponents.lhs.empty() ? info.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
else if( m_exprComponents.op == "matches" ) else if( m_exprComponents.op == "matches" )
return m_exprComponents.lhs + " " + m_exprComponents.rhs; return m_exprComponents.lhs + " " + m_exprComponents.rhs;
else if( m_exprComponents.op != "!" ) { else if( m_exprComponents.op != "!" ) {
@ -102,7 +90,7 @@ namespace Catch {
return "\n" + m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs + "\n\n"; return "\n" + m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs + "\n\n";
} }
else else
return "{can't expand - use " + m_data.macroName + "_FALSE( " + m_data.capturedExpression.substr(1) + " ) instead of " + m_data.macroName + "( " + m_data.capturedExpression + " ) for better diagnostics}"; return "{can't expand - use " + info.macroName + "_FALSE( " + info.capturedExpression.substr(1) + " ) instead of " + info.macroName + "( " + info.capturedExpression + " ) for better diagnostics}";
} }
} // end namespace Catch } // end namespace Catch

View File

@ -40,7 +40,7 @@ namespace Catch {
const std::string& matcherCallAsString ) { const std::string& matcherCallAsString ) {
return assertionBuilderFromMatcher( matcher, matcherCallAsString ) return assertionBuilderFromMatcher( matcher, matcherCallAsString )
.setLhs( Catch::toString( arg ) ) .setLhs( Catch::toString( arg ) )
.setResultType( matcher.match( arg ) ? ResultWas::Ok : ResultWas::ExpressionFailed ); .setResultType( matcher.match( arg ) );
} }
template<typename MatcherT, typename ArgT> template<typename MatcherT, typename ArgT>
@ -49,38 +49,30 @@ namespace Catch {
const std::string& matcherCallAsString ) { const std::string& matcherCallAsString ) {
return assertionBuilderFromMatcher( matcher, matcherCallAsString ) return assertionBuilderFromMatcher( matcher, matcherCallAsString )
.setLhs( Catch::toString( arg ) ) .setLhs( Catch::toString( arg ) )
.setResultType( matcher.match( arg ) ? ResultWas::Ok : ResultWas::ExpressionFailed ); .setResultType( matcher.match( arg ) );
} }
struct TestFailureException{}; struct TestFailureException{};
class ScopedInfo { class ScopedInfo {
public: public:
ScopedInfo() { ScopedInfo() : m_resultBuilder( ResultWas::Info ) {
m_resultBuilder
.setResultType( ResultWas::Info )
.setMacroName( "SCOPED_INFO" );
getResultCapture().pushScopedInfo( this ); getResultCapture().pushScopedInfo( this );
} }
~ScopedInfo() { ~ScopedInfo() {
getResultCapture().popScopedInfo( this ); getResultCapture().popScopedInfo( this );
} }
template<typename T> template<typename T>
ScopedInfo& operator << ( const T& value ) { ScopedInfo& operator << ( const T& value ) {
m_resultBuilder << value; m_resultBuilder << value;
return *this; return *this;
} }
AssertionResultData getInfo () const {
AssertionResult getInfo () const { return m_resultBuilder.build( AssertionInfo() ); // !TBD
return m_resultBuilder.build();
} }
private: private:
AssertionResultBuilder m_resultBuilder; AssertionResultBuilder m_resultBuilder;
std::ostringstream m_oss;
}; };
// This is just here to avoid compiler warnings with macro constants and boolean literals // This is just here to avoid compiler warnings with macro constants and boolean literals
@ -98,10 +90,14 @@ inline bool isTrue( bool value ){ return value; }
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( expr, isFalse, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_ACCEPT_INFO( expr, macroName, shouldNegate ) \
Catch::getResultCapture().acceptAssertionInfo( Catch::AssertionInfo( macroName, CATCH_INTERNAL_LINEINFO, #expr, shouldNegate ) );
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( expr, shouldNegate, stopOnFailure, macroName ) \
do { try { \ do { try { \
Catch::getResultCapture().acceptAssertionInfo( Catch::AssertionInfo( macroName, CATCH_INTERNAL_LINEINFO, #expr ) ); \ INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, shouldNegate ); \
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder()->*expr ).setIsFalse( isFalse ), stopOnFailure, expr ); \ INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ExpressionBuilder()->*expr ).negate( shouldNegate ), stopOnFailure, expr ); \
} catch( Catch::TestFailureException& ) { \ } catch( Catch::TestFailureException& ) { \
throw; \ throw; \
} catch( ... ) { \ } catch( ... ) { \
@ -110,19 +106,19 @@ inline bool isTrue( bool value ){ return value; }
} } while( Catch::isTrue( false ) ) } } while( Catch::isTrue( false ) )
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_IF( expr, isFalse, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_IF( expr, shouldNegate, stopOnFailure, macroName ) \
INTERNAL_CATCH_TEST( expr, isFalse, stopOnFailure, macroName ); \ INTERNAL_CATCH_TEST( expr, shouldNegate, stopOnFailure, macroName ); \
if( Catch::getResultCapture().getLastResult()->ok() ) if( Catch::getResultCapture().getLastResult()->ok() )
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_ELSE( expr, isFalse, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_ELSE( expr, shouldNegate, stopOnFailure, macroName ) \
INTERNAL_CATCH_TEST( expr, isFalse, stopOnFailure, macroName ); \ INTERNAL_CATCH_TEST( expr, shouldNegate, stopOnFailure, macroName ); \
if( !Catch::getResultCapture().getLastResult()->ok() ) if( !Catch::getResultCapture().getLastResult()->ok() )
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( expr, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_NO_THROW( expr, stopOnFailure, macroName ) \
try { \ try { \
Catch::getResultCapture().acceptAssertionInfo( Catch::AssertionInfo( macroName, CATCH_INTERNAL_LINEINFO, #expr ) ); \ INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, false ); \
expr; \ expr; \
INTERNAL_CATCH_ACCEPT_EXPR( Catch::AssertionResultBuilder( Catch::ResultWas::Ok ), stopOnFailure, false ); \ INTERNAL_CATCH_ACCEPT_EXPR( Catch::AssertionResultBuilder( Catch::ResultWas::Ok ), stopOnFailure, false ); \
} \ } \
@ -133,7 +129,7 @@ inline bool isTrue( bool value ){ return value; }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_THROWS( expr, exceptionType, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_THROWS( expr, exceptionType, stopOnFailure, macroName ) \
try { \ try { \
Catch::getResultCapture().acceptAssertionInfo( Catch::AssertionInfo( macroName, CATCH_INTERNAL_LINEINFO, #expr ) ); \ INTERNAL_CATCH_ACCEPT_INFO( #expr, macroName, false ); \
if( Catch::getCurrentContext().getConfig()->allowThrows() ) { \ if( Catch::getCurrentContext().getConfig()->allowThrows() ) { \
expr; \ expr; \
INTERNAL_CATCH_ACCEPT_EXPR( Catch::AssertionResultBuilder( Catch::ResultWas::DidntThrowException ), stopOnFailure, false ); \ INTERNAL_CATCH_ACCEPT_EXPR( Catch::AssertionResultBuilder( Catch::ResultWas::DidntThrowException ), stopOnFailure, false ); \
@ -158,14 +154,15 @@ inline bool isTrue( bool value ){ return value; }
INTERNAL_CATCH_ACCEPT_EXPR( Catch::AssertionResultBuilder( resultType ) << reason, stopOnFailure, true ); INTERNAL_CATCH_ACCEPT_EXPR( Catch::AssertionResultBuilder( resultType ) << reason, stopOnFailure, true );
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_SCOPED_INFO( log ) \ #define INTERNAL_CATCH_SCOPED_INFO( log, macroName ) \
INTERNAL_CATCH_ACCEPT_INFO( "", macroName, false ); \
Catch::ScopedInfo INTERNAL_CATCH_UNIQUE_NAME( info ); \ Catch::ScopedInfo INTERNAL_CATCH_UNIQUE_NAME( info ); \
INTERNAL_CATCH_UNIQUE_NAME( info ) << log INTERNAL_CATCH_UNIQUE_NAME( info ) << log
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CHECK_THAT( arg, matcher, stopOnFailure, macroName ) \ #define INTERNAL_CHECK_THAT( arg, matcher, stopOnFailure, macroName ) \
do { try { \ do { try { \
Catch::getResultCapture().acceptAssertionInfo( Catch::AssertionInfo( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher ) ); \ INTERNAL_CATCH_ACCEPT_INFO( #arg " " #matcher, macroName, false ) \
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::assertionBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), stopOnFailure, false ); \ INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::assertionBuilderFromMatcher( ::Catch::Matchers::matcher, arg, #matcher ) ), stopOnFailure, false ); \
} catch( Catch::TestFailureException& ) { \ } catch( Catch::TestFailureException& ) { \
throw; \ throw; \

View File

@ -122,6 +122,9 @@ namespace Catch {
file.swap( other.file ); file.swap( other.file );
std::swap( line, other.line ); std::swap( line, other.line );
} }
bool empty() const {
return file.empty();
}
std::string function; std::string function;
std::string file; std::string file;

View File

@ -13,15 +13,20 @@
namespace Catch { namespace Catch {
template<typename T>
inline void setResultIfBoolean( AssertionResultBuilder&, const T& ) {}
inline void setResultIfBoolean( AssertionResultBuilder& result, bool value ) {
result.setResultType( value );
}
template<typename T> template<typename T>
class Expression { class Expression {
void operator = ( const Expression& ); void operator = ( const Expression& );
public: public:
Expression( T lhs ) : m_lhs( lhs ) { Expression( T lhs ) : m_lhs( lhs ) {
m_result.setLhs( Catch::toString( lhs ) ); setResultIfBoolean( m_result.setLhs( Catch::toString( lhs ) ), lhs );
} }
template<typename RhsT> template<typename RhsT>
AssertionResultBuilder& operator == ( const RhsT& rhs ) { AssertionResultBuilder& operator == ( const RhsT& rhs ) {
return captureExpression<Internal::IsEqualTo>( rhs ); return captureExpression<Internal::IsEqualTo>( rhs );
@ -60,10 +65,8 @@ public:
return captureExpression<Internal::IsNotEqualTo>( rhs ); return captureExpression<Internal::IsNotEqualTo>( rhs );
} }
AssertionResultBuilder setIsFalse( bool isFalse ) { AssertionResultBuilder negate( bool shouldNegate ) {
return m_result return m_result.negate( shouldNegate );
.setResultType( m_lhs ? ResultWas::Ok : ResultWas::ExpressionFailed )
.setIsFalse( isFalse );
} }
template<typename RhsT> template<typename RhsT>
@ -76,7 +79,7 @@ private:
template<Internal::Operator Op, typename RhsT> template<Internal::Operator Op, typename RhsT>
AssertionResultBuilder& captureExpression( const RhsT& rhs ) { AssertionResultBuilder& captureExpression( const RhsT& rhs ) {
return m_result return m_result
.setResultType( Internal::compare<Op>( m_lhs, rhs ) ? ResultWas::Ok : ResultWas::ExpressionFailed ) .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
.setRhs( Catch::toString( rhs ) ) .setRhs( Catch::toString( rhs ) )
.setOp( Internal::OperatorTraits<Op>::getName() ); .setOp( Internal::OperatorTraits<Op>::getName() );
} }

View File

@ -109,7 +109,7 @@ namespace Catch {
do { do {
do { do {
m_currentResult.setLineInfo( m_runningTest->getTestCaseInfo().getLineInfo() ); m_assertionInfo.lineInfo = m_runningTest->getTestCaseInfo().getLineInfo();
runCurrentTest( redirectedCout, redirectedCerr ); runCurrentTest( redirectedCout, redirectedCerr );
} }
while( m_runningTest->hasUntestedSections() && !aborting() ); while( m_runningTest->hasUntestedSections() && !aborting() );
@ -151,7 +151,7 @@ namespace Catch {
std::vector<ScopedInfo*>::const_iterator it = m_scopedInfos.begin(); std::vector<ScopedInfo*>::const_iterator it = m_scopedInfos.begin();
std::vector<ScopedInfo*>::const_iterator itEnd = m_scopedInfos.end(); std::vector<ScopedInfo*>::const_iterator itEnd = m_scopedInfos.end();
for(; it != itEnd; ++it ) for(; it != itEnd; ++it )
m_reporter->Result( (*it)->getInfo() ); m_reporter->Result( AssertionResult( m_assertionInfo, (*it)->getInfo() ) );
} }
{ {
std::vector<AssertionResult>::const_iterator it = m_info.begin(); std::vector<AssertionResult>::const_iterator it = m_info.begin();
@ -181,7 +181,7 @@ namespace Catch {
if( !m_runningTest->addSection( oss.str() ) ) if( !m_runningTest->addSection( oss.str() ) )
return false; return false;
m_currentResult.setLineInfo( lineInfo ); m_assertionInfo.lineInfo = lineInfo;
m_reporter->StartSection( name, description ); m_reporter->StartSection( name, description );
assertions = m_totals.assertions; assertions = m_totals.assertions;
@ -233,12 +233,7 @@ namespace Catch {
private: private:
ResultAction::Value actOnCurrentResult() { ResultAction::Value actOnCurrentResult() {
m_currentResult m_lastResult = AssertionResult( m_assertionInfo, m_currentResult.build( m_assertionInfo ) );
.setMacroName( m_assertionInfo.macroName )
.setLineInfo( m_assertionInfo.lineInfo )
.setCapturedExpression( m_assertionInfo.capturedExpression );
m_lastResult = m_currentResult.build();
testEnded( m_lastResult ); testEnded( m_lastResult );
m_currentResult = AssertionResultBuilder(); m_currentResult = AssertionResultBuilder();

View File

@ -165,9 +165,9 @@ namespace Catch {
startSpansLazily(); startSpansLazily();
if( !assertionResult.getFilename().empty() ) { if( !assertionResult.getSourceInfo().empty() ) {
TextColour colour( TextColour::FileName ); TextColour colour( TextColour::FileName );
m_config.stream << SourceLineInfo( assertionResult.getFilename(), assertionResult.getLine() ); m_config.stream << assertionResult.getSourceInfo();
} }
if( assertionResult.hasExpression() ) { if( assertionResult.hasExpression() ) {

View File

@ -104,7 +104,7 @@ namespace Catch {
std::ostringstream oss; std::ostringstream oss;
if( !assertionResult.getMessage().empty() ) if( !assertionResult.getMessage().empty() )
oss << assertionResult.getMessage() << " at "; oss << assertionResult.getMessage() << " at ";
oss << SourceLineInfo( assertionResult.getFilename(), assertionResult.getLine() ); oss << assertionResult.getSourceInfo();
stats.m_content = oss.str(); stats.m_content = oss.str();
stats.m_message = assertionResult.getExpandedExpression(); stats.m_message = assertionResult.getExpandedExpression();
stats.m_resultType = assertionResult.getTestMacroName(); stats.m_resultType = assertionResult.getTestMacroName();

View File

@ -82,8 +82,8 @@ namespace Catch {
if( assertionResult.hasExpression() ) { if( assertionResult.hasExpression() ) {
m_xml.startElement( "Expression" ) m_xml.startElement( "Expression" )
.writeAttribute( "success", assertionResult.ok() ) .writeAttribute( "success", assertionResult.ok() )
.writeAttribute( "filename", assertionResult.getFilename() ) .writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getLine() ); .writeAttribute( "line", assertionResult.getSourceInfo().line );
m_xml.scopedElement( "Original" ) m_xml.scopedElement( "Original" )
.writeText( assertionResult.getExpression() ); .writeText( assertionResult.getExpression() );
@ -95,8 +95,8 @@ namespace Catch {
switch( assertionResult.getResultType() ) { switch( assertionResult.getResultType() ) {
case ResultWas::ThrewException: case ResultWas::ThrewException:
m_xml.scopedElement( "Exception" ) m_xml.scopedElement( "Exception" )
.writeAttribute( "filename", assertionResult.getFilename() ) .writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getLine() ) .writeAttribute( "line", assertionResult.getSourceInfo().line )
.writeText( assertionResult.getMessage() ); .writeText( assertionResult.getMessage() );
m_currentTestSuccess = false; m_currentTestSuccess = false;
break; break;