Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/single_include
diff options
context:
space:
mode:
authorPhil Nash2015-11-03 08:00:43 +0000
committerPhil Nash2015-11-03 08:01:27 +0000
commit7e34619f03a85eb24994166bbdf1e2039ab2fd57 (patch)
tree465a62ff370237f7fc5c93032978d7557a86e242 /single_include
parent4636be974492e2971e5c14940516e72e63ece95d (diff)
downloadcatch3-1.2.1-develop.15.tar.gz
v1.2.1-develop.15v1.2.1-develop.15
- includes all new section tracker
Diffstat (limited to 'single_include')
-rw-r--r--single_include/catch.hpp608
1 files changed, 399 insertions, 209 deletions
diff --git a/single_include/catch.hpp b/single_include/catch.hpp
index faaef35e..4ba0d193 100644
--- a/single_include/catch.hpp
+++ b/single_include/catch.hpp
@@ -1,6 +1,6 @@
/*
- * Catch v1.2.1-develop.14
- * Generated: 2015-09-27 03:27:04.922060
+ * Catch v1.2.1-develop.15
+ * Generated: 2015-11-03 08:00:19.120246
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@@ -35,6 +35,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"
@@ -3287,28 +3288,59 @@ namespace Catch {
// #included from: catch_stream.h
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
-#include <streambuf>
+// #included from: catch_streambuf.h
+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
+#include <streambuf>
namespace Catch {
- class Stream {
+ class StreamBufBase : public std::streambuf {
public:
- Stream();
- Stream( std::streambuf* _streamBuf, bool _isOwned );
- void release();
+ virtual ~StreamBufBase() CATCH_NOEXCEPT;
+ };
+}
- std::streambuf* streamBuf;
+#include <streambuf>
+#include <ostream>
+#include <fstream>
- private:
- bool isOwned;
- };
+namespace Catch {
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<StreamBufBase> m_streamBuf;
+ mutable std::ostream m_os;
+ public:
+ DebugOutStream();
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
}
#include <memory>
@@ -3382,12 +3414,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() );
@@ -3398,12 +3429,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 {
@@ -3419,17 +3444,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<std::string> getReporterNames() const { return m_data.reporterNames; }
int abortAfter() const { return m_data.abortAfter; }
@@ -3441,7 +3455,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; }
@@ -3451,10 +3465,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<IStream const> m_stream;
TestSpec m_testSpec;
};
@@ -4726,18 +4752,18 @@ namespace Catch {
namespace Catch
{
struct ReporterConfig {
- explicit ReporterConfig( Ptr<IConfig> const& _fullConfig )
+ explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
: m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
- ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream )
+ ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
: m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
std::ostream& stream() const { return *m_stream; }
- Ptr<IConfig> fullConfig() const { return m_fullConfig; }
+ Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
private:
std::ostream* m_stream;
- Ptr<IConfig> m_fullConfig;
+ Ptr<IConfig const> m_fullConfig;
};
struct ReporterPreferences {
@@ -4959,7 +4985,7 @@ namespace Catch
typedef std::vector<Ptr<IReporterFactory> > Listeners;
virtual ~IReporterRegistry();
- virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
virtual FactoryMap const& getFactories() const = 0;
virtual Listeners const& getListeners() const = 0;
};
@@ -5136,137 +5162,300 @@ namespace Catch {
#include <map>
#include <string>
#include <assert.h>
+#include <vector>
namespace Catch {
-namespace SectionTracking {
+namespace TestCaseTracking {
- class TrackedSection {
+ struct ITracker : SharedImpl<> {
+ virtual ~ITracker();
- typedef std::map<std::string, TrackedSection> TrackedSections;
+ // 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 bool hasChildren() const = 0;
+
+ virtual ITracker& parent() = 0;
+
+ // actions
+ virtual void close() = 0; // Successfully complete
+ virtual void fail() = 0;
+ virtual void markAsNeedingAnotherRun() = 0;
+
+ virtual void addChild( Ptr<ITracker> const& child ) = 0;
+ virtual ITracker* findChild( std::string const& name ) = 0;
+ virtual void openChild() = 0;
+ };
+
+ class TrackerContext {
- public:
enum RunState {
NotStarted,
Executing,
- ExecutingChildren,
- Completed
+ CompletedCycle
};
- TrackedSection( std::string const& name, TrackedSection* parent )
- : m_name( name ), m_runState( NotStarted ), m_parent( parent )
- {}
+ Ptr<ITracker> m_rootTracker;
+ ITracker* m_currentTracker;
+ RunState m_runState;
- RunState runState() const { return m_runState; }
+ public:
- TrackedSection* findChild( std::string const& childName );
- TrackedSection* acquireChild( std::string const& childName );
+ static TrackerContext& instance() {
+ static TrackerContext s_instance;
+ return s_instance;
+ }
- void enter() {
- if( m_runState == NotStarted )
- m_runState = Executing;
+ TrackerContext()
+ : m_currentTracker( CATCH_NULL ),
+ m_runState( NotStarted )
+ {}
+
+ ITracker& startRun();
+
+ void endRun() {
+ m_rootTracker.reset();
+ m_currentTracker = CATCH_NULL;
+ m_runState = NotStarted;
}
- void leave();
- TrackedSection* getParent() {
- return m_parent;
+ void startCycle() {
+ m_currentTracker = m_rootTracker.get();
+ m_runState = Executing;
}
- bool hasChildren() const {
- return !m_children.empty();
+ void completeCycle() {
+ m_runState = CompletedCycle;
}
- private:
- std::string m_name;
- RunState m_runState;
- TrackedSections m_children;
- TrackedSection* m_parent;
+ bool completedCycle() const {
+ return m_runState == CompletedCycle;
+ }
+ ITracker& currentTracker() {
+ return *m_currentTracker;
+ }
+ void setCurrentTracker( ITracker* tracker ) {
+ m_currentTracker = tracker;
+ }
};
- 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;
+ 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<ITracker> const& tracker ) {
+ return tracker->name() == m_name;
}
- m_runState = Completed;
- }
-
- class TestCaseTracker {
+ };
+ typedef std::vector<Ptr<ITracker> > Children;
+ std::string m_name;
+ TrackerContext& m_ctx;
+ ITracker* m_parent;
+ Children m_children;
+ CycleState m_runState;
public:
- TestCaseTracker( std::string const& testCaseName )
- : m_testCase( testCaseName, CATCH_NULL ),
- m_currentSection( &m_testCase ),
- m_completedASectionThisRun( false )
+ TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
+ : m_name( name ),
+ m_ctx( ctx ),
+ m_parent( parent ),
+ m_runState( NotStarted )
{}
+ virtual ~TrackerBase();
- bool enterSection( std::string const& name ) {
- TrackedSection* child = m_currentSection->acquireChild( name );
- if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed )
- return false;
+ 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 bool hasChildren() const CATCH_OVERRIDE {
+ return !m_children.empty();
+ }
- m_currentSection = child;
- m_currentSection->enter();
- return true;
+ virtual void addChild( Ptr<ITracker> 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;
}
- void leaveSection() {
- m_currentSection->leave();
- m_currentSection = m_currentSection->getParent();
- assert( m_currentSection != CATCH_NULL );
- m_completedASectionThisRun = true;
+ virtual ITracker& parent() CATCH_OVERRIDE {
+ assert( m_parent ); // Should always be non-null except for root
+ return *m_parent;
}
- bool currentSectionHasChildren() const {
- return m_currentSection->hasChildren();
+ virtual void openChild() CATCH_OVERRIDE {
+ if( m_runState != ExecutingChildren ) {
+ m_runState = ExecutingChildren;
+ if( m_parent )
+ m_parent->openChild();
+ }
}
- bool isCompleted() const {
- return m_testCase.runState() == TrackedSection::Completed;
+ void open() {
+ m_runState = Executing;
+ moveToThis();
+ if( m_parent )
+ m_parent->openChild();
}
- class Guard {
- public:
- Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) {
- m_tracker.enterTestCase();
+ 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" );
}
- ~Guard() {
- m_tracker.leaveTestCase();
+ 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<SectionTracker*>( childTracker );
+ assert( section );
}
- private:
- Guard( Guard const& );
- void operator = ( Guard const& );
- TestCaseTracker& m_tracker;
- };
+ else {
+ section = new SectionTracker( name, ctx, &currentTracker );
+ currentTracker.addChild( section );
+ }
+ if( !ctx.completedCycle() && !section->isComplete() ) {
- private:
- void enterTestCase() {
- m_currentSection = &m_testCase;
- m_completedASectionThisRun = false;
- m_testCase.enter();
+ section->open();
+ }
+ return *section;
}
- void leaveTestCase() {
- m_testCase.leave();
+ };
+
+ 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<IndexTracker*>( childTracker );
+ assert( tracker );
+ }
+ else {
+ tracker = new IndexTracker( name, ctx, &currentTracker, size );
+ currentTracker.addChild( tracker );
+ }
+
+ if( !ctx.completedCycle() && !tracker->isComplete() ) {
+ if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+ tracker->moveNext();
+ tracker->open();
+ }
+
+ return *tracker;
}
- TrackedSection m_testCase;
- TrackedSection* m_currentSection;
- bool m_completedASectionThisRun;
+ 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;
+ }
};
-} // namespace SectionTracking
+ 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 SectionTracking::TestCaseTracker;
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+using TestCaseTracking::IndexTracker;
} // namespace Catch
@@ -5387,10 +5576,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 );
@@ -5400,10 +5586,6 @@ namespace Catch {
virtual ~RunContext() {
m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
- m_context.setRunner( m_prevRunner );
- m_context.setConfig( Ptr<IConfig const>() );
- m_context.setResultCapture( m_prevResultCapture );
- m_context.setConfig( m_prevConfig );
}
void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
@@ -5424,14 +5606,17 @@ namespace Catch {
m_reporter->testCaseStarting( testInfo );
m_activeTestCase = &testCase;
- m_testCaseTracker = TestCaseTracker( testInfo.name );
do {
+ m_trackerContext.startRun();
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 - this will be replaced by indexed trackers
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
Totals deltaTotals = m_totals.delta( prevTotals );
@@ -5443,7 +5628,7 @@ namespace Catch {
aborting() ) );
m_activeTestCase = CATCH_NULL;
- m_testCaseTracker.reset();
+ m_testCaseTracker = CATCH_NULL;
return deltaTotals;
}
@@ -5478,8 +5663,10 @@ 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( &sectionTracker );
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
@@ -5490,9 +5677,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++;
@@ -5503,13 +5692,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 );
}
@@ -5578,7 +5776,6 @@ namespace Catch {
double duration = 0;
try {
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
- TestCaseTracker::Guard guard( *m_testCaseTracker );
seedRng( *m_config );
@@ -5600,6 +5797,7 @@ namespace Catch {
catch(...) {
makeUnexpectedResultBuilder().useActiveException();
}
+ m_testCaseTracker->close();
handleUnfinishedSections();
m_messages.clear();
@@ -5645,18 +5843,18 @@ namespace Catch {
TestRunInfo m_runInfo;
IMutableContext& m_context;
TestCase const* m_activeTestCase;
- Option<TestCaseTracker> m_testCaseTracker;
+ ITracker* m_testCaseTracker;
+ ITracker* m_currentSectionTracker;
AssertionResult m_lastResult;
Ptr<IConfig const> m_config;
Totals m_totals;
Ptr<IStreamingReporter> m_reporter;
std::vector<MessageInfo> m_messages;
- IRunner* m_prevRunner;
- IResultCapture* m_prevResultCapture;
- Ptr<IConfig const> m_prevConfig;
AssertionInfo m_lastAssertionInfo;
std::vector<SectionEndInfo> m_unfinishedSections;
+ std::vector<ITracker*> m_activeSections;
+ TrackerContext m_trackerContext;
};
IResultCapture& getResultCapture() {
@@ -5726,7 +5924,7 @@ namespace Catch {
reporter = addReporter( reporter, createReporter( *it, config ) );
return reporter;
}
- Ptr<IStreamingReporter> addListeners( Ptr<IConfig> const& config, Ptr<IStreamingReporter> reporters ) {
+ Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
it != itEnd;
@@ -5735,27 +5933,14 @@ namespace Catch {
return reporters;
}
- void openStreamInto( Ptr<Config> 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<Config> const& config ) {
- std::ofstream ofs;
- openStreamInto( config, ofs );
+ Ptr<IConfig const> iconfig = config.get();
+
Ptr<IStreamingReporter> reporter = makeReporter( config );
- reporter = addListeners( config.get(), reporter );
+ reporter = addListeners( iconfig, reporter );
- RunContext context( config.get(), reporter );
+ RunContext context( iconfig, reporter );
Totals totals;
@@ -5765,17 +5950,17 @@ namespace Catch {
if( !testSpec.hasFilters() )
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
- std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *config );
+ std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
for( std::vector<TestCase>::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;
}
@@ -6094,7 +6279,7 @@ namespace Catch {
virtual ~ReporterRegistry() CATCH_OVERRIDE {}
- virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const CATCH_OVERRIDE {
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
FactoryMap::const_iterator it = m_factories.find( name );
if( it == m_factories.end() )
return CATCH_NULL;
@@ -6283,19 +6468,6 @@ namespace Catch {
// #included from: catch_stream.hpp
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
-// #included from: catch_streambuf.h
-#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
-
-#include <streambuf>
-
-namespace Catch {
-
- class StreamBufBase : public std::streambuf {
- public:
- virtual ~StreamBufBase() CATCH_NOEXCEPT;
- };
-}
-
#include <stdexcept>
#include <cstdio>
#include <iostream>
@@ -6340,6 +6512,19 @@ namespace Catch {
///////////////////////////////////////////////////////////////////////////
+ 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 ) {
@@ -6347,20 +6532,23 @@ namespace Catch {
}
};
- Stream::Stream()
- : streamBuf( CATCH_NULL ), isOwned( false )
+ DebugOutStream::DebugOutStream()
+ : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+ m_os( m_streamBuf.get() )
{}
- Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
- : streamBuf( _streamBuf ), isOwned( _isOwned )
+ 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() )
{}
- void Stream::release() {
- if( isOwned ) {
- delete streamBuf;
- streamBuf = CATCH_NULL;
- isOwned = false;
- }
+ std::ostream& CoutStream::stream() const {
+ return m_os;
}
#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
@@ -6455,14 +6643,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<OutputDebugWriter>, true );
-
- throw std::domain_error( "Unknown stream: " + streamName );
- }
-
void cleanUpContext() {
delete currentContext;
currentContext = CATCH_NULL;
@@ -7011,7 +7191,7 @@ namespace Catch {
return os;
}
- Version libraryVersion( 1, 2, 1, "develop", 14 );
+ Version libraryVersion( 1, 2, 1, "develop", 15 );
}
@@ -8076,7 +8256,7 @@ namespace Catch {
// It can optionally be overridden in the derived class.
}
- Ptr<IConfig> m_config;
+ Ptr<IConfig const> m_config;
std::ostream& stream;
LazyStat<TestRunInfo> currentTestRunInfo;
@@ -8214,7 +8394,7 @@ namespace Catch {
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
- Ptr<IConfig> m_config;
+ Ptr<IConfig const> m_config;
std::ostream& stream;
std::vector<AssertionStats> m_assertions;
std::vector<std::vector<Ptr<SectionNode> > > m_sections;
@@ -9689,8 +9869,11 @@ namespace Catch {
} // end namespace Catch
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 {}
StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
IContext::~IContext() {}
IResultCapture::~IResultCapture() {}
@@ -9736,6 +9919,13 @@ namespace Catch {
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
void Config::dummy() {}
+
+ namespace TestCaseTracking {
+ ITracker::~ITracker() {}
+ TrackerBase::~TrackerBase() {}
+ SectionTracker::~SectionTracker() {}
+ IndexTracker::~IndexTracker() {}
+ }
}
#ifdef __clang__