diff --git a/include/internal/catch_common.hpp b/include/internal/catch_common.hpp index 2342ae61..fe6f2c10 100644 --- a/include/internal/catch_common.hpp +++ b/include/internal/catch_common.hpp @@ -87,7 +87,9 @@ namespace Catch { std::srand( config.rngSeed() ); } unsigned int rngSeed() { - return getCurrentContext().getConfig()->rngSeed(); + return getCurrentConfig() + ? getCurrentConfig()->rngSeed() + : 0; } std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { diff --git a/include/internal/catch_console_colour_impl.hpp b/include/internal/catch_console_colour_impl.hpp index 9ca915ff..c9891b17 100644 --- a/include/internal/catch_console_colour_impl.hpp +++ b/include/internal/catch_console_colour_impl.hpp @@ -145,7 +145,7 @@ namespace { }; IColourImpl* platformColourInstance() { - Ptr config = getCurrentContext().getConfig(); + IConfig const* config = getCurrentConfig(); return (config && config->forceColour()) || isatty(STDOUT_FILENO) ? PosixColourImpl::instance() : NoColourImpl::instance(); diff --git a/include/internal/catch_context.h b/include/internal/catch_context.h index 82a297cd..64232b9e 100644 --- a/include/internal/catch_context.h +++ b/include/internal/catch_context.h @@ -28,7 +28,7 @@ namespace Catch { virtual IResultCapture* getResultCapture() = 0; virtual IRunner* getRunner() = 0; - virtual Ptr getConfig() const = 0; + virtual IConfig const* getConfig() const = 0; }; struct IMutableContext : IContext @@ -42,8 +42,7 @@ namespace Catch { IContext& getCurrentContext(); IMutableContext& getCurrentMutableContext(); void cleanUpContext(); - Stream createStream( std::string const& streamName ); - + IConfig const* getCurrentConfig(); } #endif // TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED diff --git a/include/internal/catch_context_impl.hpp b/include/internal/catch_context_impl.hpp index 14caf5ca..b2cb640d 100644 --- a/include/internal/catch_context_impl.hpp +++ b/include/internal/catch_context_impl.hpp @@ -28,8 +28,8 @@ namespace Catch { virtual IRunner* getRunner() { return m_runner; } - virtual Ptr getConfig() const { - return m_config; + virtual IConfig const* getConfig() const { + return m_config.get(); } public: // IMutableContext @@ -67,6 +67,13 @@ namespace Catch { delete currentContext; currentContext = CATCH_NULL; } + + IConfig const* getCurrentConfig() { + return currentContext + ? currentContext->getConfig() + : CATCH_NULL; + } + } #endif // TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED diff --git a/include/internal/catch_result_builder.hpp b/include/internal/catch_result_builder.hpp index d453fecf..c0c04c9f 100644 --- a/include/internal/catch_result_builder.hpp +++ b/include/internal/catch_result_builder.hpp @@ -101,7 +101,7 @@ namespace Catch { getResultCapture().assertionEnded( result ); if( !result.isOk() ) { - if( getCurrentContext().getConfig()->shouldDebugBreak() ) + if( getCurrentConfig()->shouldDebugBreak() ) m_shouldDebugBreak = true; if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) m_shouldThrow = true; @@ -113,7 +113,7 @@ namespace Catch { } bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } - bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } + bool ResultBuilder::allowThrows() const { return getCurrentConfig()->allowThrows(); } AssertionResult ResultBuilder::build() const { diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index dd5052a1..77f84cdf 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -62,9 +62,9 @@ namespace Catch { explicit RunContext( Ptr const& _config, Ptr const& reporter ) : m_runInfo( _config->name() ), m_context( getCurrentMutableContext() ), - m_activeTestCase( CATCH_NULL ), m_config( _config ), - m_reporter( reporter ) + m_reporter( reporter ), + m_activeTestCaseInfo( CATCH_NULL ) { m_context.setRunner( this ); m_context.setConfig( m_config ); @@ -84,36 +84,33 @@ namespace Catch { } Totals runTest( TestCase const& testCase ) { + m_activeTestCaseInfo = &testCase; + Totals prevTotals = m_totals; + std::string redirectedCout, redirectedCerr; - std::string redirectedCout; - std::string redirectedCerr; - - TestCaseInfo testInfo = testCase.getTestCaseInfo(); - - m_reporter->testCaseStarting( testInfo ); - - m_activeTestCase = &testCase; + m_reporter->testCaseStarting( testCase ); + ITracker* m_testCaseTracker; m_trackerContext.startRun(); do { m_trackerContext.startCycle(); - m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name ); - runCurrentTest( redirectedCout, redirectedCerr ); + m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testCase.name ); + runTest( testCase, redirectedCout, redirectedCerr ); } while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); + Totals deltaTotals = m_totals.delta( prevTotals ); m_totals.testCases += deltaTotals.testCases; - m_reporter->testCaseEnded( TestCaseStats( testInfo, + m_reporter->testCaseEnded( TestCaseStats( testCase, deltaTotals, redirectedCout, redirectedCerr, aborting() ) ); - m_activeTestCase = CATCH_NULL; - m_testCaseTracker = CATCH_NULL; + m_activeTestCaseInfo = CATCH_NULL; return deltaTotals; } @@ -126,12 +123,10 @@ namespace Catch { virtual void assertionEnded( AssertionResult const& result ) { - if( result.getResultType() == ResultWas::Ok ) { + if( result.getResultType() == ResultWas::Ok ) m_totals.assertions.passed++; - } - else if( !result.isOk() ) { + else if( !result.isOk() ) m_totals.assertions.failed++; - } if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) m_messages.clear(); @@ -206,8 +201,8 @@ namespace Catch { } virtual std::string getCurrentTestName() const { - return m_activeTestCase - ? m_activeTestCase->getTestCaseInfo().name + return m_activeTestCaseInfo + ? m_activeTestCaseInfo->name : ""; } @@ -224,19 +219,19 @@ namespace Catch { 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 ); + SectionInfo testCaseSection + ( m_activeTestCaseInfo->lineInfo, + m_activeTestCaseInfo->name, + m_activeTestCaseInfo->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, + m_reporter->testCaseEnded( TestCaseStats( *m_activeTestCaseInfo, deltaTotals, "", "", @@ -254,14 +249,13 @@ namespace Catch { private: - void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { - TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + void runTest( TestCase const& testCase, std::string& redirectedCout, std::string& redirectedCerr ) { + SectionInfo testCaseSection( testCase.lineInfo, testCase.name, testCase.description ); m_reporter->sectionStarting( testCaseSection ); Counts prevAssertions = m_totals.assertions; double duration = 0; try { - m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); + m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCase.lineInfo, "", ResultDisposition::Normal ); seedRng( *m_config ); @@ -270,10 +264,10 @@ namespace Catch { if( m_reporter->getPreferences().shouldRedirectStdOut ) { StreamRedirect coutRedir( Catch::cout(), redirectedCout ); StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); - invokeActiveTestCase(); + invokeTestCase( testCase ); } else { - invokeActiveTestCase(); + invokeTestCase( testCase ); } duration = timer.getElapsedSeconds(); } @@ -283,14 +277,15 @@ namespace Catch { catch(...) { makeUnexpectedResultBuilder().useActiveException(); } - m_testCaseTracker->close(); + m_trackerContext.currentTracker().close(); + handleUnfinishedSections(); m_messages.clear(); Counts assertions = m_totals.assertions - prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); - if( testCaseInfo.okToFail() ) { + if( testCase.okToFail() ) { std::swap( assertions.failedButOk, assertions.failed ); m_totals.assertions.failed -= assertions.failedButOk; m_totals.assertions.failedButOk += assertions.failedButOk; @@ -300,10 +295,9 @@ namespace Catch { m_reporter->sectionEnded( testCaseSectionStats ); } - void invokeActiveTestCase() { + static void invokeTestCase( TestCase const& testCase ) { FatalConditionHandler fatalConditionHandler; // Handle signals - m_activeTestCase->invoke(); - fatalConditionHandler.reset(); + testCase.invoke(); } private: @@ -328,19 +322,19 @@ namespace Catch { TestRunInfo m_runInfo; IMutableContext& m_context; - TestCase const* m_activeTestCase; - ITracker* m_testCaseTracker; - ITracker* m_currentSectionTracker; - AssertionResult m_lastResult; Ptr m_config; - Totals m_totals; Ptr m_reporter; - std::vector m_messages; + TrackerContext m_trackerContext; + Totals m_totals; + + // Transient state + TestCaseInfo const* m_activeTestCaseInfo; + AssertionResult m_lastResult; AssertionInfo m_lastAssertionInfo; std::vector m_unfinishedSections; std::vector m_activeSections; - TrackerContext m_trackerContext; + std::vector m_messages; }; IResultCapture& getResultCapture() { diff --git a/include/internal/catch_tostring.hpp b/include/internal/catch_tostring.hpp index 0a20ee2d..ad16e25e 100644 --- a/include/internal/catch_tostring.hpp +++ b/include/internal/catch_tostring.hpp @@ -55,7 +55,7 @@ namespace Detail { std::string toString( std::string const& value ) { std::string s = value; - if( getCurrentContext().getConfig()->showInvisibles() ) { + if( getCurrentConfig() && getCurrentConfig()->showInvisibles() ) { for(size_t i = 0; i < s.size(); ++i ) { std::string subs; switch( s[i] ) { diff --git a/projects/SelfTest/GeneratorTests.cpp b/projects/SelfTest/GeneratorTests.cpp index e9d4115b..c82277b5 100644 --- a/projects/SelfTest/GeneratorTests.cpp +++ b/projects/SelfTest/GeneratorTests.cpp @@ -1,2 +1,2 @@ // The old generators have been removed -// A new generator implementation is coming \ No newline at end of file +// A new generator implementation is coming diff --git a/projects/SelfTest/MiscTests.cpp b/projects/SelfTest/MiscTests.cpp index cf7f48cf..5a773251 100644 --- a/projects/SelfTest/MiscTests.cpp +++ b/projects/SelfTest/MiscTests.cpp @@ -475,6 +475,8 @@ TEST_CASE( "long long" ) { //TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) { // int i = 0; -// int x = 10/i; // This should cause the signal to fire -// CHECK( x == 0 ); +// SECTION( "s" ) { +// int x = 10/i; // This should cause the signal to fire +// CHECK( x == 0 ); +// } //}