mirror of
https://github.com/catchorg/Catch2.git
synced 2025-06-01 01:18:02 +00:00
First cut of -c/—section option for running specific sections
This commit is contained in:
parent
4a04682e49
commit
e7bcbb35c0
6 changed files with 117 additions and 69 deletions
|
@ -19,11 +19,21 @@
|
|||
namespace Catch {
|
||||
namespace TestCaseTracking {
|
||||
|
||||
struct NameAndLocation {
|
||||
std::string name;
|
||||
SourceLineInfo location;
|
||||
|
||||
NameAndLocation( std::string const& _name, SourceLineInfo const& _location )
|
||||
: name( _name ),
|
||||
location( _location )
|
||||
{}
|
||||
};
|
||||
|
||||
struct ITracker : SharedImpl<> {
|
||||
virtual ~ITracker();
|
||||
|
||||
// static queries
|
||||
virtual std::string name() const = 0;
|
||||
virtual NameAndLocation const& nameAndLocation() const = 0;
|
||||
|
||||
// dynamic queries
|
||||
virtual bool isComplete() const = 0; // Successfully completed or failed
|
||||
|
@ -39,7 +49,7 @@ namespace TestCaseTracking {
|
|||
virtual void markAsNeedingAnotherRun() = 0;
|
||||
|
||||
virtual void addChild( Ptr<ITracker> const& child ) = 0;
|
||||
virtual ITracker* findChild( std::string const& name ) = 0;
|
||||
virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0;
|
||||
virtual void openChild() = 0;
|
||||
|
||||
// Debug/ checking
|
||||
|
@ -47,7 +57,7 @@ namespace TestCaseTracking {
|
|||
virtual bool isIndexTracker() const = 0;
|
||||
};
|
||||
|
||||
class TrackerContext {
|
||||
class TrackerContext {
|
||||
|
||||
enum RunState {
|
||||
NotStarted,
|
||||
|
@ -110,30 +120,32 @@ namespace TestCaseTracking {
|
|||
Failed
|
||||
};
|
||||
class TrackerHasName {
|
||||
std::string m_name;
|
||||
NameAndLocation m_nameAndLocation;
|
||||
public:
|
||||
TrackerHasName( std::string const& name ) : m_name( name ) {}
|
||||
TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {}
|
||||
bool operator ()( Ptr<ITracker> const& tracker ) {
|
||||
return tracker->name() == m_name;
|
||||
return
|
||||
tracker->nameAndLocation().name == m_nameAndLocation.name &&
|
||||
tracker->nameAndLocation().location == m_nameAndLocation.location;
|
||||
}
|
||||
};
|
||||
typedef std::vector<Ptr<ITracker> > Children;
|
||||
std::string m_name;
|
||||
NameAndLocation m_nameAndLocation;
|
||||
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 ),
|
||||
TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||
: m_nameAndLocation( nameAndLocation ),
|
||||
m_ctx( ctx ),
|
||||
m_parent( parent ),
|
||||
m_runState( NotStarted )
|
||||
{}
|
||||
virtual ~TrackerBase();
|
||||
|
||||
virtual std::string name() const CATCH_OVERRIDE {
|
||||
return m_name;
|
||||
virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE {
|
||||
return m_nameAndLocation;
|
||||
}
|
||||
virtual bool isComplete() const CATCH_OVERRIDE {
|
||||
return m_runState == CompletedSuccessfully || m_runState == Failed;
|
||||
|
@ -153,8 +165,8 @@ namespace TestCaseTracking {
|
|||
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 ) );
|
||||
virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE {
|
||||
Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) );
|
||||
return( it != m_children.end() )
|
||||
? it->get()
|
||||
: CATCH_NULL;
|
||||
|
@ -232,41 +244,65 @@ namespace TestCaseTracking {
|
|||
};
|
||||
|
||||
class SectionTracker : public TrackerBase {
|
||||
std::vector<std::string> m_filters;
|
||||
public:
|
||||
SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
|
||||
: TrackerBase( name, ctx, parent )
|
||||
{}
|
||||
SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )
|
||||
: TrackerBase( nameAndLocation, ctx, parent )
|
||||
{
|
||||
if( parent ) {
|
||||
while( !parent->isSectionTracker() )
|
||||
parent = &parent->parent();
|
||||
|
||||
SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );
|
||||
addNextFilters( parentSection.m_filters );
|
||||
}
|
||||
}
|
||||
virtual ~SectionTracker();
|
||||
|
||||
virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; }
|
||||
|
||||
static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
|
||||
static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {
|
||||
SectionTracker* section = CATCH_NULL;
|
||||
|
||||
ITracker& currentTracker = ctx.currentTracker();
|
||||
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
|
||||
if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
|
||||
assert( childTracker );
|
||||
assert( childTracker->isSectionTracker() );
|
||||
section = static_cast<SectionTracker*>( childTracker );
|
||||
}
|
||||
else {
|
||||
section = new SectionTracker( name, ctx, ¤tTracker );
|
||||
section = new SectionTracker( nameAndLocation, ctx, ¤tTracker );
|
||||
currentTracker.addChild( section );
|
||||
}
|
||||
if( !ctx.completedCycle() && !section->isComplete() ) {
|
||||
|
||||
section->open();
|
||||
}
|
||||
if( !ctx.completedCycle() )
|
||||
section->tryOpen();
|
||||
return *section;
|
||||
}
|
||||
|
||||
void tryOpen() {
|
||||
if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) )
|
||||
open();
|
||||
}
|
||||
|
||||
void addInitialFilters( std::vector<std::string> const& filters ) {
|
||||
if( !filters.empty() ) {
|
||||
m_filters.push_back(""); // Root - should never be consulted
|
||||
m_filters.push_back(""); // Test Case - not a section filter
|
||||
std::copy( filters.begin(), filters.end(), std::back_inserter( m_filters ) );
|
||||
}
|
||||
}
|
||||
void addNextFilters( std::vector<std::string> const& filters ) {
|
||||
if( filters.size() > 1 )
|
||||
std::copy( filters.begin()+1, filters.end(), std::back_inserter( m_filters ) );
|
||||
}
|
||||
};
|
||||
|
||||
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 ),
|
||||
IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size )
|
||||
: TrackerBase( nameAndLocation, ctx, parent ),
|
||||
m_size( size ),
|
||||
m_index( -1 )
|
||||
{}
|
||||
|
@ -274,17 +310,17 @@ namespace TestCaseTracking {
|
|||
|
||||
virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; }
|
||||
|
||||
static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
|
||||
static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) {
|
||||
IndexTracker* tracker = CATCH_NULL;
|
||||
|
||||
ITracker& currentTracker = ctx.currentTracker();
|
||||
if( ITracker* childTracker = currentTracker.findChild( name ) ) {
|
||||
if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) {
|
||||
assert( childTracker );
|
||||
assert( childTracker->isIndexTracker() );
|
||||
tracker = static_cast<IndexTracker*>( childTracker );
|
||||
}
|
||||
else {
|
||||
tracker = new IndexTracker( name, ctx, ¤tTracker, size );
|
||||
tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size );
|
||||
currentTracker.addChild( tracker );
|
||||
}
|
||||
|
||||
|
@ -312,7 +348,7 @@ namespace TestCaseTracking {
|
|||
};
|
||||
|
||||
inline ITracker& TrackerContext::startRun() {
|
||||
m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
|
||||
m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL );
|
||||
m_currentTracker = CATCH_NULL;
|
||||
m_runState = Executing;
|
||||
return *m_rootTracker;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue