From 05743eeaa189d46d3a80dae05eb5c7a665d6b625 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Fri, 22 Aug 2014 19:33:28 +0100 Subject: [PATCH] FatalErrorConditions now full close reporter states - so the console reporter(s) show final summary and the xml reporters close their tags --- include/internal/catch_fatal_condition.hpp | 7 +-- include/internal/catch_interfaces_capture.h | 3 +- include/internal/catch_runner_impl.hpp | 66 ++++++++++++++++----- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/include/internal/catch_fatal_condition.hpp b/include/internal/catch_fatal_condition.hpp index 08c4dcc2..e87e9cfc 100644 --- a/include/internal/catch_fatal_condition.hpp +++ b/include/internal/catch_fatal_condition.hpp @@ -16,11 +16,8 @@ namespace Catch { inline void fatal( std::string const& message, int exitCode ) { IContext& context = Catch::getCurrentContext(); IResultCapture* resultCapture = context.getResultCapture(); - ResultBuilder resultBuilder = resultCapture->makeUnexpectedResultBuilder(); - resultBuilder.setResultType( ResultWas::FatalErrorCondition ); - resultBuilder << message; - resultBuilder.captureExpression(); - + resultCapture->handleFatalErrorCondition( message ); + if( Catch::alwaysTrue() ) // avoids "no return" warnings exit( exitCode ); } diff --git a/include/internal/catch_interfaces_capture.h b/include/internal/catch_interfaces_capture.h index b9d1e874..bdbcfb2f 100644 --- a/include/internal/catch_interfaces_capture.h +++ b/include/internal/catch_interfaces_capture.h @@ -21,7 +21,6 @@ namespace Catch { struct MessageInfo; class ScopedMessageBuilder; struct Counts; - class ResultBuilder; struct IResultCapture { @@ -37,7 +36,7 @@ namespace Catch { virtual std::string getCurrentTestName() const = 0; virtual const AssertionResult* getLastResult() const = 0; - virtual ResultBuilder makeUnexpectedResultBuilder() const = 0; + virtual void handleFatalErrorCondition( std::string const& message ) = 0; }; IResultCapture& getResultCapture(); diff --git a/include/internal/catch_runner_impl.hpp b/include/internal/catch_runner_impl.hpp index 47b2e2be..7b9dcb66 100644 --- a/include/internal/catch_runner_impl.hpp +++ b/include/internal/catch_runner_impl.hpp @@ -210,19 +210,43 @@ namespace Catch { return &m_lastResult; } + virtual void handleFatalErrorCondition( std::string const& message ) { + ResultBuilder resultBuilder = makeUnexpectedResultBuilder(); + resultBuilder.setResultType( ResultWas::FatalErrorCondition ); + resultBuilder << message; + resultBuilder.captureExpression(); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); + m_reporter->sectionEnded( testCaseSectionStats ); + + TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + "", + "", + false ) ); + m_totals.testCases.failed++; + testGroupEnded( "", m_totals, 1, 1 ); + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); + } + public: // !TBD We need to do this another way! bool aborting() const { return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); } - virtual ResultBuilder makeUnexpectedResultBuilder() const { - return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), - m_lastAssertionInfo.lineInfo, - m_lastAssertionInfo.capturedExpression.c_str(), - m_lastAssertionInfo.resultDisposition ); - } - private: void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { @@ -253,14 +277,7 @@ namespace Catch { catch(...) { makeUnexpectedResultBuilder().useActiveException(); } - // If sections ended prematurely due to an exception we stored their - // infos here so we can tear them down outside the unwind process. - for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), - itEnd = m_unfinishedSections.rend(); - it != itEnd; - ++it ) - sectionEnded( it->info, it->prevAssertions, it->durationInSeconds ); - m_unfinishedSections.clear(); + handleUnfinishedSections(); m_messages.clear(); Counts assertions = m_totals.assertions - prevAssertions; @@ -282,6 +299,25 @@ namespace Catch { } private: + + ResultBuilder makeUnexpectedResultBuilder() const { + return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), + m_lastAssertionInfo.lineInfo, + m_lastAssertionInfo.capturedExpression.c_str(), + m_lastAssertionInfo.resultDisposition ); + } + + void handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it ) + sectionEnded( it->info, it->prevAssertions, it->durationInSeconds ); + m_unfinishedSections.clear(); + } + struct UnfinishedSections { UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds ) : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )