From 2212cdfe26415586c06e379a2400b1ee171382d3 Mon Sep 17 00:00:00 2001 From: Neal Coombes Date: Mon, 26 Jun 2017 14:30:23 -0500 Subject: [PATCH] Eliminate some work when results won't be reported. --- include/internal/catch_capture.hpp | 4 +- include/internal/catch_interfaces_capture.h | 4 ++ include/internal/catch_result_builder.cpp | 45 +++++++++++++-------- include/internal/catch_result_builder.h | 6 ++- include/internal/catch_run_context.cpp | 14 +++++++ include/internal/catch_run_context.hpp | 7 ++++ 6 files changed, 60 insertions(+), 20 deletions(-) diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp index 574361d0..d331e19b 100644 --- a/include/internal/catch_capture.hpp +++ b/include/internal/catch_capture.hpp @@ -83,12 +83,12 @@ /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ - if( Catch::getResultCapture().getLastResult()->succeeded() ) + if( Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \ INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ - if( !Catch::getResultCapture().getLastResult()->succeeded() ) + if( !Catch::getResultCapture().lastAssertionPassed() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \ 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.cpp b/include/internal/catch_result_builder.cpp index 6268f8d1..c5ea8119 100644 --- a/include/internal/catch_result_builder.cpp +++ b/include/internal/catch_result_builder.cpp @@ -34,14 +34,12 @@ namespace Catch { char const* capturedExpression, ResultDisposition::Flags resultDisposition ) : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition) - { - m_stream().oss.str(""); - } + {} 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(); } @@ -58,13 +56,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 ); } @@ -142,17 +152,12 @@ namespace Catch { // It should immediately be passed to handleResult; if the expression // needs to be reported, its string expansion must be composed before // the temporaries are destroyed. - AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const - { + AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const { 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 ); } @@ -168,7 +173,15 @@ namespace Catch { m_guardException = false; } - CopyableStream& ResultBuilder::m_stream() { + CopyableStream& ResultBuilder::stream() { + if( !m_usedStream ) { + m_usedStream = true; + s_stream().oss.str(""); + } + return s_stream(); + } + + CopyableStream& ResultBuilder::s_stream() { static CopyableStream s; return s; } diff --git a/include/internal/catch_result_builder.h b/include/internal/catch_result_builder.h index 90cbf5be..6639b541 100644 --- a/include/internal/catch_result_builder.h +++ b/include/internal/catch_result_builder.h @@ -43,7 +43,7 @@ namespace Catch { template ResultBuilder& operator << ( T const& value ) { - m_stream().oss << value; + stream().oss << value; return *this; } @@ -79,11 +79,13 @@ namespace Catch { AssertionInfo m_assertionInfo; AssertionResultData m_data; - static CopyableStream& m_stream(); + CopyableStream& stream(); + static CopyableStream& s_stream(); bool m_shouldDebugBreak = false; bool m_shouldThrow = false; bool m_guardException = false; + bool m_usedStream = false; }; } // namespace Catch diff --git a/include/internal/catch_run_context.cpp b/include/internal/catch_run_context.cpp index 31d6b8a6..bfde432b 100644 --- a/include/internal/catch_run_context.cpp +++ b/include/internal/catch_run_context.cpp @@ -213,6 +213,20 @@ namespace Catch { m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false)); } + bool RunContext::lastAssertionPassed() { + return m_totals.assertions.passed == (m_prevPassed + 1); + } + + void RunContext::assertionPassed() { + ++m_totals.assertions.passed; + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; + m_lastAssertionInfo.macroName = ""; + } + + void RunContext::assertionRun() { + m_prevPassed = m_totals.assertions.passed; + } + bool RunContext::aborting() const { return m_totals.assertions.failed == static_cast(m_config->abortAfter()); } diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index c513788b..9d065ae5 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -84,6 +84,12 @@ namespace Catch { virtual void handleFatalErrorCondition(std::string const& message) override; + virtual bool lastAssertionPassed() override; + + virtual void assertionPassed(); + + virtual void assertionRun(); + public: // !TBD We need to do this another way! bool aborting() const override; @@ -113,6 +119,7 @@ namespace Catch { std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; + size_t m_prevPassed = 0; bool m_shouldReportUnexpected = true; };