diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp index a6d25dad..b64cb965 100644 --- a/include/internal/catch_capture.hpp +++ b/include/internal/catch_capture.hpp @@ -83,12 +83,12 @@ /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ - if( Catch::getResultCapture().getLastResult()->succeeded() ) + if( Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ - if( !Catch::getResultCapture().getLastResult()->succeeded() ) + if( !Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \ diff --git a/include/internal/catch_interfaces_capture.h b/include/internal/catch_interfaces_capture.h index 35b62dd9..54cf0e4d 100644 --- a/include/internal/catch_interfaces_capture.h +++ b/include/internal/catch_interfaces_capture.h @@ -41,6 +41,10 @@ namespace Catch { virtual void exceptionEarlyReported() = 0; virtual void handleFatalErrorCondition( std::string const& message ) = 0; + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + virtual void assertionRun() = 0; }; IResultCapture& getResultCapture(); diff --git a/include/internal/catch_result_builder.h b/include/internal/catch_result_builder.h index b1808cc0..995be818 100644 --- a/include/internal/catch_result_builder.h +++ b/include/internal/catch_result_builder.h @@ -47,7 +47,7 @@ namespace Catch { template ResultBuilder& operator << ( T const& value ) { - m_stream().oss << value; + stream().oss << value; return *this; } @@ -81,6 +81,16 @@ namespace Catch { AssertionInfo m_assertionInfo; AssertionResultData m_data; + CopyableStream &stream() + { + if(!m_usedStream) + { + m_usedStream = true; + m_stream().oss.str(""); + } + return m_stream(); + } + static CopyableStream &m_stream() { static CopyableStream s; @@ -90,6 +100,7 @@ namespace Catch { bool m_shouldDebugBreak; bool m_shouldThrow; bool m_guardException; + bool m_usedStream; }; } // namespace Catch diff --git a/include/internal/catch_result_builder.hpp b/include/internal/catch_result_builder.hpp index 2abb9a91..e7a5bdd2 100644 --- a/include/internal/catch_result_builder.hpp +++ b/include/internal/catch_result_builder.hpp @@ -26,15 +26,14 @@ namespace Catch { : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ), m_shouldDebugBreak( false ), m_shouldThrow( false ), - m_guardException( false ) - { - m_stream().oss.str(""); - } + m_guardException( false ), + m_usedStream( false ) + {} ResultBuilder::~ResultBuilder() { #if defined(CATCH_CONFIG_FAST_COMPILE) if ( m_guardException ) { - m_stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; + stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; captureResult( ResultWas::ThrewException ); getCurrentContext().getResultCapture()->exceptionEarlyReported(); } @@ -51,13 +50,25 @@ namespace Catch { } void ResultBuilder::endExpression( DecomposedExpression const& expr ) { - AssertionResult result = build( expr ); - handleResult( result ); + // Flip bool results if FalseTest flag is set + if( isFalseTest( m_assertionInfo.resultDisposition ) ) { + m_data.negate( expr.isBinaryExpression() ); + } + + getResultCapture().assertionRun(); + + if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok) + { + AssertionResult result = build( expr ); + handleResult( result ); + } + else + getResultCapture().assertionPassed(); } void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { m_assertionInfo.resultDisposition = resultDisposition; - m_stream().oss << Catch::translateActiveException(); + stream().oss << Catch::translateActiveException(); captureResult( ResultWas::ThrewException ); } @@ -140,12 +151,8 @@ namespace Catch { assert( m_data.resultType != ResultWas::Unknown ); AssertionResultData data = m_data; - // Flip bool results if FalseTest flag is set - if( isFalseTest( m_assertionInfo.resultDisposition ) ) { - data.negate( expr.isBinaryExpression() ); - } - - data.message = m_stream().oss.str(); + if(m_usedStream) + data.message = m_stream().oss.str(); data.decomposedExpression = &expr; // for lazy reconstruction return AssertionResult( m_assertionInfo, data ); } diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index b3dee17f..88c56603 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -154,6 +154,23 @@ namespace Catch { m_lastResult = result; } + virtual bool lastAssertionPassed() + { + return m_totals.assertions.passed == (m_prevPassed + 1); + } + + virtual void assertionPassed() + { + m_totals.assertions.passed++; + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; + m_lastAssertionInfo.macroName = ""; + } + + virtual void assertionRun() + { + m_prevPassed = m_totals.assertions.passed; + } + virtual bool sectionStarted ( SectionInfo const& sectionInfo, Counts& assertions @@ -364,6 +381,7 @@ namespace Catch { std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; + size_t m_prevPassed; bool m_shouldReportUnexpected; };