FatalErrorConditions now full close reporter states

- so the console reporter(s) show final summary and the xml reporters close their tags
This commit is contained in:
Phil Nash 2014-08-22 19:33:28 +01:00
parent cb8fe472b2
commit 05743eeaa1
3 changed files with 54 additions and 22 deletions

View File

@ -16,11 +16,8 @@ namespace Catch {
inline void fatal( std::string const& message, int exitCode ) { inline void fatal( std::string const& message, int exitCode ) {
IContext& context = Catch::getCurrentContext(); IContext& context = Catch::getCurrentContext();
IResultCapture* resultCapture = context.getResultCapture(); IResultCapture* resultCapture = context.getResultCapture();
ResultBuilder resultBuilder = resultCapture->makeUnexpectedResultBuilder(); resultCapture->handleFatalErrorCondition( message );
resultBuilder.setResultType( ResultWas::FatalErrorCondition );
resultBuilder << message;
resultBuilder.captureExpression();
if( Catch::alwaysTrue() ) // avoids "no return" warnings if( Catch::alwaysTrue() ) // avoids "no return" warnings
exit( exitCode ); exit( exitCode );
} }

View File

@ -21,7 +21,6 @@ namespace Catch {
struct MessageInfo; struct MessageInfo;
class ScopedMessageBuilder; class ScopedMessageBuilder;
struct Counts; struct Counts;
class ResultBuilder;
struct IResultCapture { struct IResultCapture {
@ -37,7 +36,7 @@ namespace Catch {
virtual std::string getCurrentTestName() const = 0; virtual std::string getCurrentTestName() const = 0;
virtual const AssertionResult* getLastResult() const = 0; virtual const AssertionResult* getLastResult() const = 0;
virtual ResultBuilder makeUnexpectedResultBuilder() const = 0; virtual void handleFatalErrorCondition( std::string const& message ) = 0;
}; };
IResultCapture& getResultCapture(); IResultCapture& getResultCapture();

View File

@ -210,19 +210,43 @@ namespace Catch {
return &m_lastResult; 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: public:
// !TBD We need to do this another way! // !TBD We need to do this another way!
bool aborting() const { bool aborting() const {
return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() ); return m_totals.assertions.failed == static_cast<std::size_t>( 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: private:
void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
@ -253,14 +277,7 @@ namespace Catch {
catch(...) { catch(...) {
makeUnexpectedResultBuilder().useActiveException(); makeUnexpectedResultBuilder().useActiveException();
} }
// If sections ended prematurely due to an exception we stored their handleUnfinishedSections();
// infos here so we can tear them down outside the unwind process.
for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
itEnd = m_unfinishedSections.rend();
it != itEnd;
++it )
sectionEnded( it->info, it->prevAssertions, it->durationInSeconds );
m_unfinishedSections.clear();
m_messages.clear(); m_messages.clear();
Counts assertions = m_totals.assertions - prevAssertions; Counts assertions = m_totals.assertions - prevAssertions;
@ -282,6 +299,25 @@ namespace Catch {
} }
private: 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<UnfinishedSections>::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 { struct UnfinishedSections {
UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds ) UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
: info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )