From a0de07d45bf84ed1c77652f097fd7c55c6cf1888 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Mon, 28 Sep 2015 01:09:06 -0700 Subject: [PATCH 01/18] Some small clean-ups and refactorings - removed previous instance saves in RunContext (they were a hang-over from embedded contexts) - started cleaning up config usage --- include/catch_session.hpp | 14 ++++++++------ include/internal/catch_interfaces_reporter.h | 10 +++++----- include/internal/catch_reporter_registry.hpp | 2 +- include/internal/catch_run_context.hpp | 12 +----------- include/reporters/catch_reporter_bases.hpp | 4 ++-- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/include/catch_session.hpp b/include/catch_session.hpp index 50623ad4..1f37b5a5 100644 --- a/include/catch_session.hpp +++ b/include/catch_session.hpp @@ -43,7 +43,7 @@ namespace Catch { reporter = addReporter( reporter, createReporter( *it, config ) ); return reporter; } - Ptr addListeners( Ptr const& config, Ptr reporters ) { + Ptr addListeners( Ptr const& config, Ptr reporters ) { IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); it != itEnd; @@ -67,12 +67,14 @@ namespace Catch { Totals runTests( Ptr const& config ) { + Ptr iconfig = config.get(); + std::ofstream ofs; openStreamInto( config, ofs ); Ptr reporter = makeReporter( config ); - reporter = addListeners( config.get(), reporter ); + reporter = addListeners( iconfig, reporter ); - RunContext context( config.get(), reporter ); + RunContext context( iconfig, reporter ); Totals totals; @@ -82,17 +84,17 @@ namespace Catch { if( !testSpec.hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests - std::vector const& allTestCases = getAllTestCasesSorted( *config ); + std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); it != itEnd; ++it ) { - if( !context.aborting() && matchTest( *it, testSpec, *config ) ) + if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) totals += context.runTest( *it ); else reporter->skipTest( *it ); } - context.testGroupEnded( config->name(), totals, 1, 1 ); + context.testGroupEnded( iconfig->name(), totals, 1, 1 ); return totals; } diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h index 46720fbb..e40119df 100644 --- a/include/internal/catch_interfaces_reporter.h +++ b/include/internal/catch_interfaces_reporter.h @@ -26,18 +26,18 @@ namespace Catch { struct ReporterConfig { - explicit ReporterConfig( Ptr const& _fullConfig ) + explicit ReporterConfig( Ptr const& _fullConfig ) : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} - ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) + ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} std::ostream& stream() const { return *m_stream; } - Ptr fullConfig() const { return m_fullConfig; } + Ptr fullConfig() const { return m_fullConfig; } private: std::ostream* m_stream; - Ptr m_fullConfig; + Ptr m_fullConfig; }; struct ReporterPreferences { @@ -261,7 +261,7 @@ namespace Catch typedef std::vector > Listeners; virtual ~IReporterRegistry(); - virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; virtual FactoryMap const& getFactories() const = 0; virtual Listeners const& getListeners() const = 0; }; diff --git a/include/internal/catch_reporter_registry.hpp b/include/internal/catch_reporter_registry.hpp index b67252f3..71f23ff7 100644 --- a/include/internal/catch_reporter_registry.hpp +++ b/include/internal/catch_reporter_registry.hpp @@ -20,7 +20,7 @@ namespace Catch { virtual ~ReporterRegistry() CATCH_OVERRIDE {} - virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { FactoryMap::const_iterator it = m_factories.find( name ); if( it == m_factories.end() ) return CATCH_NULL; diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index 3ec12af6..5e315f96 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -64,10 +64,7 @@ namespace Catch { m_context( getCurrentMutableContext() ), m_activeTestCase( CATCH_NULL ), m_config( _config ), - m_reporter( reporter ), - m_prevRunner( m_context.getRunner() ), - m_prevResultCapture( m_context.getResultCapture() ), - m_prevConfig( m_context.getConfig() ) + m_reporter( reporter ) { m_context.setRunner( this ); m_context.setConfig( m_config ); @@ -77,10 +74,6 @@ namespace Catch { virtual ~RunContext() { m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); - m_context.setRunner( m_prevRunner ); - m_context.setConfig( Ptr() ); - m_context.setResultCapture( m_prevResultCapture ); - m_context.setConfig( m_prevConfig ); } void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { @@ -330,9 +323,6 @@ namespace Catch { Totals m_totals; Ptr m_reporter; std::vector m_messages; - IRunner* m_prevRunner; - IResultCapture* m_prevResultCapture; - Ptr m_prevConfig; AssertionInfo m_lastAssertionInfo; std::vector m_unfinishedSections; }; diff --git a/include/reporters/catch_reporter_bases.hpp b/include/reporters/catch_reporter_bases.hpp index 75a2bb44..e37cac00 100644 --- a/include/reporters/catch_reporter_bases.hpp +++ b/include/reporters/catch_reporter_bases.hpp @@ -65,7 +65,7 @@ namespace Catch { // It can optionally be overridden in the derived class. } - Ptr m_config; + Ptr m_config; std::ostream& stream; LazyStat currentTestRunInfo; @@ -204,7 +204,7 @@ namespace Catch { virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} - Ptr m_config; + Ptr m_config; std::ostream& stream; std::vector m_assertions; std::vector > > m_sections; From d43a47efca81129eb079b924e61d8cbcd12d8f3c Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 29 Sep 2015 19:21:08 +0100 Subject: [PATCH 02/18] Refactored stream related stuff - simpler, polymorphic hierarchy-based, approach - less bitty conditionals spread across the code - all resolved up-front so now config class is immutable (it had evolved the way it was and in need of a clean-up sweep for a long time) --- include/catch_session.hpp | 14 ----- include/internal/catch_config.hpp | 38 ++++++------- include/internal/catch_context_impl.hpp | 8 --- include/internal/catch_impl.hpp | 1 + include/internal/catch_stream.h | 56 +++++++++++++------ include/internal/catch_stream.hpp | 49 ++++++++++------ .../SelfTest/SurrogateCpps/catch_stream.cpp | 1 + 7 files changed, 91 insertions(+), 76 deletions(-) diff --git a/include/catch_session.hpp b/include/catch_session.hpp index 1f37b5a5..c63f517b 100644 --- a/include/catch_session.hpp +++ b/include/catch_session.hpp @@ -52,25 +52,11 @@ namespace Catch { return reporters; } - void openStreamInto( Ptr const& config, std::ofstream& ofs ) { - // Open output file, if specified - if( !config->getFilename().empty() ) { - ofs.open( config->getFilename().c_str() ); - if( ofs.fail() ) { - std::ostringstream oss; - oss << "Unable to open file: '" << config->getFilename() << "'"; - throw std::domain_error( oss.str() ); - } - config->setStreamBuf( ofs.rdbuf() ); - } - } Totals runTests( Ptr const& config ) { Ptr iconfig = config.get(); - std::ofstream ofs; - openStreamInto( config, ofs ); Ptr reporter = makeReporter( config ); reporter = addListeners( iconfig, reporter ); diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp index 6b2b04a3..eca10363 100644 --- a/include/internal/catch_config.hpp +++ b/include/internal/catch_config.hpp @@ -85,12 +85,11 @@ namespace Catch { public: Config() - : m_os( Catch::cout().rdbuf() ) {} Config( ConfigData const& data ) : m_data( data ), - m_os( Catch::cout().rdbuf() ) + m_stream( openStream() ) { if( !data.testsOrTags.empty() ) { TestSpecParser parser( ITagAliasRegistry::get() ); @@ -101,12 +100,6 @@ namespace Catch { } virtual ~Config() { - m_os.rdbuf( Catch::cout().rdbuf() ); - m_stream.release(); - } - - void setFilename( std::string const& filename ) { - m_data.outputFilename = filename; } std::string const& getFilename() const { @@ -122,17 +115,6 @@ namespace Catch { bool shouldDebugBreak() const { return m_data.shouldDebugBreak; } - void setStreamBuf( std::streambuf* buf ) { - m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() ); - } - - void useStream( std::string const& streamName ) { - Stream stream = createStream( streamName ); - setStreamBuf( stream.streamBuf ); - m_stream.release(); - m_stream = stream; - } - std::vector getReporterNames() const { return m_data.reporterNames; } int abortAfter() const { return m_data.abortAfter; } @@ -144,7 +126,7 @@ namespace Catch { // IConfig interface virtual bool allowThrows() const { return !m_data.noThrow; } - virtual std::ostream& stream() const { return m_os; } + virtual std::ostream& stream() const { return m_stream->stream(); } virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; } virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; } @@ -154,10 +136,22 @@ namespace Catch { virtual bool forceColour() const { return m_data.forceColour; } private: + + IStream const* openStream() { + if( m_data.outputFilename.empty() ) + return new CoutStream(); + else if( m_data.outputFilename[0] == '%' ) { + if( m_data.outputFilename == "%debug" ) + return new DebugOutStream(); + else + throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); + } + else + return new FileStream( m_data.outputFilename ); + } ConfigData m_data; - Stream m_stream; - mutable std::ostream m_os; + std::auto_ptr m_stream; TestSpec m_testSpec; }; diff --git a/include/internal/catch_context_impl.hpp b/include/internal/catch_context_impl.hpp index a3ac2ae5..030f29e2 100644 --- a/include/internal/catch_context_impl.hpp +++ b/include/internal/catch_context_impl.hpp @@ -95,14 +95,6 @@ namespace Catch { return getCurrentMutableContext(); } - Stream createStream( std::string const& streamName ) { - if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false ); - if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false ); - if( streamName == "debug" ) return Stream( new StreamBufImpl, true ); - - throw std::domain_error( "Unknown stream: " + streamName ); - } - void cleanUpContext() { delete currentContext; currentContext = CATCH_NULL; diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp index 3ff5ac00..170b4807 100644 --- a/include/internal/catch_impl.hpp +++ b/include/internal/catch_impl.hpp @@ -45,6 +45,7 @@ namespace Catch { NonCopyable::~NonCopyable() {} IShared::~IShared() {} + IStream::~IStream() CATCH_NOEXCEPT {} StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} IContext::~IContext() {} IResultCapture::~IResultCapture() {} diff --git a/include/internal/catch_stream.h b/include/internal/catch_stream.h index 402a6617..a69c841e 100644 --- a/include/internal/catch_stream.h +++ b/include/internal/catch_stream.h @@ -9,28 +9,52 @@ #ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED -#include +#include "catch_compiler_capabilities.h" +#include "catch_streambuf.h" -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wpadded" -#endif +#include +#include +#include namespace Catch { - class Stream { - public: - Stream(); - Stream( std::streambuf* _streamBuf, bool _isOwned ); - void release(); - - std::streambuf* streamBuf; - - private: - bool isOwned; - }; - std::ostream& cout(); std::ostream& cerr(); + + + struct IStream { + virtual ~IStream() CATCH_NOEXCEPT; + virtual std::ostream& stream() const = 0; + }; + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( std::string const& filename ); + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + CoutStream(); + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + + class DebugOutStream : public IStream { + std::auto_ptr m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream(); + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; } #endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED diff --git a/include/internal/catch_stream.hpp b/include/internal/catch_stream.hpp index 42933487..e6bf7b0c 100644 --- a/include/internal/catch_stream.hpp +++ b/include/internal/catch_stream.hpp @@ -10,7 +10,6 @@ #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED #include "catch_stream.h" -#include "catch_streambuf.h" #include "catch_debugger.h" #include @@ -57,29 +56,47 @@ namespace Catch { /////////////////////////////////////////////////////////////////////////// - struct OutputDebugWriter { + FileStream::FileStream( std::string const& filename ) { + m_ofs.open( filename.c_str() ); + if( m_ofs.fail() ) { + std::ostringstream oss; + oss << "Unable to open file: '" << filename << "'"; + throw std::domain_error( oss.str() ); + } + } + + std::ostream& FileStream::stream() const { + return m_ofs; + } + + struct OutputDebugWriter { + void operator()( std::string const&str ) { writeToDebugConsole( str ); } }; - - Stream::Stream() - : streamBuf( CATCH_NULL ), isOwned( false ) + + DebugOutStream::DebugOutStream() + : m_streamBuf( new StreamBufImpl() ), + m_os( m_streamBuf.get() ) {} - - Stream::Stream( std::streambuf* _streamBuf, bool _isOwned ) - : streamBuf( _streamBuf ), isOwned( _isOwned ) - {} - - void Stream::release() { - if( isOwned ) { - delete streamBuf; - streamBuf = CATCH_NULL; - isOwned = false; - } + + std::ostream& DebugOutStream::stream() const { + return m_os; } + + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream::CoutStream() + : m_os( Catch::cout().rdbuf() ) + {} + std::ostream& CoutStream::stream() const { + return m_os; + } + + #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions std::ostream& cout() { return std::cout; diff --git a/projects/SelfTest/SurrogateCpps/catch_stream.cpp b/projects/SelfTest/SurrogateCpps/catch_stream.cpp index 9911aec6..7aaffa1e 100644 --- a/projects/SelfTest/SurrogateCpps/catch_stream.cpp +++ b/projects/SelfTest/SurrogateCpps/catch_stream.cpp @@ -1,2 +1,3 @@ // This file is only here to verify (to the extent possible) the self sufficiency of the header +#include "catch_suppress_warnings.h" #include "catch_stream.h" From 1cb993970ad64a8dde8428fabc791e273d34520c Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Fri, 23 Oct 2015 18:20:33 +0100 Subject: [PATCH 03/18] First cut of new section/ part tracking --- projects/SelfTest/PartTrackerTests.cpp | 422 ++++++++++++++++++ .../CatchSelfTest.xcodeproj/project.pbxproj | 4 + 2 files changed, 426 insertions(+) create mode 100644 projects/SelfTest/PartTrackerTests.cpp diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp new file mode 100644 index 00000000..6323f376 --- /dev/null +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -0,0 +1,422 @@ +/* + * Created by Phil on 1/10/2015. + * Copyright 2015 Two Blue Cubes Ltd + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#include "internal/catch_suppress_warnings.h" +#include "internal/catch_compiler_capabilities.h" +#include "internal/catch_ptr.hpp" + +#ifdef __clang__ +//# pragma clang diagnostic ignored "-Wpadded" +//# pragma clang diagnostic ignored "-Wc++98-compat" +#endif + +#include +#include +#include + +namespace Catch +{ + struct IContainerPart; + + struct ITrackedPart : SharedImpl<> { + virtual ~ITrackedPart() {} + virtual std::string name() const = 0; + virtual bool isUnstarted() const = 0; + virtual bool isCompleteOrFailed() const = 0; + virtual bool isComplete() const = 0; + virtual bool isOpen() const = 0; + + virtual IContainerPart& parent() = 0; + + virtual void close() = 0; + virtual void fail() = 0; + }; + + struct IContainerPart : ITrackedPart { + virtual void addChild( Ptr const& child ) = 0; + virtual ITrackedPart* findChild( std::string const& name ) = 0; + virtual void openChild() = 0; + virtual void childFailed() = 0; + }; + + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + Ptr m_rootPartTracker; + IContainerPart* m_currentPart; + RunState m_runState; + + public: + + static TrackerContext& instance() { + static TrackerContext s_instance; + return s_instance; + } + + TrackerContext() + : m_currentPart( CATCH_NULL ), + m_runState( NotStarted ) + {} + + int i() { + return 42; + } + + IContainerPart& startRun(); + + void endRun() { + m_rootPartTracker.reset(); + m_currentPart = CATCH_NULL; + m_runState = NotStarted; + } + + void startCycle() { + m_currentPart = m_rootPartTracker.get(); + m_runState = Executing; + } + void completeCycle() { + m_runState = CompletedCycle; + } + + bool completedCycle() const { + return m_runState == CompletedCycle; + } + + IContainerPart& currentPart() { + return *m_currentPart; + } + void setCurrentPart( IContainerPart* part ) { + m_currentPart = part; + } + + ITrackedPart* findPart( std::string const& name ) { + return m_currentPart->findChild( name ); + } + + + private: + }; + + + class PartTracker : public IContainerPart { + enum RunState { + NotStarted, + Executing, + ExecutingChildren, + CompletedSuccessfully, + Failed, + ChildFailed + }; + class TrackerHasName { + std::string m_name; + public: + TrackerHasName( std::string const& name ) : m_name( name ) {} + bool operator ()( Ptr const& tracker ) { + return tracker->name() == m_name; + } + }; + typedef std::vector > Children; + std::string m_name; + TrackerContext& m_ctx; + IContainerPart* m_parent; + Children m_children; + RunState m_runState; + public: + PartTracker( std::string const& name, TrackerContext& ctx, IContainerPart* parent ) + : m_name( name ), + m_ctx( ctx ), + m_parent( parent ), + m_runState( NotStarted ) {} + + virtual std::string name() const CATCH_OVERRIDE { + return m_name; + } + + virtual bool isCompleteOrFailed() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + virtual bool isComplete() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully; + } + virtual bool isUnstarted() const CATCH_OVERRIDE { + return m_runState == NotStarted; + } + virtual bool isOpen() const CATCH_OVERRIDE { + return m_runState == Executing || m_runState == ExecutingChildren; + } + + + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + m_children.push_back( child ); + size_t childCount = m_children.size(); + } + + virtual ITrackedPart* findChild( std::string const& name ) CATCH_OVERRIDE { + Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); + return( it != m_children.end() ) + ? it->get() + : CATCH_NULL; + } + virtual IContainerPart& parent() CATCH_OVERRIDE { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + virtual void openChild() CATCH_OVERRIDE { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + virtual void childFailed() CATCH_OVERRIDE { + assert( m_runState == ExecutingChildren ); + m_runState = ChildFailed; + if( m_parent ) + m_parent->childFailed(); + } + void open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + virtual void close() CATCH_OVERRIDE { + switch( m_runState ) { + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( !hasUnstartedChildren() ) + m_runState = CompletedSuccessfully; + break; + case ChildFailed: + m_runState = ExecutingChildren; + break; + default: + throw std::logic_error( "Unexpected state" ); + } + moveToParent(); + m_ctx.completeCycle(); + } + virtual void fail() CATCH_OVERRIDE { + m_runState = Failed; + if( m_parent ) + m_parent->childFailed(); + moveToParent(); + m_ctx.completeCycle(); + } + private: + void moveToParent() { + m_ctx.setCurrentPart( m_parent ); + } + void moveToThis() { + m_ctx.setCurrentPart( this ); + } + + bool hasUnstartedChildren() const { + return !m_children.empty() && m_children.back()->isUnstarted(); + } + }; + + IContainerPart& TrackerContext::startRun() { + m_rootPartTracker = new PartTracker( "{root}", *this, CATCH_NULL ); + m_currentPart = CATCH_NULL; + m_runState = Executing; + return *m_rootPartTracker; + } + + class LocalContext { + + public: + TrackerContext& operator()() const { + return TrackerContext::instance(); + } + }; + + class SectionPart : public PartTracker { + public: + SectionPart( std::string const& name, TrackerContext& ctx, IContainerPart* parent ) + : PartTracker( name, ctx, parent ) + {} + + static SectionPart& acquire( TrackerContext& ctx, std::string const& name ) { + SectionPart* section = CATCH_NULL; + + IContainerPart& currentPart = ctx.currentPart(); + if( ITrackedPart* part = currentPart.findChild( name ) ) { + section = dynamic_cast( part ); + assert( section ); + } + else { + section = new SectionPart( name, ctx, ¤tPart ); + currentPart.addChild( section ); + } + if( !ctx.completedCycle() && !section->isCompleteOrFailed() ) { + section->open(); + } + return *section; + } + }; + +} // namespace Catch + +inline Catch::TrackerContext& C_A_T_C_H_Context() { + return Catch::TrackerContext::instance(); +} + +// ------------------- + +#include "catch.hpp" + +using namespace Catch; + +inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) { + + REQUIRE( C_A_T_C_H_Context().i() == 42 ); +} + +TEST_CASE( "PartTracker" ) { + + TrackerContext ctx; + ctx.startRun(); + ctx.startCycle(); + + SectionPart& testCase = SectionPart::acquire( ctx, "Testcase" ); + REQUIRE( testCase.isComplete() == false ); + + SectionPart& s1 = SectionPart::acquire( ctx, "S1" ); + REQUIRE( s1.isComplete() == false ); + + SECTION( "successfully close one section" ) { + s1.close(); + REQUIRE( s1.isComplete() == true ); + REQUIRE( testCase.isCompleteOrFailed() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() == true ); + + REQUIRE( ctx.completedCycle() == true ); + } + + SECTION( "fail one section" ) { + s1.fail(); + REQUIRE( s1.isComplete() == false ); + REQUIRE( s1.isCompleteOrFailed() == true ); + REQUIRE( testCase.isComplete() == false ); + REQUIRE( testCase.isCompleteOrFailed() == false ); + + testCase.close(); + REQUIRE( ctx.completedCycle() == true ); + REQUIRE( testCase.isComplete() == false ); + + SECTION( "re-enter after failed section" ) { + ctx.startCycle(); + SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isComplete() == false ); + + SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); + REQUIRE( s1b.isComplete() == false ); + + testCase2.close(); + REQUIRE( ctx.completedCycle() == true ); + REQUIRE( testCase.isComplete() == true ); + REQUIRE( testCase.isCompleteOrFailed() == true ); + } + SECTION( "re-enter after failed section and find next section" ) { + ctx.startCycle(); + SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isComplete() == false ); + + SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); + REQUIRE( s1b.isComplete() == false ); + + SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); + REQUIRE( s2.isOpen() ); + s2.close(); + REQUIRE( ctx.completedCycle() == true ); + + testCase2.close(); + REQUIRE( testCase.isComplete() == true ); + REQUIRE( testCase.isCompleteOrFailed() == true ); + } + } + + SECTION( "successfully close one section, then find another" ) { + s1.close(); + REQUIRE( ctx.completedCycle() == true ); + + SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); + REQUIRE( s2.isComplete() == false ); + REQUIRE( s2.isOpen() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() == false ); + + SECTION( "Re-enter - skip S1 and enter S2" ) { + ctx.startCycle(); + SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isComplete() == false ); + + SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); + REQUIRE( s1b.isComplete() == true ); + + SectionPart& s2b = SectionPart::acquire( ctx, "S2" ); + REQUIRE( s2b.isComplete() == false ); + REQUIRE( s2b.isOpen() ); + + REQUIRE( ctx.completedCycle() == false ); + + SECTION ("Successfully close S2") { + s2b.close(); + REQUIRE( ctx.completedCycle() == true ); + + REQUIRE( s2b.isComplete() == true ); + REQUIRE( testCase2.isCompleteOrFailed() == false ); + + testCase2.close(); + REQUIRE( testCase2.isComplete() == true ); + } + SECTION ("fail S2") { + s2b.fail(); + REQUIRE( ctx.completedCycle() == true ); + + REQUIRE( s2b.isComplete() == false ); + REQUIRE( s2b.isCompleteOrFailed() == true ); + REQUIRE( testCase2.isCompleteOrFailed() == false ); + + testCase2.close(); + REQUIRE( testCase2.isComplete() == false ); + } + } + } + + SECTION( "open a nested section" ) { + SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); + REQUIRE( s2.isOpen() == true ); + + s2.close(); + REQUIRE( s2.isComplete() == true ); + REQUIRE( s1.isComplete() == false ); + + s1.close(); + REQUIRE( s1.isComplete() == true ); + REQUIRE( testCase.isComplete() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() == true ); + + } + +} diff --git a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj index 81f826b6..5ec14365 100644 --- a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj +++ b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */; settings = {ASSET_TAGS = (); }; }; 263F7A4719B6FCBF009474C2 /* EnumToString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */; }; 263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */; }; 263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */; }; @@ -62,6 +63,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PartTrackerTests.cpp; path = ../../../SelfTest/PartTrackerTests.cpp; sourceTree = ""; }; 261488FA184C81130041FBEB /* catch_test_spec.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec.hpp; sourceTree = ""; }; 261488FC184D1DC10041FBEB /* catch_stream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_stream.h; sourceTree = ""; }; 261488FD184D21290041FBEB /* catch_section_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section_info.h; sourceTree = ""; }; @@ -212,6 +214,7 @@ 266E9AD317290E710061DAB2 /* Introspective Tests */ = { isa = PBXGroup; children = ( + 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */, 26948284179A9AB900ED166E /* SectionTrackerTests.cpp */, 26E1B7D119213BC900812682 /* CmdLineTests.cpp */, 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */, @@ -548,6 +551,7 @@ 4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */, 4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */, 263F7A4D19B6FE1E009474C2 /* ToStringWhich.cpp in Sources */, + 26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */, 263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */, 4AEE032016142F910071E950 /* catch_common.cpp in Sources */, 263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */, From 2c6411e70a9325b8fdaf5051ad20cfe9b8c5a8be Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Fri, 23 Oct 2015 18:34:16 +0100 Subject: [PATCH 04/18] Tweaks --- projects/SelfTest/PartTrackerTests.cpp | 147 ++++++++++++------------- 1 file changed, 71 insertions(+), 76 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 6323f376..19a9c806 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -20,29 +20,29 @@ namespace Catch { - struct IContainerPart; - struct ITrackedPart : SharedImpl<> { virtual ~ITrackedPart() {} + + // queries virtual std::string name() const = 0; - virtual bool isUnstarted() const = 0; - virtual bool isCompleteOrFailed() const = 0; - virtual bool isComplete() const = 0; + virtual bool hasStarted() const = 0; // true even if ended + virtual bool hasEnded() const = 0; + virtual bool didCompleteSuccessfully() const = 0; virtual bool isOpen() const = 0; - virtual IContainerPart& parent() = 0; + virtual ITrackedPart& parent() = 0; + // actions virtual void close() = 0; virtual void fail() = 0; - }; - - struct IContainerPart : ITrackedPart { + virtual void addChild( Ptr const& child ) = 0; virtual ITrackedPart* findChild( std::string const& name ) = 0; virtual void openChild() = 0; virtual void childFailed() = 0; + }; - + class TrackerContext { @@ -52,8 +52,8 @@ namespace Catch CompletedCycle }; - Ptr m_rootPartTracker; - IContainerPart* m_currentPart; + Ptr m_rootPart; + ITrackedPart* m_currentPart; RunState m_runState; public: @@ -67,21 +67,18 @@ namespace Catch : m_currentPart( CATCH_NULL ), m_runState( NotStarted ) {} - - int i() { - return 42; - } - IContainerPart& startRun(); + + ITrackedPart& startRun(); void endRun() { - m_rootPartTracker.reset(); + m_rootPart.reset(); m_currentPart = CATCH_NULL; m_runState = NotStarted; } void startCycle() { - m_currentPart = m_rootPartTracker.get(); + m_currentPart = m_rootPart.get(); m_runState = Executing; } void completeCycle() { @@ -92,10 +89,10 @@ namespace Catch return m_runState == CompletedCycle; } - IContainerPart& currentPart() { + ITrackedPart& currentPart() { return *m_currentPart; } - void setCurrentPart( IContainerPart* part ) { + void setCurrentPart( ITrackedPart* part ) { m_currentPart = part; } @@ -103,12 +100,10 @@ namespace Catch return m_currentPart->findChild( name ); } - - private: }; - class PartTracker : public IContainerPart { + class SectionTracker : public ITrackedPart { enum RunState { NotStarted, Executing, @@ -128,11 +123,11 @@ namespace Catch typedef std::vector > Children; std::string m_name; TrackerContext& m_ctx; - IContainerPart* m_parent; + ITrackedPart* m_parent; Children m_children; RunState m_runState; public: - PartTracker( std::string const& name, TrackerContext& ctx, IContainerPart* parent ) + SectionTracker( std::string const& name, TrackerContext& ctx, ITrackedPart* parent ) : m_name( name ), m_ctx( ctx ), m_parent( parent ), @@ -142,14 +137,14 @@ namespace Catch return m_name; } - virtual bool isCompleteOrFailed() const CATCH_OVERRIDE { + virtual bool hasEnded() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully || m_runState == Failed; } - virtual bool isComplete() const CATCH_OVERRIDE { + virtual bool didCompleteSuccessfully() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully; } - virtual bool isUnstarted() const CATCH_OVERRIDE { - return m_runState == NotStarted; + virtual bool hasStarted() const CATCH_OVERRIDE { + return m_runState != NotStarted; } virtual bool isOpen() const CATCH_OVERRIDE { return m_runState == Executing || m_runState == ExecutingChildren; @@ -167,7 +162,7 @@ namespace Catch ? it->get() : CATCH_NULL; } - virtual IContainerPart& parent() CATCH_OVERRIDE { + virtual ITrackedPart& parent() CATCH_OVERRIDE { assert( m_parent ); // Should always be non-null except for root return *m_parent; } @@ -226,15 +221,15 @@ namespace Catch } bool hasUnstartedChildren() const { - return !m_children.empty() && m_children.back()->isUnstarted(); + return !m_children.empty() && !m_children.back()->hasStarted(); } }; - IContainerPart& TrackerContext::startRun() { - m_rootPartTracker = new PartTracker( "{root}", *this, CATCH_NULL ); + ITrackedPart& TrackerContext::startRun() { + m_rootPart = new SectionTracker( "{root}", *this, CATCH_NULL ); m_currentPart = CATCH_NULL; m_runState = Executing; - return *m_rootPartTracker; + return *m_rootPart; } class LocalContext { @@ -245,16 +240,16 @@ namespace Catch } }; - class SectionPart : public PartTracker { + class SectionPart : public SectionTracker { public: - SectionPart( std::string const& name, TrackerContext& ctx, IContainerPart* parent ) - : PartTracker( name, ctx, parent ) + SectionPart( std::string const& name, TrackerContext& ctx, ITrackedPart* parent ) + : SectionTracker( name, ctx, parent ) {} static SectionPart& acquire( TrackerContext& ctx, std::string const& name ) { SectionPart* section = CATCH_NULL; - IContainerPart& currentPart = ctx.currentPart(); + ITrackedPart& currentPart = ctx.currentPart(); if( ITrackedPart* part = currentPart.findChild( name ) ) { section = dynamic_cast( part ); assert( section ); @@ -263,7 +258,7 @@ namespace Catch section = new SectionPart( name, ctx, ¤tPart ); currentPart.addChild( section ); } - if( !ctx.completedCycle() && !section->isCompleteOrFailed() ) { + if( !ctx.completedCycle() && !section->hasEnded() ) { section->open(); } return *section; @@ -284,7 +279,7 @@ using namespace Catch; inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) { - REQUIRE( C_A_T_C_H_Context().i() == 42 ); +// REQUIRE( C_A_T_C_H_Context().i() == 42 ); } TEST_CASE( "PartTracker" ) { @@ -294,53 +289,53 @@ TEST_CASE( "PartTracker" ) { ctx.startCycle(); SectionPart& testCase = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase.isComplete() == false ); + REQUIRE( testCase.didCompleteSuccessfully() == false ); SectionPart& s1 = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1.isComplete() == false ); + REQUIRE( s1.didCompleteSuccessfully() == false ); SECTION( "successfully close one section" ) { s1.close(); - REQUIRE( s1.isComplete() == true ); - REQUIRE( testCase.isCompleteOrFailed() == false ); + REQUIRE( s1.didCompleteSuccessfully() == true ); + REQUIRE( testCase.hasEnded() == false ); testCase.close(); - REQUIRE( testCase.isComplete() == true ); + REQUIRE( testCase.didCompleteSuccessfully() == true ); REQUIRE( ctx.completedCycle() == true ); } SECTION( "fail one section" ) { s1.fail(); - REQUIRE( s1.isComplete() == false ); - REQUIRE( s1.isCompleteOrFailed() == true ); - REQUIRE( testCase.isComplete() == false ); - REQUIRE( testCase.isCompleteOrFailed() == false ); + REQUIRE( s1.didCompleteSuccessfully() == false ); + REQUIRE( s1.hasEnded() == true ); + REQUIRE( testCase.didCompleteSuccessfully() == false ); + REQUIRE( testCase.hasEnded() == false ); testCase.close(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( testCase.isComplete() == false ); + REQUIRE( testCase.didCompleteSuccessfully() == false ); SECTION( "re-enter after failed section" ) { ctx.startCycle(); SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isComplete() == false ); + REQUIRE( testCase2.didCompleteSuccessfully() == false ); SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1b.isComplete() == false ); + REQUIRE( s1b.didCompleteSuccessfully() == false ); testCase2.close(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( testCase.isComplete() == true ); - REQUIRE( testCase.isCompleteOrFailed() == true ); + REQUIRE( testCase.didCompleteSuccessfully() == true ); + REQUIRE( testCase.hasEnded() == true ); } SECTION( "re-enter after failed section and find next section" ) { ctx.startCycle(); SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isComplete() == false ); + REQUIRE( testCase2.didCompleteSuccessfully() == false ); SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1b.isComplete() == false ); + REQUIRE( s1b.didCompleteSuccessfully() == false ); SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); @@ -348,8 +343,8 @@ TEST_CASE( "PartTracker" ) { REQUIRE( ctx.completedCycle() == true ); testCase2.close(); - REQUIRE( testCase.isComplete() == true ); - REQUIRE( testCase.isCompleteOrFailed() == true ); + REQUIRE( testCase.didCompleteSuccessfully() == true ); + REQUIRE( testCase.hasEnded() == true ); } } @@ -358,22 +353,22 @@ TEST_CASE( "PartTracker" ) { REQUIRE( ctx.completedCycle() == true ); SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); - REQUIRE( s2.isComplete() == false ); + REQUIRE( s2.didCompleteSuccessfully() == false ); REQUIRE( s2.isOpen() == false ); testCase.close(); - REQUIRE( testCase.isComplete() == false ); + REQUIRE( testCase.didCompleteSuccessfully() == false ); SECTION( "Re-enter - skip S1 and enter S2" ) { ctx.startCycle(); SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isComplete() == false ); + REQUIRE( testCase2.didCompleteSuccessfully() == false ); SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1b.isComplete() == true ); + REQUIRE( s1b.didCompleteSuccessfully() == true ); SectionPart& s2b = SectionPart::acquire( ctx, "S2" ); - REQUIRE( s2b.isComplete() == false ); + REQUIRE( s2b.didCompleteSuccessfully() == false ); REQUIRE( s2b.isOpen() ); REQUIRE( ctx.completedCycle() == false ); @@ -382,22 +377,22 @@ TEST_CASE( "PartTracker" ) { s2b.close(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( s2b.isComplete() == true ); - REQUIRE( testCase2.isCompleteOrFailed() == false ); + REQUIRE( s2b.didCompleteSuccessfully() == true ); + REQUIRE( testCase2.hasEnded() == false ); testCase2.close(); - REQUIRE( testCase2.isComplete() == true ); + REQUIRE( testCase2.didCompleteSuccessfully() == true ); } SECTION ("fail S2") { s2b.fail(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( s2b.isComplete() == false ); - REQUIRE( s2b.isCompleteOrFailed() == true ); - REQUIRE( testCase2.isCompleteOrFailed() == false ); + REQUIRE( s2b.didCompleteSuccessfully() == false ); + REQUIRE( s2b.hasEnded() == true ); + REQUIRE( testCase2.hasEnded() == false ); testCase2.close(); - REQUIRE( testCase2.isComplete() == false ); + REQUIRE( testCase2.didCompleteSuccessfully() == false ); } } } @@ -407,15 +402,15 @@ TEST_CASE( "PartTracker" ) { REQUIRE( s2.isOpen() == true ); s2.close(); - REQUIRE( s2.isComplete() == true ); - REQUIRE( s1.isComplete() == false ); + REQUIRE( s2.didCompleteSuccessfully() == true ); + REQUIRE( s1.didCompleteSuccessfully() == false ); s1.close(); - REQUIRE( s1.isComplete() == true ); - REQUIRE( testCase.isComplete() == false ); + REQUIRE( s1.didCompleteSuccessfully() == true ); + REQUIRE( testCase.didCompleteSuccessfully() == false ); testCase.close(); - REQUIRE( testCase.isComplete() == true ); + REQUIRE( testCase.didCompleteSuccessfully() == true ); } From 9a6a0865f2a0c60a831438c0516f3eb94043ca02 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Fri, 23 Oct 2015 18:44:48 +0100 Subject: [PATCH 05/18] More name changes --- projects/SelfTest/PartTrackerTests.cpp | 171 +++++++++++++------------ 1 file changed, 87 insertions(+), 84 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 19a9c806..f699e78f 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -20,24 +20,24 @@ namespace Catch { - struct ITrackedPart : SharedImpl<> { - virtual ~ITrackedPart() {} + struct IPartTracker : SharedImpl<> { + virtual ~IPartTracker() {} // queries virtual std::string name() const = 0; virtual bool hasStarted() const = 0; // true even if ended virtual bool hasEnded() const = 0; - virtual bool didCompleteSuccessfully() const = 0; + virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; - virtual ITrackedPart& parent() = 0; + virtual IPartTracker& parent() = 0; // actions virtual void close() = 0; virtual void fail() = 0; - virtual void addChild( Ptr const& child ) = 0; - virtual ITrackedPart* findChild( std::string const& name ) = 0; + virtual void addChild( Ptr const& child ) = 0; + virtual IPartTracker* findChild( std::string const& name ) = 0; virtual void openChild() = 0; virtual void childFailed() = 0; @@ -52,8 +52,8 @@ namespace Catch CompletedCycle }; - Ptr m_rootPart; - ITrackedPart* m_currentPart; + Ptr m_rootPart; + IPartTracker* m_currentPart; RunState m_runState; public: @@ -69,7 +69,7 @@ namespace Catch {} - ITrackedPart& startRun(); + IPartTracker& startRun(); void endRun() { m_rootPart.reset(); @@ -89,21 +89,20 @@ namespace Catch return m_runState == CompletedCycle; } - ITrackedPart& currentPart() { + IPartTracker& currentPart() { return *m_currentPart; } - void setCurrentPart( ITrackedPart* part ) { + void setCurrentPart( IPartTracker* part ) { m_currentPart = part; } - ITrackedPart* findPart( std::string const& name ) { + IPartTracker* findPart( std::string const& name ) { return m_currentPart->findChild( name ); } }; - - class SectionTracker : public ITrackedPart { + class PartTrackerBase : public IPartTracker { enum RunState { NotStarted, Executing, @@ -116,18 +115,18 @@ namespace Catch std::string m_name; public: TrackerHasName( std::string const& name ) : m_name( name ) {} - bool operator ()( Ptr const& tracker ) { + bool operator ()( Ptr const& tracker ) { return tracker->name() == m_name; } }; - typedef std::vector > Children; + typedef std::vector > Children; std::string m_name; TrackerContext& m_ctx; - ITrackedPart* m_parent; + IPartTracker* m_parent; Children m_children; RunState m_runState; public: - SectionTracker( std::string const& name, TrackerContext& ctx, ITrackedPart* parent ) + PartTrackerBase( std::string const& name, TrackerContext& ctx, IPartTracker* parent ) : m_name( name ), m_ctx( ctx ), m_parent( parent ), @@ -140,7 +139,7 @@ namespace Catch virtual bool hasEnded() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully || m_runState == Failed; } - virtual bool didCompleteSuccessfully() const CATCH_OVERRIDE { + virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully; } virtual bool hasStarted() const CATCH_OVERRIDE { @@ -151,18 +150,18 @@ namespace Catch } - virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { m_children.push_back( child ); size_t childCount = m_children.size(); } - virtual ITrackedPart* findChild( std::string const& name ) CATCH_OVERRIDE { + virtual IPartTracker* findChild( std::string const& name ) CATCH_OVERRIDE { Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); return( it != m_children.end() ) ? it->get() : CATCH_NULL; } - virtual ITrackedPart& parent() CATCH_OVERRIDE { + virtual IPartTracker& parent() CATCH_OVERRIDE { assert( m_parent ); // Should always be non-null except for root return *m_parent; } @@ -225,37 +224,24 @@ namespace Catch } }; - ITrackedPart& TrackerContext::startRun() { - m_rootPart = new SectionTracker( "{root}", *this, CATCH_NULL ); - m_currentPart = CATCH_NULL; - m_runState = Executing; - return *m_rootPart; - } - class LocalContext { - - public: - TrackerContext& operator()() const { - return TrackerContext::instance(); - } - }; - class SectionPart : public SectionTracker { + class SectionTracker : public PartTrackerBase { public: - SectionPart( std::string const& name, TrackerContext& ctx, ITrackedPart* parent ) - : SectionTracker( name, ctx, parent ) + SectionTracker( std::string const& name, TrackerContext& ctx, IPartTracker* parent ) + : PartTrackerBase( name, ctx, parent ) {} - static SectionPart& acquire( TrackerContext& ctx, std::string const& name ) { - SectionPart* section = CATCH_NULL; + static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) { + SectionTracker* section = CATCH_NULL; - ITrackedPart& currentPart = ctx.currentPart(); - if( ITrackedPart* part = currentPart.findChild( name ) ) { - section = dynamic_cast( part ); + IPartTracker& currentPart = ctx.currentPart(); + if( IPartTracker* part = currentPart.findChild( name ) ) { + section = dynamic_cast( part ); assert( section ); } else { - section = new SectionPart( name, ctx, ¤tPart ); + section = new SectionTracker( name, ctx, ¤tPart ); currentPart.addChild( section ); } if( !ctx.completedCycle() && !section->hasEnded() ) { @@ -265,6 +251,21 @@ namespace Catch } }; + IPartTracker& TrackerContext::startRun() { + m_rootPart = new SectionTracker( "{root}", *this, CATCH_NULL ); + m_currentPart = CATCH_NULL; + m_runState = Executing; + return *m_rootPart; + } + + class LocalContext { + + public: + TrackerContext& operator()() const { + return TrackerContext::instance(); + } + }; + } // namespace Catch inline Catch::TrackerContext& C_A_T_C_H_Context() { @@ -288,62 +289,63 @@ TEST_CASE( "PartTracker" ) { ctx.startRun(); ctx.startCycle(); - SectionPart& testCase = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase.didCompleteSuccessfully() == false ); + IPartTracker& testCase = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); - SectionPart& s1 = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1.didCompleteSuccessfully() == false ); + IPartTracker& s1 = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1.isOpen() == true ); + REQUIRE( s1.isSuccessfullyCompleted() == false ); SECTION( "successfully close one section" ) { s1.close(); - REQUIRE( s1.didCompleteSuccessfully() == true ); + REQUIRE( s1.isSuccessfullyCompleted() == true ); REQUIRE( testCase.hasEnded() == false ); testCase.close(); - REQUIRE( testCase.didCompleteSuccessfully() == true ); + REQUIRE( testCase.isSuccessfullyCompleted() == true ); REQUIRE( ctx.completedCycle() == true ); } SECTION( "fail one section" ) { s1.fail(); - REQUIRE( s1.didCompleteSuccessfully() == false ); + REQUIRE( s1.isSuccessfullyCompleted() == false ); REQUIRE( s1.hasEnded() == true ); - REQUIRE( testCase.didCompleteSuccessfully() == false ); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); REQUIRE( testCase.hasEnded() == false ); testCase.close(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( testCase.didCompleteSuccessfully() == false ); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); SECTION( "re-enter after failed section" ) { ctx.startCycle(); - SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.didCompleteSuccessfully() == false ); + IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isSuccessfullyCompleted() == false ); - SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1b.didCompleteSuccessfully() == false ); + IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1b.isSuccessfullyCompleted() == false ); testCase2.close(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( testCase.didCompleteSuccessfully() == true ); + REQUIRE( testCase.isSuccessfullyCompleted() == true ); REQUIRE( testCase.hasEnded() == true ); } SECTION( "re-enter after failed section and find next section" ) { ctx.startCycle(); - SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.didCompleteSuccessfully() == false ); + IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isSuccessfullyCompleted() == false ); - SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1b.didCompleteSuccessfully() == false ); + IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1b.isSuccessfullyCompleted() == false ); - SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); + IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); s2.close(); REQUIRE( ctx.completedCycle() == true ); testCase2.close(); - REQUIRE( testCase.didCompleteSuccessfully() == true ); + REQUIRE( testCase.isSuccessfullyCompleted() == true ); REQUIRE( testCase.hasEnded() == true ); } } @@ -352,24 +354,25 @@ TEST_CASE( "PartTracker" ) { s1.close(); REQUIRE( ctx.completedCycle() == true ); - SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); - REQUIRE( s2.didCompleteSuccessfully() == false ); + IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() == false ); + REQUIRE( s2.isSuccessfullyCompleted() == false ); testCase.close(); - REQUIRE( testCase.didCompleteSuccessfully() == false ); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); - SECTION( "Re-enter - skip S1 and enter S2" ) { + SECTION( "Re-enter - skips S1 and enters S2" ) { ctx.startCycle(); - SectionPart& testCase2 = SectionPart::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.didCompleteSuccessfully() == false ); + IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + REQUIRE( testCase2.isSuccessfullyCompleted() == false ); - SectionPart& s1b = SectionPart::acquire( ctx, "S1" ); - REQUIRE( s1b.didCompleteSuccessfully() == true ); + IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1b.isOpen() == false ); - SectionPart& s2b = SectionPart::acquire( ctx, "S2" ); - REQUIRE( s2b.didCompleteSuccessfully() == false ); + IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2b.isOpen() ); + REQUIRE( s2b.isSuccessfullyCompleted() == false ); REQUIRE( ctx.completedCycle() == false ); @@ -377,40 +380,40 @@ TEST_CASE( "PartTracker" ) { s2b.close(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( s2b.didCompleteSuccessfully() == true ); + REQUIRE( s2b.isSuccessfullyCompleted() == true ); REQUIRE( testCase2.hasEnded() == false ); testCase2.close(); - REQUIRE( testCase2.didCompleteSuccessfully() == true ); + REQUIRE( testCase2.isSuccessfullyCompleted() == true ); } SECTION ("fail S2") { s2b.fail(); REQUIRE( ctx.completedCycle() == true ); - REQUIRE( s2b.didCompleteSuccessfully() == false ); + REQUIRE( s2b.isSuccessfullyCompleted() == false ); REQUIRE( s2b.hasEnded() == true ); REQUIRE( testCase2.hasEnded() == false ); testCase2.close(); - REQUIRE( testCase2.didCompleteSuccessfully() == false ); + REQUIRE( testCase2.isSuccessfullyCompleted() == false ); } } } SECTION( "open a nested section" ) { - SectionPart& s2 = SectionPart::acquire( ctx, "S2" ); + IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() == true ); s2.close(); - REQUIRE( s2.didCompleteSuccessfully() == true ); - REQUIRE( s1.didCompleteSuccessfully() == false ); + REQUIRE( s2.isSuccessfullyCompleted() == true ); + REQUIRE( s1.isSuccessfullyCompleted() == false ); s1.close(); - REQUIRE( s1.didCompleteSuccessfully() == true ); - REQUIRE( testCase.didCompleteSuccessfully() == false ); + REQUIRE( s1.isSuccessfullyCompleted() == true ); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); testCase.close(); - REQUIRE( testCase.didCompleteSuccessfully() == true ); + REQUIRE( testCase.isSuccessfullyCompleted() == true ); } From 293e54dcbee9189f32e97dd218e10f1025a0e5af Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Thu, 29 Oct 2015 08:02:40 +0000 Subject: [PATCH 06/18] Added IndexTracker and got it working with a single generator - made some simplifications to state machine --- projects/SelfTest/PartTrackerTests.cpp | 187 +++++++++++++++++++++---- 1 file changed, 160 insertions(+), 27 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index f699e78f..6f9abfca 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -23,8 +23,10 @@ namespace Catch struct IPartTracker : SharedImpl<> { virtual ~IPartTracker() {} - // queries + // static queries virtual std::string name() const = 0; + + // dynamic queries virtual bool hasStarted() const = 0; // true even if ended virtual bool hasEnded() const = 0; virtual bool isSuccessfullyCompleted() const = 0; @@ -35,12 +37,11 @@ namespace Catch // actions virtual void close() = 0; virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() =0; virtual void addChild( Ptr const& child ) = 0; virtual IPartTracker* findChild( std::string const& name ) = 0; virtual void openChild() = 0; - virtual void childFailed() = 0; - }; @@ -103,13 +104,14 @@ namespace Catch }; class PartTrackerBase : public IPartTracker { + protected: enum RunState { NotStarted, Executing, ExecutingChildren, + NeedsAnotherRun, CompletedSuccessfully, - Failed, - ChildFailed + Failed }; class TrackerHasName { std::string m_name; @@ -146,7 +148,7 @@ namespace Catch return m_runState != NotStarted; } virtual bool isOpen() const CATCH_OVERRIDE { - return m_runState == Executing || m_runState == ExecutingChildren; + return hasStarted() && !hasEnded(); } @@ -158,8 +160,8 @@ namespace Catch virtual IPartTracker* findChild( std::string const& name ) CATCH_OVERRIDE { Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); return( it != m_children.end() ) - ? it->get() - : CATCH_NULL; + ? it->get() + : CATCH_NULL; } virtual IPartTracker& parent() CATCH_OVERRIDE { assert( m_parent ); // Should always be non-null except for root @@ -173,12 +175,6 @@ namespace Catch m_parent->openChild(); } } - virtual void childFailed() CATCH_OVERRIDE { - assert( m_runState == ExecutingChildren ); - m_runState = ChildFailed; - if( m_parent ) - m_parent->childFailed(); - } void open() { m_runState = Executing; moveToThis(); @@ -187,16 +183,25 @@ namespace Catch } virtual void close() CATCH_OVERRIDE { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentPart() != this ) + m_ctx.currentPart().close(); + switch( m_runState ) { + case CompletedSuccessfully: + case Failed: + return; + case Executing: m_runState = CompletedSuccessfully; break; case ExecutingChildren: - if( !hasUnstartedChildren() ) + if( m_children.empty() || m_children.back()->hasEnded() ) m_runState = CompletedSuccessfully; break; - case ChildFailed: - m_runState = ExecutingChildren; + case NeedsAnotherRun: + m_runState = Executing; break; default: throw std::logic_error( "Unexpected state" ); @@ -207,21 +212,21 @@ namespace Catch virtual void fail() CATCH_OVERRIDE { m_runState = Failed; if( m_parent ) - m_parent->childFailed(); + m_parent->markAsNeedingAnotherRun(); moveToParent(); m_ctx.completeCycle(); } + virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { + m_runState = NeedsAnotherRun; + } private: void moveToParent() { + assert( m_parent ); m_ctx.setCurrentPart( m_parent ); } void moveToThis() { m_ctx.setCurrentPart( this ); } - - bool hasUnstartedChildren() const { - return !m_children.empty() && !m_children.back()->hasStarted(); - } }; @@ -245,12 +250,60 @@ namespace Catch currentPart.addChild( section ); } if( !ctx.completedCycle() && !section->hasEnded() ) { + section->open(); } return *section; } }; + class IndexTracker : public PartTrackerBase { + int m_size; + int m_index; + public: + IndexTracker( std::string const& name, TrackerContext& ctx, IPartTracker* parent, int size ) + : PartTrackerBase( name, ctx, parent ), + m_size( size ), + m_index( -1 ) + {} + + static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) { + IndexTracker* tracker = CATCH_NULL; + + IPartTracker& currentPart = ctx.currentPart(); + if( IPartTracker* part = currentPart.findChild( name ) ) { + tracker = dynamic_cast( part ); + assert( tracker ); + } + else { + tracker = new IndexTracker( name, ctx, ¤tPart, size ); + currentPart.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->hasEnded() ) { + if( tracker->m_runState != ExecutingChildren ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int index() const { return m_index; } + + void moveNext() { + m_index++; + m_children.clear(); + } + + virtual void close() CATCH_OVERRIDE { + PartTrackerBase::close(); + if( m_runState == CompletedSuccessfully ) + if( m_index < m_size-1 ) + m_runState = Executing; + } + }; + IPartTracker& TrackerContext::startRun() { m_rootPart = new SectionTracker( "{root}", *this, CATCH_NULL ); m_currentPart = CATCH_NULL; @@ -302,9 +355,8 @@ TEST_CASE( "PartTracker" ) { REQUIRE( testCase.hasEnded() == false ); testCase.close(); - REQUIRE( testCase.isSuccessfullyCompleted() == true ); - REQUIRE( ctx.completedCycle() == true ); + REQUIRE( testCase.isSuccessfullyCompleted() == true ); } SECTION( "fail one section" ) { @@ -324,8 +376,8 @@ TEST_CASE( "PartTracker" ) { REQUIRE( testCase2.isSuccessfullyCompleted() == false ); IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); - REQUIRE( s1b.isSuccessfullyCompleted() == false ); - + REQUIRE( s1b.isOpen() == false ); + testCase2.close(); REQUIRE( ctx.completedCycle() == true ); REQUIRE( testCase.isSuccessfullyCompleted() == true ); @@ -414,7 +466,88 @@ TEST_CASE( "PartTracker" ) { testCase.close(); REQUIRE( testCase.isSuccessfullyCompleted() == true ); - } + SECTION( "start a generator" ) { + IndexTracker& g1 = IndexTracker::acquire( ctx, "G1", 2 ); + REQUIRE( g1.isOpen() == true ); + REQUIRE( g1.index() == 0 ); + + REQUIRE( g1.isSuccessfullyCompleted() == false ); + REQUIRE( s1.isSuccessfullyCompleted() == false ); + + SECTION( "close outer section" ) + { + s1.close(); + REQUIRE( s1.isSuccessfullyCompleted() == false ); + testCase.close(); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); + + SECTION( "Re-enter for second generation" ) { + ctx.startCycle(); + IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isOpen() == true ); + + IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1b.isOpen() == true ); + + + IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 ); + REQUIRE( g1b.isOpen() == true ); + REQUIRE( g1b.index() == 1 ); + + REQUIRE( s1.isSuccessfullyCompleted() == false ); + + s1b.close(); + REQUIRE( s1b.isSuccessfullyCompleted() == true ); + REQUIRE( g1b.isSuccessfullyCompleted() == true ); + testCase2.close(); + REQUIRE( testCase2.isSuccessfullyCompleted() == true ); + } + } + SECTION( "Start a new inner section" ) { + IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); + REQUIRE( s2.isOpen() == true ); + + s2.close(); + REQUIRE( s2.isSuccessfullyCompleted() == true ); + + s1.close(); + REQUIRE( s1.isSuccessfullyCompleted() == false ); + + testCase.close(); + REQUIRE( testCase.isSuccessfullyCompleted() == false ); + + SECTION( "Re-enter for second generation" ) { + ctx.startCycle(); + IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + + IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1b.isSuccessfullyCompleted() == false ); + + // generator - next value + IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 ); + REQUIRE( g1b.isOpen() == true ); + REQUIRE( g1b.index() == 1 ); + + // inner section again + IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); + REQUIRE( s2b.isOpen() == true ); + + s2b.close(); + REQUIRE( s2b.isSuccessfullyCompleted() == true ); + + s1b.close(); + REQUIRE( s1b.isSuccessfullyCompleted() == true ); + REQUIRE( g1b.isSuccessfullyCompleted() == true ); + + testCase2.close(); + REQUIRE( testCase2.isSuccessfullyCompleted() == true ); + } + } + // !TBD" + // nested generator + // two sections within a generator + } } From 4b99be6a9a2c2933c8da84c5a5c59de18666cb57 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Thu, 29 Oct 2015 08:17:55 +0000 Subject: [PATCH 07/18] Cleaned tests up a bit --- projects/SelfTest/PartTrackerTests.cpp | 110 +++++++++++++------------ 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 6f9abfca..9c5efa1e 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -343,134 +343,142 @@ TEST_CASE( "PartTracker" ) { ctx.startCycle(); IPartTracker& testCase = SectionTracker::acquire( ctx, "Testcase" ); - REQUIRE( testCase.isSuccessfullyCompleted() == false ); + REQUIRE( testCase.isOpen() ); IPartTracker& s1 = SectionTracker::acquire( ctx, "S1" ); - REQUIRE( s1.isOpen() == true ); - REQUIRE( s1.isSuccessfullyCompleted() == false ); + REQUIRE( s1.isOpen() ); SECTION( "successfully close one section" ) { s1.close(); - REQUIRE( s1.isSuccessfullyCompleted() == true ); + REQUIRE( s1.isSuccessfullyCompleted() ); REQUIRE( testCase.hasEnded() == false ); testCase.close(); - REQUIRE( ctx.completedCycle() == true ); - REQUIRE( testCase.isSuccessfullyCompleted() == true ); + REQUIRE( ctx.completedCycle() ); + REQUIRE( testCase.isSuccessfullyCompleted() ); } SECTION( "fail one section" ) { s1.fail(); + REQUIRE( s1.hasEnded() ); REQUIRE( s1.isSuccessfullyCompleted() == false ); - REQUIRE( s1.hasEnded() == true ); - REQUIRE( testCase.isSuccessfullyCompleted() == false ); REQUIRE( testCase.hasEnded() == false ); testCase.close(); - REQUIRE( ctx.completedCycle() == true ); + REQUIRE( ctx.completedCycle() ); REQUIRE( testCase.isSuccessfullyCompleted() == false ); SECTION( "re-enter after failed section" ) { ctx.startCycle(); IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + REQUIRE( testCase2.isOpen() ); IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() == false ); testCase2.close(); - REQUIRE( ctx.completedCycle() == true ); - REQUIRE( testCase.isSuccessfullyCompleted() == true ); - REQUIRE( testCase.hasEnded() == true ); + REQUIRE( ctx.completedCycle() ); + REQUIRE( testCase.hasEnded() ); + REQUIRE( testCase.isSuccessfullyCompleted() ); } SECTION( "re-enter after failed section and find next section" ) { ctx.startCycle(); IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + REQUIRE( testCase2.isOpen() ); IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); - REQUIRE( s1b.isSuccessfullyCompleted() == false ); + REQUIRE( s1b.isOpen() == false ); IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); + s2.close(); - REQUIRE( ctx.completedCycle() == true ); + REQUIRE( ctx.completedCycle() ); testCase2.close(); - REQUIRE( testCase.isSuccessfullyCompleted() == true ); - REQUIRE( testCase.hasEnded() == true ); + REQUIRE( testCase.hasEnded() ); + REQUIRE( testCase.isSuccessfullyCompleted() ); } } SECTION( "successfully close one section, then find another" ) { s1.close(); - REQUIRE( ctx.completedCycle() == true ); IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() == false ); - REQUIRE( s2.isSuccessfullyCompleted() == false ); testCase.close(); - REQUIRE( testCase.isSuccessfullyCompleted() == false ); + REQUIRE( testCase.hasEnded() == false ); SECTION( "Re-enter - skips S1 and enters S2" ) { ctx.startCycle(); IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isSuccessfullyCompleted() == false ); - REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + REQUIRE( testCase2.isOpen() ); IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() == false ); IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2b.isOpen() ); - REQUIRE( s2b.isSuccessfullyCompleted() == false ); REQUIRE( ctx.completedCycle() == false ); SECTION ("Successfully close S2") { s2b.close(); - REQUIRE( ctx.completedCycle() == true ); + REQUIRE( ctx.completedCycle() ); - REQUIRE( s2b.isSuccessfullyCompleted() == true ); + REQUIRE( s2b.isSuccessfullyCompleted() ); REQUIRE( testCase2.hasEnded() == false ); testCase2.close(); - REQUIRE( testCase2.isSuccessfullyCompleted() == true ); + REQUIRE( testCase2.isSuccessfullyCompleted() ); } SECTION ("fail S2") { s2b.fail(); - REQUIRE( ctx.completedCycle() == true ); + REQUIRE( ctx.completedCycle() ); + REQUIRE( s2b.hasEnded() ); REQUIRE( s2b.isSuccessfullyCompleted() == false ); - REQUIRE( s2b.hasEnded() == true ); - REQUIRE( testCase2.hasEnded() == false ); testCase2.close(); REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + + // Need a final cycle + ctx.startCycle(); + IPartTracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase3.isOpen() ); + + IPartTracker& s1c = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1c.isOpen() == false ); + + IPartTracker& s2c = SectionTracker::acquire( ctx, "S2" ); + REQUIRE( s2c.isOpen() == false ); + + testCase3.close(); + REQUIRE( testCase3.isSuccessfullyCompleted() ); } } } SECTION( "open a nested section" ) { IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); - REQUIRE( s2.isOpen() == true ); + REQUIRE( s2.isOpen() ); s2.close(); - REQUIRE( s2.isSuccessfullyCompleted() == true ); + REQUIRE( s2.isSuccessfullyCompleted() ); REQUIRE( s1.isSuccessfullyCompleted() == false ); s1.close(); - REQUIRE( s1.isSuccessfullyCompleted() == true ); + REQUIRE( s1.isSuccessfullyCompleted() ); REQUIRE( testCase.isSuccessfullyCompleted() == false ); testCase.close(); - REQUIRE( testCase.isSuccessfullyCompleted() == true ); + REQUIRE( testCase.isSuccessfullyCompleted() ); } SECTION( "start a generator" ) { IndexTracker& g1 = IndexTracker::acquire( ctx, "G1", 2 ); - REQUIRE( g1.isOpen() == true ); + REQUIRE( g1.isOpen() ); REQUIRE( g1.index() == 0 ); REQUIRE( g1.isSuccessfullyCompleted() == false ); @@ -486,31 +494,31 @@ TEST_CASE( "PartTracker" ) { SECTION( "Re-enter for second generation" ) { ctx.startCycle(); IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isOpen() == true ); + REQUIRE( testCase2.isOpen() ); IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); - REQUIRE( s1b.isOpen() == true ); + REQUIRE( s1b.isOpen() ); IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 ); - REQUIRE( g1b.isOpen() == true ); + REQUIRE( g1b.isOpen() ); REQUIRE( g1b.index() == 1 ); REQUIRE( s1.isSuccessfullyCompleted() == false ); s1b.close(); - REQUIRE( s1b.isSuccessfullyCompleted() == true ); - REQUIRE( g1b.isSuccessfullyCompleted() == true ); + REQUIRE( s1b.isSuccessfullyCompleted() ); + REQUIRE( g1b.isSuccessfullyCompleted() ); testCase2.close(); - REQUIRE( testCase2.isSuccessfullyCompleted() == true ); + REQUIRE( testCase2.isSuccessfullyCompleted() ); } } SECTION( "Start a new inner section" ) { IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); - REQUIRE( s2.isOpen() == true ); + REQUIRE( s2.isOpen() ); s2.close(); - REQUIRE( s2.isSuccessfullyCompleted() == true ); + REQUIRE( s2.isSuccessfullyCompleted() ); s1.close(); REQUIRE( s1.isSuccessfullyCompleted() == false ); @@ -521,29 +529,29 @@ TEST_CASE( "PartTracker" ) { SECTION( "Re-enter for second generation" ) { ctx.startCycle(); IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); - REQUIRE( testCase2.isSuccessfullyCompleted() == false ); + REQUIRE( testCase2.isOpen() ); IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); - REQUIRE( s1b.isSuccessfullyCompleted() == false ); + REQUIRE( s1b.isOpen() ); // generator - next value IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 ); - REQUIRE( g1b.isOpen() == true ); + REQUIRE( g1b.isOpen() ); REQUIRE( g1b.index() == 1 ); // inner section again IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); - REQUIRE( s2b.isOpen() == true ); + REQUIRE( s2b.isOpen() ); s2b.close(); - REQUIRE( s2b.isSuccessfullyCompleted() == true ); + REQUIRE( s2b.isSuccessfullyCompleted() ); s1b.close(); - REQUIRE( s1b.isSuccessfullyCompleted() == true ); - REQUIRE( g1b.isSuccessfullyCompleted() == true ); + REQUIRE( s1b.isSuccessfullyCompleted() ); + REQUIRE( g1b.isSuccessfullyCompleted() ); testCase2.close(); - REQUIRE( testCase2.isSuccessfullyCompleted() == true ); + REQUIRE( testCase2.isSuccessfullyCompleted() ); } } // !TBD" From f4389b4fdb1961cd09c0567c1f3de02aed067507 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Thu, 29 Oct 2015 08:33:50 +0000 Subject: [PATCH 08/18] more minor clean-ups --- projects/SelfTest/PartTrackerTests.cpp | 45 ++++++++++++-------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 9c5efa1e..74dd3ac4 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -27,17 +27,16 @@ namespace Catch virtual std::string name() const = 0; // dynamic queries - virtual bool hasStarted() const = 0; // true even if ended - virtual bool hasEnded() const = 0; + virtual bool isComplete() const = 0; // Successfully completed or failed virtual bool isSuccessfullyCompleted() const = 0; - virtual bool isOpen() const = 0; + virtual bool isOpen() const = 0; // Started but not complete virtual IPartTracker& parent() = 0; // actions - virtual void close() = 0; + virtual void close() = 0; // Successfully complete virtual void fail() = 0; - virtual void markAsNeedingAnotherRun() =0; + virtual void markAsNeedingAnotherRun() = 0; virtual void addChild( Ptr const& child ) = 0; virtual IPartTracker* findChild( std::string const& name ) = 0; @@ -138,17 +137,14 @@ namespace Catch return m_name; } - virtual bool hasEnded() const CATCH_OVERRIDE { + virtual bool isComplete() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully || m_runState == Failed; } virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully; } - virtual bool hasStarted() const CATCH_OVERRIDE { - return m_runState != NotStarted; - } virtual bool isOpen() const CATCH_OVERRIDE { - return hasStarted() && !hasEnded(); + return m_runState != NotStarted && !isComplete(); } @@ -191,18 +187,18 @@ namespace Catch switch( m_runState ) { case CompletedSuccessfully: case Failed: + assert(false); // Shouldn't really get here + case NeedsAnotherRun: return; case Executing: m_runState = CompletedSuccessfully; break; case ExecutingChildren: - if( m_children.empty() || m_children.back()->hasEnded() ) + if( m_children.empty() || m_children.back()->isComplete() ) m_runState = CompletedSuccessfully; break; - case NeedsAnotherRun: - m_runState = Executing; - break; + default: throw std::logic_error( "Unexpected state" ); } @@ -249,7 +245,7 @@ namespace Catch section = new SectionTracker( name, ctx, ¤tPart ); currentPart.addChild( section ); } - if( !ctx.completedCycle() && !section->hasEnded() ) { + if( !ctx.completedCycle() && !section->isComplete() ) { section->open(); } @@ -280,7 +276,7 @@ namespace Catch currentPart.addChild( tracker ); } - if( !ctx.completedCycle() && !tracker->hasEnded() ) { + if( !ctx.completedCycle() && !tracker->isComplete() ) { if( tracker->m_runState != ExecutingChildren ) tracker->moveNext(); tracker->open(); @@ -351,7 +347,7 @@ TEST_CASE( "PartTracker" ) { SECTION( "successfully close one section" ) { s1.close(); REQUIRE( s1.isSuccessfullyCompleted() ); - REQUIRE( testCase.hasEnded() == false ); + REQUIRE( testCase.isComplete() == false ); testCase.close(); REQUIRE( ctx.completedCycle() ); @@ -360,9 +356,9 @@ TEST_CASE( "PartTracker" ) { SECTION( "fail one section" ) { s1.fail(); - REQUIRE( s1.hasEnded() ); + REQUIRE( s1.isComplete() ); REQUIRE( s1.isSuccessfullyCompleted() == false ); - REQUIRE( testCase.hasEnded() == false ); + REQUIRE( testCase.isComplete() == false ); testCase.close(); REQUIRE( ctx.completedCycle() ); @@ -378,7 +374,7 @@ TEST_CASE( "PartTracker" ) { testCase2.close(); REQUIRE( ctx.completedCycle() ); - REQUIRE( testCase.hasEnded() ); + REQUIRE( testCase.isComplete() ); REQUIRE( testCase.isSuccessfullyCompleted() ); } SECTION( "re-enter after failed section and find next section" ) { @@ -396,7 +392,7 @@ TEST_CASE( "PartTracker" ) { REQUIRE( ctx.completedCycle() ); testCase2.close(); - REQUIRE( testCase.hasEnded() ); + REQUIRE( testCase.isComplete() ); REQUIRE( testCase.isSuccessfullyCompleted() ); } } @@ -408,7 +404,7 @@ TEST_CASE( "PartTracker" ) { REQUIRE( s2.isOpen() == false ); testCase.close(); - REQUIRE( testCase.hasEnded() == false ); + REQUIRE( testCase.isComplete() == false ); SECTION( "Re-enter - skips S1 and enters S2" ) { ctx.startCycle(); @@ -428,7 +424,7 @@ TEST_CASE( "PartTracker" ) { REQUIRE( ctx.completedCycle() ); REQUIRE( s2b.isSuccessfullyCompleted() ); - REQUIRE( testCase2.hasEnded() == false ); + REQUIRE( testCase2.isComplete() == false ); testCase2.close(); REQUIRE( testCase2.isSuccessfullyCompleted() ); @@ -437,10 +433,11 @@ TEST_CASE( "PartTracker" ) { s2b.fail(); REQUIRE( ctx.completedCycle() ); - REQUIRE( s2b.hasEnded() ); + REQUIRE( s2b.isComplete() ); REQUIRE( s2b.isSuccessfullyCompleted() == false ); testCase2.close(); +// REQUIRE( testCase2.isComplete() ); REQUIRE( testCase2.isSuccessfullyCompleted() == false ); // Need a final cycle From ef62b578e293e21b5f973d30130866c9a869fdeb Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Thu, 29 Oct 2015 19:25:27 +0000 Subject: [PATCH 09/18] Added tests for failing a section within a generator - small fixes to implementation to make it work --- projects/SelfTest/PartTrackerTests.cpp | 112 ++++++++++++++++++++----- 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 74dd3ac4..b33084d9 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -187,9 +187,10 @@ namespace Catch switch( m_runState ) { case CompletedSuccessfully: case Failed: - assert(false); // Shouldn't really get here + throw std::logic_error( "Illogical state" ); + case NeedsAnotherRun: - return; + break;; case Executing: m_runState = CompletedSuccessfully; @@ -277,7 +278,7 @@ namespace Catch } if( !ctx.completedCycle() && !tracker->isComplete() ) { - if( tracker->m_runState != ExecutingChildren ) + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) tracker->moveNext(); tracker->open(); } @@ -462,15 +463,15 @@ TEST_CASE( "PartTracker" ) { REQUIRE( s2.isOpen() ); s2.close(); - REQUIRE( s2.isSuccessfullyCompleted() ); - REQUIRE( s1.isSuccessfullyCompleted() == false ); + REQUIRE( s2.isComplete() ); + REQUIRE( s1.isComplete() == false ); s1.close(); - REQUIRE( s1.isSuccessfullyCompleted() ); - REQUIRE( testCase.isSuccessfullyCompleted() == false ); + REQUIRE( s1.isComplete() ); + REQUIRE( testCase.isComplete() == false ); testCase.close(); - REQUIRE( testCase.isSuccessfullyCompleted() ); + REQUIRE( testCase.isComplete() ); } SECTION( "start a generator" ) { @@ -478,13 +479,13 @@ TEST_CASE( "PartTracker" ) { REQUIRE( g1.isOpen() ); REQUIRE( g1.index() == 0 ); - REQUIRE( g1.isSuccessfullyCompleted() == false ); - REQUIRE( s1.isSuccessfullyCompleted() == false ); + REQUIRE( g1.isComplete() == false ); + REQUIRE( s1.isComplete() == false ); SECTION( "close outer section" ) { s1.close(); - REQUIRE( s1.isSuccessfullyCompleted() == false ); + REQUIRE( s1.isComplete() == false ); testCase.close(); REQUIRE( testCase.isSuccessfullyCompleted() == false ); @@ -501,13 +502,13 @@ TEST_CASE( "PartTracker" ) { REQUIRE( g1b.isOpen() ); REQUIRE( g1b.index() == 1 ); - REQUIRE( s1.isSuccessfullyCompleted() == false ); + REQUIRE( s1.isComplete() == false ); s1b.close(); - REQUIRE( s1b.isSuccessfullyCompleted() ); - REQUIRE( g1b.isSuccessfullyCompleted() ); + REQUIRE( s1b.isComplete() ); + REQUIRE( g1b.isComplete() ); testCase2.close(); - REQUIRE( testCase2.isSuccessfullyCompleted() ); + REQUIRE( testCase2.isComplete() ); } } SECTION( "Start a new inner section" ) { @@ -515,13 +516,13 @@ TEST_CASE( "PartTracker" ) { REQUIRE( s2.isOpen() ); s2.close(); - REQUIRE( s2.isSuccessfullyCompleted() ); + REQUIRE( s2.isComplete() ); s1.close(); - REQUIRE( s1.isSuccessfullyCompleted() == false ); + REQUIRE( s1.isComplete() == false ); testCase.close(); - REQUIRE( testCase.isSuccessfullyCompleted() == false ); + REQUIRE( testCase.isComplete() == false ); SECTION( "Re-enter for second generation" ) { ctx.startCycle(); @@ -541,14 +542,81 @@ TEST_CASE( "PartTracker" ) { REQUIRE( s2b.isOpen() ); s2b.close(); - REQUIRE( s2b.isSuccessfullyCompleted() ); + REQUIRE( s2b.isComplete() ); s1b.close(); - REQUIRE( s1b.isSuccessfullyCompleted() ); - REQUIRE( g1b.isSuccessfullyCompleted() ); + REQUIRE( g1b.isComplete() ); + REQUIRE( s1b.isComplete() ); testCase2.close(); - REQUIRE( testCase2.isSuccessfullyCompleted() ); + REQUIRE( testCase2.isComplete() ); + } + } + + SECTION( "Fail an inner section" ) { + IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); + REQUIRE( s2.isOpen() ); + + s2.fail(); + REQUIRE( s2.isComplete() ); + REQUIRE( s2.isSuccessfullyCompleted() == false ); + + s1.close(); + REQUIRE( s1.isComplete() == false ); + + testCase.close(); + REQUIRE( testCase.isComplete() == false ); + + SECTION( "Re-enter for second generation" ) { + ctx.startCycle(); + IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase2.isOpen() ); + + IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1b.isOpen() ); + + // generator - still same value + IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 ); + REQUIRE( g1b.isOpen() ); + REQUIRE( g1b.index() == 0 ); + + // inner section again - this time won't open + IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); + REQUIRE( s2b.isOpen() == false ); + + s1b.close(); + REQUIRE( g1b.isComplete() == false ); + REQUIRE( s1b.isComplete() == false ); + + testCase2.close(); + REQUIRE( testCase2.isComplete() == false ); + + // Another cycle - now should complete + ctx.startCycle(); + IPartTracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" ); + REQUIRE( testCase3.isOpen() ); + + IPartTracker& s1c = SectionTracker::acquire( ctx, "S1" ); + REQUIRE( s1c.isOpen() ); + + // generator - now next value + IndexTracker& g1c = IndexTracker::acquire( ctx, "G1", 2 ); + REQUIRE( g1c.isOpen() ); + REQUIRE( g1c.index() == 1 ); + + // inner section - now should open again + IPartTracker& s2c = SectionTracker::acquire( ctx, "S2" ); + REQUIRE( s2c.isOpen() ); + + s2c.close(); + REQUIRE( s2c.isComplete() ); + + s1c.close(); + REQUIRE( g1c.isComplete() ); + REQUIRE( s1c.isComplete() ); + + testCase3.close(); + REQUIRE( testCase3.isComplete() ); } } // !TBD" From 73a140fb9e2aeed03011c70715ccd05be5eaf8d7 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Thu, 29 Oct 2015 19:33:25 +0000 Subject: [PATCH 10/18] More minor tweaks --- projects/SelfTest/PartTrackerTests.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index b33084d9..88a8cb79 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -104,7 +104,7 @@ namespace Catch class PartTrackerBase : public IPartTracker { protected: - enum RunState { + enum CycleState { NotStarted, Executing, ExecutingChildren, @@ -125,18 +125,18 @@ namespace Catch TrackerContext& m_ctx; IPartTracker* m_parent; Children m_children; - RunState m_runState; + CycleState m_runState; public: PartTrackerBase( std::string const& name, TrackerContext& ctx, IPartTracker* parent ) : m_name( name ), m_ctx( ctx ), m_parent( parent ), - m_runState( NotStarted ) {} + m_runState( NotStarted ) + {} virtual std::string name() const CATCH_OVERRIDE { return m_name; } - virtual bool isComplete() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully || m_runState == Failed; } @@ -227,7 +227,6 @@ namespace Catch }; - class SectionTracker : public PartTrackerBase { public: SectionTracker( std::string const& name, TrackerContext& ctx, IPartTracker* parent ) @@ -438,7 +437,6 @@ TEST_CASE( "PartTracker" ) { REQUIRE( s2b.isSuccessfullyCompleted() == false ); testCase2.close(); -// REQUIRE( testCase2.isComplete() ); REQUIRE( testCase2.isSuccessfullyCompleted() == false ); // Need a final cycle From 3deb3e010f1fbe6eadb7ed0879b706853d574124 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Thu, 29 Oct 2015 19:41:50 +0000 Subject: [PATCH 11/18] Removed the "part" component of the tracker names --- projects/SelfTest/PartTrackerTests.cpp | 161 ++++++++++++------------- 1 file changed, 78 insertions(+), 83 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 88a8cb79..13dfe5e0 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -20,8 +20,8 @@ namespace Catch { - struct IPartTracker : SharedImpl<> { - virtual ~IPartTracker() {} + struct ITracker : SharedImpl<> { + virtual ~ITracker() {} // static queries virtual std::string name() const = 0; @@ -31,15 +31,15 @@ namespace Catch virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; // Started but not complete - virtual IPartTracker& parent() = 0; + virtual ITracker& parent() = 0; // actions virtual void close() = 0; // Successfully complete virtual void fail() = 0; virtual void markAsNeedingAnotherRun() = 0; - virtual void addChild( Ptr const& child ) = 0; - virtual IPartTracker* findChild( std::string const& name ) = 0; + virtual void addChild( Ptr const& child ) = 0; + virtual ITracker* findChild( std::string const& name ) = 0; virtual void openChild() = 0; }; @@ -52,8 +52,8 @@ namespace Catch CompletedCycle }; - Ptr m_rootPart; - IPartTracker* m_currentPart; + Ptr m_rootTracker; + ITracker* m_currentTracker; RunState m_runState; public: @@ -64,21 +64,21 @@ namespace Catch } TrackerContext() - : m_currentPart( CATCH_NULL ), + : m_currentTracker( CATCH_NULL ), m_runState( NotStarted ) {} - IPartTracker& startRun(); + ITracker& startRun(); void endRun() { - m_rootPart.reset(); - m_currentPart = CATCH_NULL; + m_rootTracker.reset(); + m_currentTracker = CATCH_NULL; m_runState = NotStarted; } void startCycle() { - m_currentPart = m_rootPart.get(); + m_currentTracker = m_rootTracker.get(); m_runState = Executing; } void completeCycle() { @@ -89,20 +89,15 @@ namespace Catch return m_runState == CompletedCycle; } - IPartTracker& currentPart() { - return *m_currentPart; + ITracker& currentTracker() { + return *m_currentTracker; } - void setCurrentPart( IPartTracker* part ) { - m_currentPart = part; + void setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; } - - IPartTracker* findPart( std::string const& name ) { - return m_currentPart->findChild( name ); - } - }; - class PartTrackerBase : public IPartTracker { + class TrackerBase : public ITracker { protected: enum CycleState { NotStarted, @@ -116,18 +111,18 @@ namespace Catch std::string m_name; public: TrackerHasName( std::string const& name ) : m_name( name ) {} - bool operator ()( Ptr const& tracker ) { + bool operator ()( Ptr const& tracker ) { return tracker->name() == m_name; } }; - typedef std::vector > Children; + typedef std::vector > Children; std::string m_name; TrackerContext& m_ctx; - IPartTracker* m_parent; + ITracker* m_parent; Children m_children; CycleState m_runState; public: - PartTrackerBase( std::string const& name, TrackerContext& ctx, IPartTracker* parent ) + TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent ) : m_name( name ), m_ctx( ctx ), m_parent( parent ), @@ -148,18 +143,18 @@ namespace Catch } - virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { m_children.push_back( child ); size_t childCount = m_children.size(); } - virtual IPartTracker* findChild( std::string const& name ) CATCH_OVERRIDE { + virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE { Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); return( it != m_children.end() ) ? it->get() : CATCH_NULL; } - virtual IPartTracker& parent() CATCH_OVERRIDE { + virtual ITracker& parent() CATCH_OVERRIDE { assert( m_parent ); // Should always be non-null except for root return *m_parent; } @@ -181,8 +176,8 @@ namespace Catch virtual void close() CATCH_OVERRIDE { // Close any still open children (e.g. generators) - while( &m_ctx.currentPart() != this ) - m_ctx.currentPart().close(); + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); switch( m_runState ) { case CompletedSuccessfully: @@ -219,31 +214,31 @@ namespace Catch private: void moveToParent() { assert( m_parent ); - m_ctx.setCurrentPart( m_parent ); + m_ctx.setCurrentTracker( m_parent ); } void moveToThis() { - m_ctx.setCurrentPart( this ); + m_ctx.setCurrentTracker( this ); } }; - class SectionTracker : public PartTrackerBase { + class SectionTracker : public TrackerBase { public: - SectionTracker( std::string const& name, TrackerContext& ctx, IPartTracker* parent ) - : PartTrackerBase( name, ctx, parent ) + SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( name, ctx, parent ) {} static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) { SectionTracker* section = CATCH_NULL; - IPartTracker& currentPart = ctx.currentPart(); - if( IPartTracker* part = currentPart.findChild( name ) ) { - section = dynamic_cast( part ); + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( name ) ) { + section = dynamic_cast( childTracker ); assert( section ); } else { - section = new SectionTracker( name, ctx, ¤tPart ); - currentPart.addChild( section ); + section = new SectionTracker( name, ctx, ¤tTracker ); + currentTracker.addChild( section ); } if( !ctx.completedCycle() && !section->isComplete() ) { @@ -253,12 +248,12 @@ namespace Catch } }; - class IndexTracker : public PartTrackerBase { + class IndexTracker : public TrackerBase { int m_size; int m_index; public: - IndexTracker( std::string const& name, TrackerContext& ctx, IPartTracker* parent, int size ) - : PartTrackerBase( name, ctx, parent ), + IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( name, ctx, parent ), m_size( size ), m_index( -1 ) {} @@ -266,14 +261,14 @@ namespace Catch static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) { IndexTracker* tracker = CATCH_NULL; - IPartTracker& currentPart = ctx.currentPart(); - if( IPartTracker* part = currentPart.findChild( name ) ) { - tracker = dynamic_cast( part ); + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( name ) ) { + tracker = dynamic_cast( childTracker ); assert( tracker ); } else { - tracker = new IndexTracker( name, ctx, ¤tPart, size ); - currentPart.addChild( tracker ); + tracker = new IndexTracker( name, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); } if( !ctx.completedCycle() && !tracker->isComplete() ) { @@ -293,18 +288,18 @@ namespace Catch } virtual void close() CATCH_OVERRIDE { - PartTrackerBase::close(); + TrackerBase::close(); if( m_runState == CompletedSuccessfully ) if( m_index < m_size-1 ) m_runState = Executing; } }; - IPartTracker& TrackerContext::startRun() { - m_rootPart = new SectionTracker( "{root}", *this, CATCH_NULL ); - m_currentPart = CATCH_NULL; + ITracker& TrackerContext::startRun() { + m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL ); + m_currentTracker = CATCH_NULL; m_runState = Executing; - return *m_rootPart; + return *m_rootTracker; } class LocalContext { @@ -332,16 +327,16 @@ inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) { // REQUIRE( C_A_T_C_H_Context().i() == 42 ); } -TEST_CASE( "PartTracker" ) { +TEST_CASE( "Tracker" ) { TrackerContext ctx; ctx.startRun(); ctx.startCycle(); - IPartTracker& testCase = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase.isOpen() ); - IPartTracker& s1 = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1 = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1.isOpen() ); SECTION( "successfully close one section" ) { @@ -366,10 +361,10 @@ TEST_CASE( "PartTracker" ) { SECTION( "re-enter after failed section" ) { ctx.startCycle(); - IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); - IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() == false ); testCase2.close(); @@ -379,13 +374,13 @@ TEST_CASE( "PartTracker" ) { } SECTION( "re-enter after failed section and find next section" ) { ctx.startCycle(); - IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); - IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() == false ); - IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); s2.close(); @@ -400,7 +395,7 @@ TEST_CASE( "PartTracker" ) { SECTION( "successfully close one section, then find another" ) { s1.close(); - IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() == false ); testCase.close(); @@ -408,13 +403,13 @@ TEST_CASE( "PartTracker" ) { SECTION( "Re-enter - skips S1 and enters S2" ) { ctx.startCycle(); - IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); - IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() == false ); - IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2b = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2b.isOpen() ); REQUIRE( ctx.completedCycle() == false ); @@ -441,13 +436,13 @@ TEST_CASE( "PartTracker" ) { // Need a final cycle ctx.startCycle(); - IPartTracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase3.isOpen() ); - IPartTracker& s1c = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1c = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1c.isOpen() == false ); - IPartTracker& s2c = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2c = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2c.isOpen() == false ); testCase3.close(); @@ -457,7 +452,7 @@ TEST_CASE( "PartTracker" ) { } SECTION( "open a nested section" ) { - IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); s2.close(); @@ -489,10 +484,10 @@ TEST_CASE( "PartTracker" ) { SECTION( "Re-enter for second generation" ) { ctx.startCycle(); - IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); - IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() ); @@ -510,7 +505,7 @@ TEST_CASE( "PartTracker" ) { } } SECTION( "Start a new inner section" ) { - IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); s2.close(); @@ -524,10 +519,10 @@ TEST_CASE( "PartTracker" ) { SECTION( "Re-enter for second generation" ) { ctx.startCycle(); - IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); - IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() ); // generator - next value @@ -536,7 +531,7 @@ TEST_CASE( "PartTracker" ) { REQUIRE( g1b.index() == 1 ); // inner section again - IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2b = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2b.isOpen() ); s2b.close(); @@ -552,7 +547,7 @@ TEST_CASE( "PartTracker" ) { } SECTION( "Fail an inner section" ) { - IPartTracker& s2 = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); s2.fail(); @@ -567,10 +562,10 @@ TEST_CASE( "PartTracker" ) { SECTION( "Re-enter for second generation" ) { ctx.startCycle(); - IPartTracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); - IPartTracker& s1b = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1b = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1b.isOpen() ); // generator - still same value @@ -579,7 +574,7 @@ TEST_CASE( "PartTracker" ) { REQUIRE( g1b.index() == 0 ); // inner section again - this time won't open - IPartTracker& s2b = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2b = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2b.isOpen() == false ); s1b.close(); @@ -591,10 +586,10 @@ TEST_CASE( "PartTracker" ) { // Another cycle - now should complete ctx.startCycle(); - IPartTracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" ); + ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase3.isOpen() ); - IPartTracker& s1c = SectionTracker::acquire( ctx, "S1" ); + ITracker& s1c = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1c.isOpen() ); // generator - now next value @@ -603,7 +598,7 @@ TEST_CASE( "PartTracker" ) { REQUIRE( g1c.index() == 1 ); // inner section - now should open again - IPartTracker& s2c = SectionTracker::acquire( ctx, "S2" ); + ITracker& s2c = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2c.isOpen() ); s2c.close(); From b8515929b87b471dff0675b450423c17b40c42a2 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Mon, 2 Nov 2015 06:14:52 +0000 Subject: [PATCH 12/18] Moved all new tracking impl into catch_test_case_tracker.pp --- include/internal/catch_config.hpp | 1 - include/internal/catch_impl.hpp | 10 + include/internal/catch_suppress_warnings.h | 1 + include/internal/catch_test_case_tracker.hpp | 294 ++++++++++++++++++ projects/SelfTest/PartTrackerTests.cpp | 299 +------------------ projects/SelfTest/SectionTrackerTests.cpp | 6 +- 6 files changed, 310 insertions(+), 301 deletions(-) diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp index eca10363..c0d0948e 100644 --- a/include/internal/catch_config.hpp +++ b/include/internal/catch_config.hpp @@ -155,7 +155,6 @@ namespace Catch { TestSpec m_testSpec; }; - } // end namespace Catch #endif // TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp index 170b4807..baabd7ab 100644 --- a/include/internal/catch_impl.hpp +++ b/include/internal/catch_impl.hpp @@ -35,6 +35,7 @@ #include "catch_tostring.hpp" #include "catch_result_builder.hpp" #include "catch_tag_alias_registry.hpp" +#include "catch_test_case_tracker.hpp" #include "../reporters/catch_reporter_multi.hpp" #include "../reporters/catch_reporter_xml.hpp" @@ -43,6 +44,8 @@ #include "../reporters/catch_reporter_compact.hpp" namespace Catch { + // These are all here to avoid warnings about not having any out of line + // virtual methods NonCopyable::~NonCopyable() {} IShared::~IShared() {} IStream::~IStream() CATCH_NOEXCEPT {} @@ -91,6 +94,13 @@ namespace Catch { Matchers::Impl::StdString::EndsWith::~EndsWith() {} void Config::dummy() {} + + namespace TestCaseTracking { + ITracker::~ITracker() {} + TrackerBase::~TrackerBase() {} + SectionTracker::~SectionTracker() {} + IndexTracker::~IndexTracker() {} + } } #ifdef __clang__ diff --git a/include/internal/catch_suppress_warnings.h b/include/internal/catch_suppress_warnings.h index 094ed98b..8f57b285 100644 --- a/include/internal/catch_suppress_warnings.h +++ b/include/internal/catch_suppress_warnings.h @@ -19,6 +19,7 @@ # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" # pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ # pragma GCC diagnostic ignored "-Wvariadic-macros" diff --git a/include/internal/catch_test_case_tracker.hpp b/include/internal/catch_test_case_tracker.hpp index eb2616e0..4f174fb6 100644 --- a/include/internal/catch_test_case_tracker.hpp +++ b/include/internal/catch_test_case_tracker.hpp @@ -9,14 +9,308 @@ #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED #include "catch_compiler_capabilities.h" +#include "catch_ptr.hpp" #include #include #include +#include namespace Catch { +namespace TestCaseTracking { + + struct ITracker : SharedImpl<> { + virtual ~ITracker(); + + // static queries + virtual std::string name() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( Ptr const& child ) = 0; + virtual ITracker* findChild( std::string const& name ) = 0; + virtual void openChild() = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + Ptr m_rootTracker; + ITracker* m_currentTracker; + RunState m_runState; + + public: + + static TrackerContext& instance() { + static TrackerContext s_instance; + return s_instance; + } + + TrackerContext() + : m_currentTracker( CATCH_NULL ), + m_runState( NotStarted ) + {} + + + ITracker& startRun(); + + void endRun() { + m_rootTracker.reset(); + m_currentTracker = CATCH_NULL; + m_runState = NotStarted; + } + + void startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void completeCycle() { + m_runState = CompletedCycle; + } + + bool completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& currentTracker() { + return *m_currentTracker; + } + void setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + class TrackerHasName { + std::string m_name; + public: + TrackerHasName( std::string const& name ) : m_name( name ) {} + bool operator ()( Ptr const& tracker ) { + return tracker->name() == m_name; + } + }; + typedef std::vector > Children; + std::string m_name; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState; + public: + TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent ) + : m_name( name ), + m_ctx( ctx ), + m_parent( parent ), + m_runState( NotStarted ) + {} + virtual ~TrackerBase(); + + virtual std::string name() const CATCH_OVERRIDE { + return m_name; + } + virtual bool isComplete() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully; + } + virtual bool isOpen() const CATCH_OVERRIDE { + return m_runState != NotStarted && !isComplete(); + } + + + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + m_children.push_back( child ); + } + + virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE { + Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); + return( it != m_children.end() ) + ? it->get() + : CATCH_NULL; + } + virtual ITracker& parent() CATCH_OVERRIDE { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + virtual void openChild() CATCH_OVERRIDE { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + void open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + virtual void close() CATCH_OVERRIDE { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NotStarted: + case CompletedSuccessfully: + case Failed: + throw std::logic_error( "Illogical state" ); + + case NeedsAnotherRun: + break;; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( m_children.empty() || m_children.back()->isComplete() ) + m_runState = CompletedSuccessfully; + break; + + default: + throw std::logic_error( "Unexpected state" ); + } + moveToParent(); + m_ctx.completeCycle(); + } + virtual void fail() CATCH_OVERRIDE { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { + m_runState = NeedsAnotherRun; + } + private: + void moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void moveToThis() { + m_ctx.setCurrentTracker( this ); + } + }; + + class SectionTracker : public TrackerBase { + public: + SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( name, ctx, parent ) + {} + virtual ~SectionTracker(); + + static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) { + SectionTracker* section = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( name ) ) { + section = dynamic_cast( childTracker ); + assert( section ); + } + else { + section = new SectionTracker( name, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() && !section->isComplete() ) { + + section->open(); + } + return *section; + } + }; + + class IndexTracker : public TrackerBase { + int m_size; + int m_index; + public: + IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( name, ctx, parent ), + m_size( size ), + m_index( -1 ) + {} + virtual ~IndexTracker(); + + static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) { + IndexTracker* tracker = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( name ) ) { + tracker = dynamic_cast( childTracker ); + assert( tracker ); + } + else { + tracker = new IndexTracker( name, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int index() const { return m_index; } + + void moveNext() { + m_index++; + m_children.clear(); + } + + virtual void close() CATCH_OVERRIDE { + TrackerBase::close(); + if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) + m_runState = Executing; + } + }; + + inline ITracker& TrackerContext::startRun() { + m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL ); + m_currentTracker = CATCH_NULL; + m_runState = Executing; + return *m_rootTracker; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +// !TBD: Deprecated namespace SectionTracking { + class TrackedSection { typedef std::map TrackedSections; diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 13dfe5e0..11a501ad 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -6,302 +6,11 @@ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #include "internal/catch_suppress_warnings.h" -#include "internal/catch_compiler_capabilities.h" -#include "internal/catch_ptr.hpp" +#include "internal/catch_test_case_tracker.hpp" -#ifdef __clang__ -//# pragma clang diagnostic ignored "-Wpadded" -//# pragma clang diagnostic ignored "-Wc++98-compat" -#endif - -#include -#include -#include namespace Catch { - struct ITracker : SharedImpl<> { - virtual ~ITracker() {} - - // static queries - virtual std::string name() const = 0; - - // dynamic queries - virtual bool isComplete() const = 0; // Successfully completed or failed - virtual bool isSuccessfullyCompleted() const = 0; - virtual bool isOpen() const = 0; // Started but not complete - - virtual ITracker& parent() = 0; - - // actions - virtual void close() = 0; // Successfully complete - virtual void fail() = 0; - virtual void markAsNeedingAnotherRun() = 0; - - virtual void addChild( Ptr const& child ) = 0; - virtual ITracker* findChild( std::string const& name ) = 0; - virtual void openChild() = 0; - }; - - - class TrackerContext { - - enum RunState { - NotStarted, - Executing, - CompletedCycle - }; - - Ptr m_rootTracker; - ITracker* m_currentTracker; - RunState m_runState; - - public: - - static TrackerContext& instance() { - static TrackerContext s_instance; - return s_instance; - } - - TrackerContext() - : m_currentTracker( CATCH_NULL ), - m_runState( NotStarted ) - {} - - - ITracker& startRun(); - - void endRun() { - m_rootTracker.reset(); - m_currentTracker = CATCH_NULL; - m_runState = NotStarted; - } - - void startCycle() { - m_currentTracker = m_rootTracker.get(); - m_runState = Executing; - } - void completeCycle() { - m_runState = CompletedCycle; - } - - bool completedCycle() const { - return m_runState == CompletedCycle; - } - - ITracker& currentTracker() { - return *m_currentTracker; - } - void setCurrentTracker( ITracker* tracker ) { - m_currentTracker = tracker; - } - }; - - class TrackerBase : public ITracker { - protected: - enum CycleState { - NotStarted, - Executing, - ExecutingChildren, - NeedsAnotherRun, - CompletedSuccessfully, - Failed - }; - class TrackerHasName { - std::string m_name; - public: - TrackerHasName( std::string const& name ) : m_name( name ) {} - bool operator ()( Ptr const& tracker ) { - return tracker->name() == m_name; - } - }; - typedef std::vector > Children; - std::string m_name; - TrackerContext& m_ctx; - ITracker* m_parent; - Children m_children; - CycleState m_runState; - public: - TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent ) - : m_name( name ), - m_ctx( ctx ), - m_parent( parent ), - m_runState( NotStarted ) - {} - - virtual std::string name() const CATCH_OVERRIDE { - return m_name; - } - virtual bool isComplete() const CATCH_OVERRIDE { - return m_runState == CompletedSuccessfully || m_runState == Failed; - } - virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { - return m_runState == CompletedSuccessfully; - } - virtual bool isOpen() const CATCH_OVERRIDE { - return m_runState != NotStarted && !isComplete(); - } - - - virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { - m_children.push_back( child ); - size_t childCount = m_children.size(); - } - - virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE { - Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); - return( it != m_children.end() ) - ? it->get() - : CATCH_NULL; - } - virtual ITracker& parent() CATCH_OVERRIDE { - assert( m_parent ); // Should always be non-null except for root - return *m_parent; - } - - virtual void openChild() CATCH_OVERRIDE { - if( m_runState != ExecutingChildren ) { - m_runState = ExecutingChildren; - if( m_parent ) - m_parent->openChild(); - } - } - void open() { - m_runState = Executing; - moveToThis(); - if( m_parent ) - m_parent->openChild(); - } - - virtual void close() CATCH_OVERRIDE { - - // Close any still open children (e.g. generators) - while( &m_ctx.currentTracker() != this ) - m_ctx.currentTracker().close(); - - switch( m_runState ) { - case CompletedSuccessfully: - case Failed: - throw std::logic_error( "Illogical state" ); - - case NeedsAnotherRun: - break;; - - case Executing: - m_runState = CompletedSuccessfully; - break; - case ExecutingChildren: - if( m_children.empty() || m_children.back()->isComplete() ) - m_runState = CompletedSuccessfully; - break; - - default: - throw std::logic_error( "Unexpected state" ); - } - moveToParent(); - m_ctx.completeCycle(); - } - virtual void fail() CATCH_OVERRIDE { - m_runState = Failed; - if( m_parent ) - m_parent->markAsNeedingAnotherRun(); - moveToParent(); - m_ctx.completeCycle(); - } - virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { - m_runState = NeedsAnotherRun; - } - private: - void moveToParent() { - assert( m_parent ); - m_ctx.setCurrentTracker( m_parent ); - } - void moveToThis() { - m_ctx.setCurrentTracker( this ); - } - }; - - - class SectionTracker : public TrackerBase { - public: - SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent ) - : TrackerBase( name, ctx, parent ) - {} - - static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) { - SectionTracker* section = CATCH_NULL; - - ITracker& currentTracker = ctx.currentTracker(); - if( ITracker* childTracker = currentTracker.findChild( name ) ) { - section = dynamic_cast( childTracker ); - assert( section ); - } - else { - section = new SectionTracker( name, ctx, ¤tTracker ); - currentTracker.addChild( section ); - } - if( !ctx.completedCycle() && !section->isComplete() ) { - - section->open(); - } - return *section; - } - }; - - class IndexTracker : public TrackerBase { - int m_size; - int m_index; - public: - IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size ) - : TrackerBase( name, ctx, parent ), - m_size( size ), - m_index( -1 ) - {} - - static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) { - IndexTracker* tracker = CATCH_NULL; - - ITracker& currentTracker = ctx.currentTracker(); - if( ITracker* childTracker = currentTracker.findChild( name ) ) { - tracker = dynamic_cast( childTracker ); - assert( tracker ); - } - else { - tracker = new IndexTracker( name, ctx, ¤tTracker, size ); - currentTracker.addChild( tracker ); - } - - if( !ctx.completedCycle() && !tracker->isComplete() ) { - if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) - tracker->moveNext(); - tracker->open(); - } - - return *tracker; - } - - int index() const { return m_index; } - - void moveNext() { - m_index++; - m_children.clear(); - } - - virtual void close() CATCH_OVERRIDE { - TrackerBase::close(); - if( m_runState == CompletedSuccessfully ) - if( m_index < m_size-1 ) - m_runState = Executing; - } - }; - - ITracker& TrackerContext::startRun() { - m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL ); - m_currentTracker = CATCH_NULL; - m_runState = Executing; - return *m_rootTracker; - } - class LocalContext { public: @@ -322,10 +31,10 @@ inline Catch::TrackerContext& C_A_T_C_H_Context() { using namespace Catch; -inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) { - +//inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) { +// // REQUIRE( C_A_T_C_H_Context().i() == 42 ); -} +//} TEST_CASE( "Tracker" ) { diff --git a/projects/SelfTest/SectionTrackerTests.cpp b/projects/SelfTest/SectionTrackerTests.cpp index 96e96f5e..d3df994d 100644 --- a/projects/SelfTest/SectionTrackerTests.cpp +++ b/projects/SelfTest/SectionTrackerTests.cpp @@ -6,11 +6,7 @@ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ -#ifdef __clang__ -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wc++98-compat" -#endif - +#include "internal/catch_suppress_warnings.h" #include "internal/catch_test_case_tracker.hpp" #include "catch.hpp" From 0b523db6b9276a1792d0723df440c393a843349c Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Mon, 2 Nov 2015 06:16:09 +0000 Subject: [PATCH 13/18] Converted all new part tracking tests/ sections to non variadic form --- projects/SelfTest/PartTrackerTests.cpp | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/projects/SelfTest/PartTrackerTests.cpp b/projects/SelfTest/PartTrackerTests.cpp index 11a501ad..c576d53c 100644 --- a/projects/SelfTest/PartTrackerTests.cpp +++ b/projects/SelfTest/PartTrackerTests.cpp @@ -36,7 +36,7 @@ using namespace Catch; // REQUIRE( C_A_T_C_H_Context().i() == 42 ); //} -TEST_CASE( "Tracker" ) { +TEST_CASE( "Tracker", "" ) { TrackerContext ctx; ctx.startRun(); @@ -48,7 +48,7 @@ TEST_CASE( "Tracker" ) { ITracker& s1 = SectionTracker::acquire( ctx, "S1" ); REQUIRE( s1.isOpen() ); - SECTION( "successfully close one section" ) { + SECTION( "successfully close one section", "" ) { s1.close(); REQUIRE( s1.isSuccessfullyCompleted() ); REQUIRE( testCase.isComplete() == false ); @@ -58,7 +58,7 @@ TEST_CASE( "Tracker" ) { REQUIRE( testCase.isSuccessfullyCompleted() ); } - SECTION( "fail one section" ) { + SECTION( "fail one section", "" ) { s1.fail(); REQUIRE( s1.isComplete() ); REQUIRE( s1.isSuccessfullyCompleted() == false ); @@ -68,7 +68,7 @@ TEST_CASE( "Tracker" ) { REQUIRE( ctx.completedCycle() ); REQUIRE( testCase.isSuccessfullyCompleted() == false ); - SECTION( "re-enter after failed section" ) { + SECTION( "re-enter after failed section", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); @@ -81,7 +81,7 @@ TEST_CASE( "Tracker" ) { REQUIRE( testCase.isComplete() ); REQUIRE( testCase.isSuccessfullyCompleted() ); } - SECTION( "re-enter after failed section and find next section" ) { + SECTION( "re-enter after failed section and find next section", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); @@ -101,7 +101,7 @@ TEST_CASE( "Tracker" ) { } } - SECTION( "successfully close one section, then find another" ) { + SECTION( "successfully close one section, then find another", "" ) { s1.close(); ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); @@ -110,7 +110,7 @@ TEST_CASE( "Tracker" ) { testCase.close(); REQUIRE( testCase.isComplete() == false ); - SECTION( "Re-enter - skips S1 and enters S2" ) { + SECTION( "Re-enter - skips S1 and enters S2", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); @@ -160,7 +160,7 @@ TEST_CASE( "Tracker" ) { } } - SECTION( "open a nested section" ) { + SECTION( "open a nested section", "" ) { ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); @@ -176,7 +176,7 @@ TEST_CASE( "Tracker" ) { REQUIRE( testCase.isComplete() ); } - SECTION( "start a generator" ) { + SECTION( "start a generator", "" ) { IndexTracker& g1 = IndexTracker::acquire( ctx, "G1", 2 ); REQUIRE( g1.isOpen() ); REQUIRE( g1.index() == 0 ); @@ -191,7 +191,7 @@ TEST_CASE( "Tracker" ) { testCase.close(); REQUIRE( testCase.isSuccessfullyCompleted() == false ); - SECTION( "Re-enter for second generation" ) { + SECTION( "Re-enter for second generation", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); @@ -213,7 +213,7 @@ TEST_CASE( "Tracker" ) { REQUIRE( testCase2.isComplete() ); } } - SECTION( "Start a new inner section" ) { + SECTION( "Start a new inner section", "" ) { ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); @@ -226,7 +226,7 @@ TEST_CASE( "Tracker" ) { testCase.close(); REQUIRE( testCase.isComplete() == false ); - SECTION( "Re-enter for second generation" ) { + SECTION( "Re-enter for second generation", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); @@ -255,7 +255,7 @@ TEST_CASE( "Tracker" ) { } } - SECTION( "Fail an inner section" ) { + SECTION( "Fail an inner section", "" ) { ITracker& s2 = SectionTracker::acquire( ctx, "S2" ); REQUIRE( s2.isOpen() ); @@ -269,7 +269,7 @@ TEST_CASE( "Tracker" ) { testCase.close(); REQUIRE( testCase.isComplete() == false ); - SECTION( "Re-enter for second generation" ) { + SECTION( "Re-enter for second generation", "" ) { ctx.startCycle(); ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" ); REQUIRE( testCase2.isOpen() ); From 52a417df7b3f5a52169004ad9138bc7fb5a1ddd2 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Mon, 2 Nov 2015 19:21:46 +0000 Subject: [PATCH 14/18] Fitted new section tracking --- include/internal/catch_run_context.hpp | 45 +++++++++++++++----- include/internal/catch_test_case_tracker.hpp | 4 ++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index 5e315f96..c607b432 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -70,6 +70,7 @@ namespace Catch { m_context.setConfig( m_config ); m_context.setResultCapture( this ); m_reporter->testRunStarting( m_runInfo ); + m_trackerContext.startRun(); } virtual ~RunContext() { @@ -94,14 +95,17 @@ namespace Catch { m_reporter->testCaseStarting( testInfo ); m_activeTestCase = &testCase; - m_testCaseTracker = TestCaseTracker( testInfo.name ); + do { do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name ); runCurrentTest( redirectedCout, redirectedCerr ); } - while( !m_testCaseTracker->isCompleted() && !aborting() ); + while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); } + // !TBD: deprecated while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); Totals deltaTotals = m_totals.delta( prevTotals ); @@ -113,7 +117,7 @@ namespace Catch { aborting() ) ); m_activeTestCase = CATCH_NULL; - m_testCaseTracker.reset(); + m_testCaseTracker = CATCH_NULL; return deltaTotals; } @@ -149,9 +153,11 @@ namespace Catch { std::ostringstream oss; oss << sectionInfo.name << "@" << sectionInfo.lineInfo; - if( !m_testCaseTracker->enterSection( oss.str() ) ) + ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() ); + if( !sectionTracker.isOpen() ) return false; - + m_activeSections.push_back( §ionTracker ); + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_reporter->sectionStarting( sectionInfo ); @@ -161,9 +167,11 @@ namespace Catch { return true; } bool testForMissingAssertions( Counts& assertions ) { - if( assertions.total() != 0 || - !m_config->warnAboutMissingAssertions() || - m_testCaseTracker->currentSectionHasChildren() ) + if( assertions.total() != 0 ) + return false; + if( m_config->warnAboutMissingAssertions() ) + return false; + if( m_trackerContext.currentTracker().hasChildren() ) return false; m_totals.assertions.failed++; assertions.failed++; @@ -174,13 +182,22 @@ namespace Catch { Counts assertions = m_totals.assertions - endInfo.prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); - m_testCaseTracker->leaveSection(); + if( !m_activeSections.empty() ) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); m_messages.clear(); } virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { + if( m_unfinishedSections.empty() ) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + m_unfinishedSections.push_back( endInfo ); } @@ -249,7 +266,7 @@ namespace Catch { double duration = 0; try { m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); - TestCaseTracker::Guard guard( *m_testCaseTracker ); +// TestCaseTracker::Guard guard( *m_testCaseTracker ); seedRng( *m_config ); @@ -267,10 +284,13 @@ namespace Catch { } catch( TestFailureException& ) { // This just means the test was aborted due to failure +// m_testCaseTracker->fail(); } catch(...) { makeUnexpectedResultBuilder().useActiveException(); +// m_testCaseTracker->fail(); } + m_testCaseTracker->close(); handleUnfinishedSections(); m_messages.clear(); @@ -316,7 +336,8 @@ namespace Catch { TestRunInfo m_runInfo; IMutableContext& m_context; TestCase const* m_activeTestCase; - Option m_testCaseTracker; + ITracker* m_testCaseTracker; + ITracker* m_currentSectionTracker; AssertionResult m_lastResult; Ptr m_config; @@ -325,6 +346,8 @@ namespace Catch { std::vector m_messages; AssertionInfo m_lastAssertionInfo; std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; }; IResultCapture& getResultCapture() { diff --git a/include/internal/catch_test_case_tracker.hpp b/include/internal/catch_test_case_tracker.hpp index 4f174fb6..0bb82dbf 100644 --- a/include/internal/catch_test_case_tracker.hpp +++ b/include/internal/catch_test_case_tracker.hpp @@ -29,6 +29,7 @@ namespace TestCaseTracking { virtual bool isComplete() const = 0; // Successfully completed or failed virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; virtual ITracker& parent() = 0; @@ -139,6 +140,9 @@ namespace TestCaseTracking { virtual bool isOpen() const CATCH_OVERRIDE { return m_runState != NotStarted && !isComplete(); } + virtual bool hasChildren() const CATCH_OVERRIDE { + return !m_children.empty(); + } virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { From aa49823bc07cf2422866454fd04de20a47ce620f Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 3 Nov 2015 07:29:23 +0000 Subject: [PATCH 15/18] perform startRun() at the start of each test case --- include/internal/catch_run_context.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index c607b432..7a93af0d 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -70,7 +70,6 @@ namespace Catch { m_context.setConfig( m_config ); m_context.setResultCapture( this ); m_reporter->testRunStarting( m_runInfo ); - m_trackerContext.startRun(); } virtual ~RunContext() { @@ -98,6 +97,7 @@ namespace Catch { do { + m_trackerContext.startRun(); do { m_trackerContext.startCycle(); m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name ); From 471bd2556a597f54a120b8382215296e3473f95d Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 3 Nov 2015 07:33:43 +0000 Subject: [PATCH 16/18] Approved changes due to "No assertions" warnings now firing correctly on inner sections --- .../Baselines/console.std.approved.txt | 76 +- .../Baselines/console.sw.approved.txt | 1159 ++++++++++++++-- .../SelfTest/Baselines/junit.sw.approved.txt | 21 +- .../SelfTest/Baselines/xml.sw.approved.txt | 1188 ++++++++++++++++- 4 files changed, 2271 insertions(+), 173 deletions(-) diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt index dbaca8ba..6f0b0a2c 100644 --- a/projects/SelfTest/Baselines/console.std.approved.txt +++ b/projects/SelfTest/Baselines/console.std.approved.txt @@ -494,7 +494,27 @@ explicitly with message: Message from section two Message from section one +------------------------------------------------------------------------------- +Standard output from all sections is reported + one +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + + +No assertions in section 'one' + Message from section two +------------------------------------------------------------------------------- +Standard output from all sections is reported + two +------------------------------------------------------------------------------- +MessageTests.cpp: +............................................................................... + + +No assertions in section 'two' + ------------------------------------------------------------------------------- SCOPED_INFO is reset for each loop ------------------------------------------------------------------------------- @@ -558,6 +578,38 @@ MiscTests.cpp:: FAILED: with expansion: 1 == 2 +------------------------------------------------------------------------------- +even more nested SECTION tests + c + d (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + + +No assertions in section 'd (leaf)' + +------------------------------------------------------------------------------- +even more nested SECTION tests + c + e (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + + +No assertions in section 'e (leaf)' + +------------------------------------------------------------------------------- +even more nested SECTION tests + f (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + + +No assertions in section 'f (leaf)' + ------------------------------------------------------------------------------- looped SECTION tests s1 @@ -652,6 +704,26 @@ MiscTests.cpp:: FAILED: with expansion: false +------------------------------------------------------------------------------- +xmlentitycheck + embedded xml +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + + +No assertions in section 'embedded xml' + +------------------------------------------------------------------------------- +xmlentitycheck + encoded chars +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + + +No assertions in section 'encoded chars' + ------------------------------------------------------------------------------- send a single char to INFO ------------------------------------------------------------------------------- @@ -797,6 +869,6 @@ with expansion: "first" == "second" =============================================================================== -test cases: 159 | 119 passed | 39 failed | 1 failed as expected -assertions: 788 | 695 passed | 80 failed | 13 failed as expected +test cases: 160 | 117 passed | 42 failed | 1 failed as expected +assertions: 927 | 827 passed | 87 failed | 13 failed as expected diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt index 82702ecf..2d07e380 100644 --- a/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/projects/SelfTest/Baselines/console.sw.approved.txt @@ -1216,15 +1216,6 @@ ExceptionTests.cpp:: FAILED: due to unexpected exception with message: expected exception -------------------------------------------------------------------------------- -When unchecked exceptions are thrown, but caught, they do not affect the test -------------------------------------------------------------------------------- -ExceptionTests.cpp: -............................................................................... - - -No assertions in test case 'When unchecked exceptions are thrown, but caught, they do not affect the test' - ------------------------------------------------------------------------------- Unexpected custom exceptions can be translated ------------------------------------------------------------------------------- @@ -2668,9 +2659,6 @@ warning: this is a message this is a warning - -No assertions in test case 'INFO and WARN do not abort tests' - ------------------------------------------------------------------------------- SUCCEED counts as a test pass ------------------------------------------------------------------------------- @@ -2782,27 +2770,7 @@ explicitly with message: Message from section two Message from section one -------------------------------------------------------------------------------- -Standard output from all sections is reported - one -------------------------------------------------------------------------------- -MessageTests.cpp: -............................................................................... - - -No assertions in section 'one' - Message from section two -------------------------------------------------------------------------------- -Standard output from all sections is reported - two -------------------------------------------------------------------------------- -MessageTests.cpp: -............................................................................... - - -No assertions in section 'two' - ------------------------------------------------------------------------------- SCOPED_INFO is reset for each loop ------------------------------------------------------------------------------- @@ -2917,18 +2885,6 @@ MessageTests.cpp:: FAILED - but was ok: CHECK_NOFAIL( 1 == 2 ) - -No assertions in test case 'The NO_FAIL macro reports a failure but does not fail the test' - -------------------------------------------------------------------------------- -just info -------------------------------------------------------------------------------- -MessageTests.cpp: -............................................................................... - - -No assertions in test case 'just info' - ------------------------------------------------------------------------------- just failure ------------------------------------------------------------------------------- @@ -2965,9 +2921,6 @@ MessageTests.cpp:: warning: toString(p): 0x - -No assertions in test case 'Pointers can be converted to strings' - ------------------------------------------------------------------------------- random SECTION tests s1 @@ -3047,36 +3000,32 @@ with expansion: 1 == 2 ------------------------------------------------------------------------------- -even more nested SECTION tests - c - d (leaf) +more nested SECTION tests + s1 + s3 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... - -No assertions in section 'd (leaf)' +MiscTests.cpp:: +PASSED: + REQUIRE( a != b ) +with expansion: + 1 != 2 ------------------------------------------------------------------------------- -even more nested SECTION tests - c - e (leaf) +more nested SECTION tests + s1 + s4 ------------------------------------------------------------------------------- MiscTests.cpp: ............................................................................... - -No assertions in section 'e (leaf)' - -------------------------------------------------------------------------------- -even more nested SECTION tests - f (leaf) -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'f (leaf)' +MiscTests.cpp:: +PASSED: + REQUIRE( a < b ) +with expansion: + 1 < 2 ------------------------------------------------------------------------------- looped SECTION tests @@ -3156,15 +3105,6 @@ with message: A string sent directly to stdout A string sent directly to stderr -------------------------------------------------------------------------------- -Sends stuff to stdout and stderr -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in test case 'Sends stuff to stdout and stderr' - ------------------------------------------------------------------------------- null strings ------------------------------------------------------------------------------- @@ -3251,26 +3191,6 @@ MiscTests.cpp:: FAILED: with expansion: false -------------------------------------------------------------------------------- -xmlentitycheck - embedded xml -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'embedded xml' - -------------------------------------------------------------------------------- -xmlentitycheck - encoded chars -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'encoded chars' - ------------------------------------------------------------------------------- send a single char to INFO ------------------------------------------------------------------------------- @@ -3462,15 +3382,6 @@ PASSED: with expansion: 3628800 (0x) == 3628800 (0x) -------------------------------------------------------------------------------- -An empty test with no assertions -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in test case 'An empty test with no assertions' - ------------------------------------------------------------------------------- Nice descriptive name ------------------------------------------------------------------------------- @@ -3481,27 +3392,6 @@ MiscTests.cpp:: warning: This one ran - -No assertions in test case 'Nice descriptive name' - -------------------------------------------------------------------------------- -first tag -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in test case 'first tag' - -------------------------------------------------------------------------------- -second tag -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in test case 'second tag' - ------------------------------------------------------------------------------- vectors can be sized and resized ------------------------------------------------------------------------------- @@ -4917,15 +4807,6 @@ with expansion: hello hello -------------------------------------------------------------------------------- -Strings can be rendered with colour -------------------------------------------------------------------------------- -TestMain.cpp: -............................................................................... - - -No assertions in test case 'Strings can be rendered with colour' - ------------------------------------------------------------------------------- Text can be formatted using the Text class ------------------------------------------------------------------------------- @@ -5983,9 +5864,6 @@ warning: Uncomment the code in this test to check that it gives a sensible compiler error - -No assertions in test case 'Where there is more to the expression after the RHS' - ------------------------------------------------------------------------------- Where the LHS is not a simple value ------------------------------------------------------------------------------- @@ -5997,9 +5875,6 @@ warning: Uncomment the code in this test to check that it gives a sensible compiler error - -No assertions in test case 'Where the LHS is not a simple value' - ------------------------------------------------------------------------------- A failing expression with a non streamable type is still captured ------------------------------------------------------------------------------- @@ -6464,6 +6339,1004 @@ with expansion: == "{ StringMaker }" +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + successfully close one section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isSuccessfullyCompleted() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + fail one section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + fail one section + re-enter after failed section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + fail one section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + fail one section + re-enter after failed section and find next section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 + Successfully close S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isSuccessfullyCompleted() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + successfully close one section, then find another + Re-enter - skips S1 and enters S2 + fail S2 +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( ctx.completedCycle() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1c.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2c.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isSuccessfullyCompleted() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + open a nested section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + start a generator +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + close outer section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + close outer section + Re-enter for second generation +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.index() == 1 ) +with expansion: + 1 == 1 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + start a generator +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Start a new inner section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Start a new inner section + Re-enter for second generation +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.index() == 1 ) +with expansion: + 1 == 1 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isOpen() ) +with expansion: + true + +------------------------------------------------------------------------------- +Tracker + start a generator +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Fail an inner section +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2.isSuccessfullyCompleted() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase.isComplete() == false ) +with expansion: + false == false + +------------------------------------------------------------------------------- +Tracker + start a generator + Fail an inner section + Re-enter for second generation +------------------------------------------------------------------------------- +PartTrackerTests.cpp: +............................................................................... + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.index() == 0 ) +with expansion: + 0 == 0 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2b.isOpen() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1b.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1b.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase2.isComplete() == false ) +with expansion: + false == false + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1c.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1c.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1c.index() == 1 ) +with expansion: + 1 == 1 + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2c.isOpen() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s2c.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( g1c.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( s1c.isComplete() ) +with expansion: + true + +PartTrackerTests.cpp:: +PASSED: + REQUIRE( testCase3.isComplete() ) +with expansion: + true + ------------------------------------------------------------------------------- std::pair -> toString ------------------------------------------------------------------------------- @@ -8170,6 +9043,6 @@ with expansion: true =============================================================================== -test cases: 159 | 103 passed | 55 failed | 1 failed as expected -assertions: 808 | 695 passed | 100 failed | 13 failed as expected +test cases: 160 | 120 passed | 39 failed | 1 failed as expected +assertions: 920 | 827 passed | 80 failed | 13 failed as expected diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt index 6c6e5208..94f59b8e 100644 --- a/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,5 +1,5 @@ - + @@ -341,6 +341,8 @@ MessageTests.cpp: MiscTests.cpp: + + MiscTests.cpp: @@ -566,6 +568,23 @@ TrickyTests.cpp: + + + + + + + + + + + + + + + + + diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt index 3d20d996..56695fe1 100644 --- a/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -1543,7 +1543,7 @@ - + @@ -2856,7 +2856,7 @@ this is a warning - + @@ -2949,12 +2949,12 @@
- +
- +
- +
@@ -3062,10 +3062,10 @@ 1 == 2 - + - + @@ -3097,7 +3097,7 @@ toString(p): 0x - +
@@ -3180,25 +3180,53 @@
+
+
+ + + a != b + + + 1 != 2 + + + +
+ +
+
+
+ + + a < b + + + 1 < 2 + + + +
+ +
- +
- +
- +
- +
- +
- +
@@ -3300,7 +3328,7 @@ - + @@ -3399,12 +3427,12 @@
- +
- +
- +
@@ -3606,19 +3634,19 @@ - + This one ran - + - + - + @@ -5140,7 +5168,7 @@ four" - + @@ -6191,13 +6219,13 @@ there" Uncomment the code in this test to check that it gives a sensible compiler error - + Uncomment the code in this test to check that it gives a sensible compiler error - + @@ -6617,6 +6645,1112 @@ there" + + + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s1.isSuccessfullyCompleted() + + + true + + + + + testCase.isComplete() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isSuccessfullyCompleted() + + + true + + + +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s1.isComplete() + + + true + + + + + s1.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isSuccessfullyCompleted() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isComplete() + + + true + + + + + testCase.isSuccessfullyCompleted() + + + true + + + +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s1.isComplete() + + + true + + + + + s1.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + + + + ctx.completedCycle() + + + true + + + + + testCase.isSuccessfullyCompleted() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + s2.isOpen() + + + true + + + + + ctx.completedCycle() + + + true + + + + + testCase.isComplete() + + + true + + + + + testCase.isSuccessfullyCompleted() + + + true + + + +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s2.isOpen() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + s2b.isOpen() + + + true + + + + + ctx.completedCycle() == false + + + false == false + + +
+ + + ctx.completedCycle() + + + true + + + + + s2b.isSuccessfullyCompleted() + + + true + + + + + testCase2.isComplete() == false + + + false == false + + + + + testCase2.isSuccessfullyCompleted() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s2.isOpen() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() == false + + + false == false + + + + + s2b.isOpen() + + + true + + + + + ctx.completedCycle() == false + + + false == false + + +
+ + + ctx.completedCycle() + + + true + + + + + s2b.isComplete() + + + true + + + + + s2b.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase2.isSuccessfullyCompleted() == false + + + false == false + + + + + testCase3.isOpen() + + + true + + + + + s1c.isOpen() == false + + + false == false + + + + + s2c.isOpen() == false + + + false == false + + + + + testCase3.isSuccessfullyCompleted() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + s2.isOpen() + + + true + + + + + s2.isComplete() + + + true + + + + + s1.isComplete() == false + + + false == false + + + + + s1.isComplete() + + + true + + + + + testCase.isComplete() == false + + + false == false + + + + + testCase.isComplete() + + + true + + + +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + g1.isOpen() + + + true + + + + + g1.index() == 0 + + + 0 == 0 + + + + + g1.isComplete() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + +
+ + + s1.isComplete() == false + + + false == false + + + + + testCase.isSuccessfullyCompleted() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() + + + true + + + + + g1b.isOpen() + + + true + + + + + g1b.index() == 1 + + + 1 == 1 + + + + + s1.isComplete() == false + + + false == false + + + + + s1b.isComplete() + + + true + + + + + g1b.isComplete() + + + true + + + + + testCase2.isComplete() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + g1.isOpen() + + + true + + + + + g1.index() == 0 + + + 0 == 0 + + + + + g1.isComplete() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + +
+ + + s2.isOpen() + + + true + + + + + s2.isComplete() + + + true + + + + + s1.isComplete() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() + + + true + + + + + g1b.isOpen() + + + true + + + + + g1b.index() == 1 + + + 1 == 1 + + + + + s2b.isOpen() + + + true + + + + + s2b.isComplete() + + + true + + + + + g1b.isComplete() + + + true + + + + + s1b.isComplete() + + + true + + + + + testCase2.isComplete() + + + true + + + +
+ +
+ +
+ + + testCase.isOpen() + + + true + + + + + s1.isOpen() + + + true + + +
+ + + g1.isOpen() + + + true + + + + + g1.index() == 0 + + + 0 == 0 + + + + + g1.isComplete() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + +
+ + + s2.isOpen() + + + true + + + + + s2.isComplete() + + + true + + + + + s2.isSuccessfullyCompleted() == false + + + false == false + + + + + s1.isComplete() == false + + + false == false + + + + + testCase.isComplete() == false + + + false == false + + +
+ + + testCase2.isOpen() + + + true + + + + + s1b.isOpen() + + + true + + + + + g1b.isOpen() + + + true + + + + + g1b.index() == 0 + + + 0 == 0 + + + + + s2b.isOpen() == false + + + false == false + + + + + g1b.isComplete() == false + + + false == false + + + + + s1b.isComplete() == false + + + false == false + + + + + testCase2.isComplete() == false + + + false == false + + + + + testCase3.isOpen() + + + true + + + + + s1c.isOpen() + + + true + + + + + g1c.isOpen() + + + true + + + + + g1c.index() == 1 + + + 1 == 1 + + + + + s2c.isOpen() + + + true + + + + + s2c.isComplete() + + + true + + + + + g1c.isComplete() + + + true + + + + + s1c.isComplete() + + + true + + + + + testCase3.isComplete() + + + true + + + +
+ +
+ +
+ +
@@ -8463,7 +9597,7 @@ there"
- +
- + From bc8840cbb86fe57155620695714eb3936b85244b Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 3 Nov 2015 07:38:14 +0000 Subject: [PATCH 17/18] Removed deprecated section tracking implementation and tests --- include/internal/catch_run_context.hpp | 5 +- include/internal/catch_test_case_tracker.hpp | 132 ------------- .../Baselines/console.std.approved.txt | 4 +- .../Baselines/console.sw.approved.txt | 176 +---------------- .../SelfTest/Baselines/junit.sw.approved.txt | 7 +- .../SelfTest/Baselines/xml.sw.approved.txt | 179 +----------------- projects/SelfTest/SectionTrackerTests.cpp | 114 ----------- .../CatchSelfTest.xcodeproj/project.pbxproj | 6 +- 8 files changed, 9 insertions(+), 614 deletions(-) delete mode 100644 projects/SelfTest/SectionTrackerTests.cpp diff --git a/include/internal/catch_run_context.hpp b/include/internal/catch_run_context.hpp index 7a93af0d..a3098b5f 100644 --- a/include/internal/catch_run_context.hpp +++ b/include/internal/catch_run_context.hpp @@ -105,7 +105,7 @@ namespace Catch { } while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); } - // !TBD: deprecated + // !TBD: deprecated - this will be replaced by indexed trackers while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); Totals deltaTotals = m_totals.delta( prevTotals ); @@ -266,7 +266,6 @@ namespace Catch { double duration = 0; try { m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); -// TestCaseTracker::Guard guard( *m_testCaseTracker ); seedRng( *m_config ); @@ -284,11 +283,9 @@ namespace Catch { } catch( TestFailureException& ) { // This just means the test was aborted due to failure -// m_testCaseTracker->fail(); } catch(...) { makeUnexpectedResultBuilder().useActiveException(); -// m_testCaseTracker->fail(); } m_testCaseTracker->close(); handleUnfinishedSections(); diff --git a/include/internal/catch_test_case_tracker.hpp b/include/internal/catch_test_case_tracker.hpp index 0bb82dbf..713ec96c 100644 --- a/include/internal/catch_test_case_tracker.hpp +++ b/include/internal/catch_test_case_tracker.hpp @@ -310,138 +310,6 @@ using TestCaseTracking::ITracker; using TestCaseTracking::TrackerContext; using TestCaseTracking::SectionTracker; using TestCaseTracking::IndexTracker; - -// !TBD: Deprecated -namespace SectionTracking { - - - class TrackedSection { - - typedef std::map TrackedSections; - - public: - enum RunState { - NotStarted, - Executing, - ExecutingChildren, - Completed - }; - - TrackedSection( std::string const& name, TrackedSection* parent ) - : m_name( name ), m_runState( NotStarted ), m_parent( parent ) - {} - - RunState runState() const { return m_runState; } - - TrackedSection* findChild( std::string const& childName ); - TrackedSection* acquireChild( std::string const& childName ); - - void enter() { - if( m_runState == NotStarted ) - m_runState = Executing; - } - void leave(); - - TrackedSection* getParent() { - return m_parent; - } - bool hasChildren() const { - return !m_children.empty(); - } - - private: - std::string m_name; - RunState m_runState; - TrackedSections m_children; - TrackedSection* m_parent; - }; - - inline TrackedSection* TrackedSection::findChild( std::string const& childName ) { - TrackedSections::iterator it = m_children.find( childName ); - return it != m_children.end() - ? &it->second - : CATCH_NULL; - } - inline TrackedSection* TrackedSection::acquireChild( std::string const& childName ) { - if( TrackedSection* child = findChild( childName ) ) - return child; - m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) ); - return findChild( childName ); - } - inline void TrackedSection::leave() { - for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end(); - it != itEnd; - ++it ) - if( it->second.runState() != Completed ) { - m_runState = ExecutingChildren; - return; - } - m_runState = Completed; - } - - class TestCaseTracker { - public: - TestCaseTracker( std::string const& testCaseName ) - : m_testCase( testCaseName, CATCH_NULL ), - m_currentSection( &m_testCase ), - m_completedASectionThisRun( false ) - {} - - bool enterSection( std::string const& name ) { - TrackedSection* child = m_currentSection->acquireChild( name ); - if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed ) - return false; - - m_currentSection = child; - m_currentSection->enter(); - return true; - } - void leaveSection() { - m_currentSection->leave(); - m_currentSection = m_currentSection->getParent(); - assert( m_currentSection != CATCH_NULL ); - m_completedASectionThisRun = true; - } - - bool currentSectionHasChildren() const { - return m_currentSection->hasChildren(); - } - bool isCompleted() const { - return m_testCase.runState() == TrackedSection::Completed; - } - - class Guard { - public: - Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) { - m_tracker.enterTestCase(); - } - ~Guard() { - m_tracker.leaveTestCase(); - } - private: - Guard( Guard const& ); - void operator = ( Guard const& ); - TestCaseTracker& m_tracker; - }; - - private: - void enterTestCase() { - m_currentSection = &m_testCase; - m_completedASectionThisRun = false; - m_testCase.enter(); - } - void leaveTestCase() { - m_testCase.leave(); - } - - TrackedSection m_testCase; - TrackedSection* m_currentSection; - bool m_completedASectionThisRun; - }; - -} // namespace SectionTracking - -using SectionTracking::TestCaseTracker; } // namespace Catch diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt index 6f0b0a2c..92c2624b 100644 --- a/projects/SelfTest/Baselines/console.std.approved.txt +++ b/projects/SelfTest/Baselines/console.std.approved.txt @@ -869,6 +869,6 @@ with expansion: "first" == "second" =============================================================================== -test cases: 160 | 117 passed | 42 failed | 1 failed as expected -assertions: 927 | 827 passed | 87 failed | 13 failed as expected +test cases: 159 | 116 passed | 42 failed | 1 failed as expected +assertions: 907 | 807 passed | 87 failed | 13 failed as expected diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt index 2d07e380..8e2ba564 100644 --- a/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/projects/SelfTest/Baselines/console.sw.approved.txt @@ -8870,179 +8870,7 @@ PASSED: with expansion: 1 > 0 -------------------------------------------------------------------------------- -section tracking -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -------------------------------------------------------------------------------- -section tracking - test case with no sections -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.isCompleted() ) -with expansion: - true - -------------------------------------------------------------------------------- -section tracking -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -------------------------------------------------------------------------------- -section tracking - test case with one section -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.enterSection( section1Name ) ) -with expansion: - true - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.isCompleted() ) -with expansion: - true - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.enterSection( section1Name ) ) -with expansion: - !false - -------------------------------------------------------------------------------- -section tracking -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -------------------------------------------------------------------------------- -section tracking - test case with two consecutive sections -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.enterSection( section1Name ) ) -with expansion: - true - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.enterSection( section2Name ) ) -with expansion: - !false - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.enterSection( section1Name ) ) -with expansion: - !false - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.enterSection( section2Name ) ) -with expansion: - true - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.isCompleted() ) -with expansion: - true - -------------------------------------------------------------------------------- -section tracking -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -------------------------------------------------------------------------------- -section tracking - test case with one section within another -------------------------------------------------------------------------------- -SectionTrackerTests.cpp: -............................................................................... - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.enterSection( section1Name ) ) -with expansion: - true - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.enterSection( section2Name ) ) -with expansion: - true - -SectionTrackerTests.cpp:: -PASSED: - CHECK_FALSE( testCaseTracker.isCompleted() ) -with expansion: - !false - -SectionTrackerTests.cpp:: -PASSED: - CHECK( testCaseTracker.isCompleted() ) -with expansion: - true - =============================================================================== -test cases: 160 | 120 passed | 39 failed | 1 failed as expected -assertions: 920 | 827 passed | 80 failed | 13 failed as expected +test cases: 159 | 119 passed | 39 failed | 1 failed as expected +assertions: 900 | 807 passed | 80 failed | 13 failed as expected diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt index 94f59b8e..a7ad8583 100644 --- a/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,5 +1,5 @@ - + @@ -644,11 +644,6 @@ TrickyTests.cpp: - - - - - Message from section one Message from section two diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt index 56695fe1..a11f61b4 100644 --- a/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -9422,182 +9422,7 @@ there" - - - - !testCaseTracker.isCompleted() - - - !false - - -
- - - !testCaseTracker.isCompleted() - - - !false - - - - - testCaseTracker.isCompleted() - - - true - - - -
- - - !testCaseTracker.isCompleted() - - - !false - - -
- - - testCaseTracker.enterSection( section1Name ) - - - true - - - - - !testCaseTracker.isCompleted() - - - !false - - - - - testCaseTracker.isCompleted() - - - true - - - - - !testCaseTracker.enterSection( section1Name ) - - - !false - - - -
- - - !testCaseTracker.isCompleted() - - - !false - - -
- - - testCaseTracker.enterSection( section1Name ) - - - true - - - - - !testCaseTracker.enterSection( section2Name ) - - - !false - - - - - !testCaseTracker.isCompleted() - - - !false - - - - - !testCaseTracker.enterSection( section1Name ) - - - !false - - - - - testCaseTracker.enterSection( section2Name ) - - - true - - - - - testCaseTracker.isCompleted() - - - true - - - -
- - - !testCaseTracker.isCompleted() - - - !false - - -
- - - testCaseTracker.enterSection( section1Name ) - - - true - - - - - testCaseTracker.enterSection( section2Name ) - - - true - - - - - !testCaseTracker.isCompleted() - - - !false - - - - - testCaseTracker.isCompleted() - - - true - - - -
- -
- +
- + diff --git a/projects/SelfTest/SectionTrackerTests.cpp b/projects/SelfTest/SectionTrackerTests.cpp deleted file mode 100644 index d3df994d..00000000 --- a/projects/SelfTest/SectionTrackerTests.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Created by Phil on 20/07/2013. - * Copyright 2013 Two Blue Cubes Ltd - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ - -#include "internal/catch_suppress_warnings.h" -#include "internal/catch_test_case_tracker.hpp" - -#include "catch.hpp" - -TEST_CASE( "section tracking", "" ) { - - using namespace Catch; - TestCaseTracker testCaseTracker( "test case" ); - - const std::string section1Name = "section 1"; - const std::string section2Name = "section 2"; - - CHECK_FALSE( testCaseTracker.isCompleted() ); - - SECTION( "test case with no sections", "" ) { - - { - TestCaseTracker::Guard guard( testCaseTracker ); - CHECK_FALSE( testCaseTracker.isCompleted() ); - } - CHECK( testCaseTracker.isCompleted() ); - } - - SECTION( "test case with one section", "" ) { - - { - TestCaseTracker::Guard guard( testCaseTracker ); - - // Enter section? - yes - CHECK( testCaseTracker.enterSection( section1Name ) ); - CHECK_FALSE( testCaseTracker.isCompleted() ); - testCaseTracker.leaveSection(); - - // Leave test case - now complete - } - CHECK( testCaseTracker.isCompleted() ); - - // ... - - // Enter test case again - { - TestCaseTracker::Guard guard( testCaseTracker ); - - // Enter section? - no - now complete - CHECK_FALSE( testCaseTracker.enterSection( section1Name ) ); - } - } - - SECTION( "test case with two consecutive sections", "" ) { - - // Enter test case - { - TestCaseTracker::Guard guard( testCaseTracker ); - - // Enter section 1? - yes - CHECK( testCaseTracker.enterSection( section1Name ) ); - testCaseTracker.leaveSection(); - - // Enter section 2? - no - we just exected section 1 - CHECK_FALSE( testCaseTracker.enterSection( section2Name ) ); - - // Leave test case - incomplete (still need to visit section 2) - } - CHECK_FALSE( testCaseTracker.isCompleted() ); - - // ... - - // Enter test case again - { - TestCaseTracker::Guard guard( testCaseTracker ); - - // Enter section 1? - no, already done now - CHECK_FALSE( testCaseTracker.enterSection( section1Name ) ); - - // Enter section 2? - yes - CHECK( testCaseTracker.enterSection( section2Name ) ); - testCaseTracker.leaveSection(); - - // Leave test case - now complete - } - CHECK( testCaseTracker.isCompleted() ); - } - - SECTION( "test case with one section within another", "" ) { - - // Enter test case again - { - TestCaseTracker::Guard guard( testCaseTracker ); - - // Enter section 1? - yes - CHECK( testCaseTracker.enterSection( section1Name ) ); - - // Enter section 2? - yes - CHECK( testCaseTracker.enterSection( section2Name ) ); - - CHECK_FALSE( testCaseTracker.isCompleted() ); - - testCaseTracker.leaveSection(); // section 2 - testCaseTracker.leaveSection(); // section 1 - - // Leave test case - now complete - } - CHECK( testCaseTracker.isCompleted() ); - } -} diff --git a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj index 5ec14365..8947e38e 100644 --- a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj +++ b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */; settings = {ASSET_TAGS = (); }; }; + 26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */; }; 263F7A4719B6FCBF009474C2 /* EnumToString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */; }; 263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */; }; 263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */; }; @@ -18,7 +18,6 @@ 26711C8F195D465C0033EDA2 /* TagAliasTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */; }; 26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26847E5D16BBADB40043B9C1 /* catch_message.cpp */; }; 2691574C1A532A280054F1ED /* ToStringTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2691574B1A532A280054F1ED /* ToStringTuple.cpp */; }; - 26948286179A9AB900ED166E /* SectionTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26948284179A9AB900ED166E /* SectionTrackerTests.cpp */; }; 2694A1FD16A0000E004816E3 /* catch_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2694A1FB16A0000E004816E3 /* catch_text.cpp */; }; 26E1B7D319213BC900812682 /* CmdLineTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E1B7D119213BC900812682 /* CmdLineTests.cpp */; }; 4A45DA2416161EF9004F8D6B /* catch_console_colour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */; }; @@ -102,7 +101,6 @@ 2691574B1A532A280054F1ED /* ToStringTuple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringTuple.cpp; path = ../../../SelfTest/ToStringTuple.cpp; sourceTree = ""; }; 26926E8318D7777D004E10F2 /* clara.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = clara.h; path = ../../../../include/external/clara.h; sourceTree = ""; }; 26926E8418D77809004E10F2 /* tbc_text_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tbc_text_format.h; path = ../../../../include/external/tbc_text_format.h; sourceTree = ""; }; - 26948284179A9AB900ED166E /* SectionTrackerTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SectionTrackerTests.cpp; path = ../../../SelfTest/SectionTrackerTests.cpp; sourceTree = ""; }; 26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_case_tracker.hpp; sourceTree = ""; }; 2694A1FB16A0000E004816E3 /* catch_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = catch_text.cpp; sourceTree = ""; }; 269831E519078C1600BB0CE0 /* catch_tostring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_tostring.h; sourceTree = ""; }; @@ -215,7 +213,6 @@ isa = PBXGroup; children = ( 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */, - 26948284179A9AB900ED166E /* SectionTrackerTests.cpp */, 26E1B7D119213BC900812682 /* CmdLineTests.cpp */, 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */, ); @@ -578,7 +575,6 @@ 26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */, 266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */, 266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */, - 26948286179A9AB900ED166E /* SectionTrackerTests.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 015e07100eebdf0557fbd08154e6adc1cf128ae2 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 3 Nov 2015 07:46:37 +0000 Subject: [PATCH 18/18] Added SUCCEEDs to empty leaf sections to avoid failing due to no assertions --- .../Baselines/console.std.approved.txt | 56 +------------------ .../Baselines/console.sw.approved.txt | 54 +++++++++++++++++- .../SelfTest/Baselines/junit.sw.approved.txt | 7 ++- .../SelfTest/Baselines/xml.sw.approved.txt | 18 +++--- projects/SelfTest/MiscTests.cpp | 7 ++- 5 files changed, 75 insertions(+), 67 deletions(-) diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt index 92c2624b..ad144d77 100644 --- a/projects/SelfTest/Baselines/console.std.approved.txt +++ b/projects/SelfTest/Baselines/console.std.approved.txt @@ -578,38 +578,6 @@ MiscTests.cpp:: FAILED: with expansion: 1 == 2 -------------------------------------------------------------------------------- -even more nested SECTION tests - c - d (leaf) -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'd (leaf)' - -------------------------------------------------------------------------------- -even more nested SECTION tests - c - e (leaf) -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'e (leaf)' - -------------------------------------------------------------------------------- -even more nested SECTION tests - f (leaf) -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'f (leaf)' - ------------------------------------------------------------------------------- looped SECTION tests s1 @@ -704,26 +672,6 @@ MiscTests.cpp:: FAILED: with expansion: false -------------------------------------------------------------------------------- -xmlentitycheck - embedded xml -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'embedded xml' - -------------------------------------------------------------------------------- -xmlentitycheck - encoded chars -------------------------------------------------------------------------------- -MiscTests.cpp: -............................................................................... - - -No assertions in section 'encoded chars' - ------------------------------------------------------------------------------- send a single char to INFO ------------------------------------------------------------------------------- @@ -869,6 +817,6 @@ with expansion: "first" == "second" =============================================================================== -test cases: 159 | 116 passed | 42 failed | 1 failed as expected -assertions: 907 | 807 passed | 87 failed | 13 failed as expected +test cases: 159 | 118 passed | 40 failed | 1 failed as expected +assertions: 907 | 812 passed | 82 failed | 13 failed as expected diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt index 8e2ba564..5fb53373 100644 --- a/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/projects/SelfTest/Baselines/console.sw.approved.txt @@ -3027,6 +3027,38 @@ PASSED: with expansion: 1 < 2 +------------------------------------------------------------------------------- +even more nested SECTION tests + c + d (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +even more nested SECTION tests + c + e (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +even more nested SECTION tests + f (leaf) +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + ------------------------------------------------------------------------------- looped SECTION tests s1 @@ -3191,6 +3223,26 @@ MiscTests.cpp:: FAILED: with expansion: false +------------------------------------------------------------------------------- +xmlentitycheck + embedded xml +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + +------------------------------------------------------------------------------- +xmlentitycheck + encoded chars +------------------------------------------------------------------------------- +MiscTests.cpp: +............................................................................... + +MiscTests.cpp:: +PASSED: + ------------------------------------------------------------------------------- send a single char to INFO ------------------------------------------------------------------------------- @@ -8872,5 +8924,5 @@ with expansion: =============================================================================== test cases: 159 | 119 passed | 39 failed | 1 failed as expected -assertions: 900 | 807 passed | 80 failed | 13 failed as expected +assertions: 905 | 812 passed | 80 failed | 13 failed as expected diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt index a7ad8583..40447d11 100644 --- a/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,5 +1,5 @@ - + @@ -343,6 +343,9 @@ MiscTests.cpp: + + + MiscTests.cpp: @@ -401,6 +404,8 @@ MiscTests.cpp: MiscTests.cpp: + + 3 diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt index a11f61b4..ebe5c69b 100644 --- a/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -3213,18 +3213,18 @@
- +
- +
- +
- +
- +
@@ -3427,10 +3427,10 @@
- +
- +
@@ -9422,7 +9422,7 @@ there"
- +
- + diff --git a/projects/SelfTest/MiscTests.cpp b/projects/SelfTest/MiscTests.cpp index 36b8a608..e791cb10 100644 --- a/projects/SelfTest/MiscTests.cpp +++ b/projects/SelfTest/MiscTests.cpp @@ -80,15 +80,18 @@ TEST_CASE( "even more nested SECTION tests", "[sections]" ) { SECTION( "d (leaf)", "" ) { + SUCCEED(""); // avoid failing due to no tests } SECTION( "e (leaf)", "" ) { + SUCCEED(""); // avoid failing due to no tests } } SECTION( "f (leaf)", "" ) { + SUCCEED(""); // avoid failing due to no tests } } @@ -177,11 +180,11 @@ TEST_CASE( "xmlentitycheck", "" ) { SECTION( "embedded xml", "it should be possible to embed xml characters, such as <, \" or &, or even whole documents within an attribute" ) { - // No test + SUCCEED(""); // We need this here to stop it failing due to no tests } SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" ) { - // No test + SUCCEED(""); // We need this here to stop it failing due to no tests } }