mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-26 15:26:11 +01:00
Moved all new tracking impl into catch_test_case_tracker.pp
This commit is contained in:
parent
3deb3e010f
commit
b8515929b8
@ -155,7 +155,6 @@ namespace Catch {
|
|||||||
TestSpec m_testSpec;
|
TestSpec m_testSpec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Catch
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "catch_tostring.hpp"
|
#include "catch_tostring.hpp"
|
||||||
#include "catch_result_builder.hpp"
|
#include "catch_result_builder.hpp"
|
||||||
#include "catch_tag_alias_registry.hpp"
|
#include "catch_tag_alias_registry.hpp"
|
||||||
|
#include "catch_test_case_tracker.hpp"
|
||||||
|
|
||||||
#include "../reporters/catch_reporter_multi.hpp"
|
#include "../reporters/catch_reporter_multi.hpp"
|
||||||
#include "../reporters/catch_reporter_xml.hpp"
|
#include "../reporters/catch_reporter_xml.hpp"
|
||||||
@ -43,6 +44,8 @@
|
|||||||
#include "../reporters/catch_reporter_compact.hpp"
|
#include "../reporters/catch_reporter_compact.hpp"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
// These are all here to avoid warnings about not having any out of line
|
||||||
|
// virtual methods
|
||||||
NonCopyable::~NonCopyable() {}
|
NonCopyable::~NonCopyable() {}
|
||||||
IShared::~IShared() {}
|
IShared::~IShared() {}
|
||||||
IStream::~IStream() CATCH_NOEXCEPT {}
|
IStream::~IStream() CATCH_NOEXCEPT {}
|
||||||
@ -91,6 +94,13 @@ namespace Catch {
|
|||||||
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
|
||||||
|
|
||||||
void Config::dummy() {}
|
void Config::dummy() {}
|
||||||
|
|
||||||
|
namespace TestCaseTracking {
|
||||||
|
ITracker::~ITracker() {}
|
||||||
|
TrackerBase::~TrackerBase() {}
|
||||||
|
SectionTracker::~SectionTracker() {}
|
||||||
|
IndexTracker::~IndexTracker() {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
# pragma clang diagnostic ignored "-Wc++98-compat"
|
||||||
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
|
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
|
||||||
# pragma clang diagnostic ignored "-Wswitch-enum"
|
# pragma clang diagnostic ignored "-Wswitch-enum"
|
||||||
|
# pragma clang diagnostic ignored "-Wcovered-switch-default"
|
||||||
# endif
|
# endif
|
||||||
#elif defined __GNUC__
|
#elif defined __GNUC__
|
||||||
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||||
|
@ -9,14 +9,308 @@
|
|||||||
#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
|
||||||
|
|
||||||
#include "catch_compiler_capabilities.h"
|
#include "catch_compiler_capabilities.h"
|
||||||
|
#include "catch_ptr.hpp"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Catch {
|
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<ITracker> const& child ) = 0;
|
||||||
|
virtual ITracker* findChild( std::string const& name ) = 0;
|
||||||
|
virtual void openChild() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TrackerContext {
|
||||||
|
|
||||||
|
enum RunState {
|
||||||
|
NotStarted,
|
||||||
|
Executing,
|
||||||
|
CompletedCycle
|
||||||
|
};
|
||||||
|
|
||||||
|
Ptr<ITracker> 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<ITracker> const& tracker ) {
|
||||||
|
return tracker->name() == m_name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typedef std::vector<Ptr<ITracker> > 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<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;
|
||||||
|
}
|
||||||
|
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<SectionTracker*>( 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<IndexTracker*>( 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 {
|
namespace SectionTracking {
|
||||||
|
|
||||||
|
|
||||||
class TrackedSection {
|
class TrackedSection {
|
||||||
|
|
||||||
typedef std::map<std::string, TrackedSection> TrackedSections;
|
typedef std::map<std::string, TrackedSection> TrackedSections;
|
||||||
|
@ -6,302 +6,11 @@
|
|||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
* 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_suppress_warnings.h"
|
||||||
#include "internal/catch_compiler_capabilities.h"
|
#include "internal/catch_test_case_tracker.hpp"
|
||||||
#include "internal/catch_ptr.hpp"
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
//# pragma clang diagnostic ignored "-Wpadded"
|
|
||||||
//# pragma clang diagnostic ignored "-Wc++98-compat"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Catch
|
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<ITracker> const& child ) = 0;
|
|
||||||
virtual ITracker* findChild( std::string const& name ) = 0;
|
|
||||||
virtual void openChild() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class TrackerContext {
|
|
||||||
|
|
||||||
enum RunState {
|
|
||||||
NotStarted,
|
|
||||||
Executing,
|
|
||||||
CompletedCycle
|
|
||||||
};
|
|
||||||
|
|
||||||
Ptr<ITracker> 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<ITracker> const& tracker ) {
|
|
||||||
return tracker->name() == m_name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
typedef std::vector<Ptr<ITracker> > 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<ITracker> 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<SectionTracker*>( 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<IndexTracker*>( 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 {
|
class LocalContext {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -322,10 +31,10 @@ inline Catch::TrackerContext& C_A_T_C_H_Context() {
|
|||||||
|
|
||||||
using namespace Catch;
|
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 );
|
// REQUIRE( C_A_T_C_H_Context().i() == 42 );
|
||||||
}
|
//}
|
||||||
|
|
||||||
TEST_CASE( "Tracker" ) {
|
TEST_CASE( "Tracker" ) {
|
||||||
|
|
||||||
|
@ -6,11 +6,7 @@
|
|||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __clang__
|
#include "internal/catch_suppress_warnings.h"
|
||||||
# pragma clang diagnostic ignored "-Wpadded"
|
|
||||||
# pragma clang diagnostic ignored "-Wc++98-compat"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "internal/catch_test_case_tracker.hpp"
|
#include "internal/catch_test_case_tracker.hpp"
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
Loading…
Reference in New Issue
Block a user