Internal linkage for generator trackers

This commit is contained in:
Martin Hořeňovský 2023-03-16 16:30:06 +01:00
parent 72f3ce4db5
commit 3c8fb6bbb2
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
1 changed files with 127 additions and 119 deletions

View File

@ -26,15 +26,22 @@
namespace Catch { namespace Catch {
namespace Generators { namespace Generators {
struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker { namespace {
struct GeneratorTracker : TestCaseTracking::TrackerBase,
IGeneratorTracker {
GeneratorBasePtr m_generator; GeneratorBasePtr m_generator;
GeneratorTracker( TestCaseTracking::NameAndLocation&& nameAndLocation, TrackerContext& ctx, ITracker* parent ) GeneratorTracker(
: TrackerBase( CATCH_MOVE(nameAndLocation), ctx, parent ) TestCaseTracking::NameAndLocation&& nameAndLocation,
{} TrackerContext& ctx,
ITracker* parent ):
TrackerBase( CATCH_MOVE( nameAndLocation ), ctx, parent ) {}
~GeneratorTracker() override; ~GeneratorTracker() override;
static GeneratorTracker* acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocationRef const& nameAndLocation ) { static GeneratorTracker*
acquire( TrackerContext& ctx,
TestCaseTracking::NameAndLocationRef const&
nameAndLocation ) {
GeneratorTracker* tracker; GeneratorTracker* tracker;
ITracker& currentTracker = ctx.currentTracker(); ITracker& currentTracker = ctx.currentTracker();
@ -50,23 +57,23 @@ namespace Catch {
// //
// without it, the code above creates 5 nested generators. // without it, the code above creates 5 nested generators.
if ( currentTracker.nameAndLocation() == nameAndLocation ) { if ( currentTracker.nameAndLocation() == nameAndLocation ) {
auto thisTracker = auto thisTracker = currentTracker.parent()->findChild(
currentTracker.parent()->findChild( nameAndLocation ); nameAndLocation );
assert( thisTracker ); assert( thisTracker );
assert( thisTracker->isGeneratorTracker() ); assert( thisTracker->isGeneratorTracker() );
tracker = static_cast<GeneratorTracker*>( thisTracker ); tracker = static_cast<GeneratorTracker*>( thisTracker );
} else if ( ITracker* childTracker = } else if ( ITracker* childTracker =
currentTracker.findChild( nameAndLocation ) ) { currentTracker.findChild(
nameAndLocation ) ) {
assert( childTracker ); assert( childTracker );
assert( childTracker->isGeneratorTracker() ); assert( childTracker->isGeneratorTracker() );
tracker = static_cast<GeneratorTracker*>( childTracker ); tracker =
static_cast<GeneratorTracker*>( childTracker );
} else { } else {
return nullptr; return nullptr;
} }
if( !tracker->isComplete() ) { if ( !tracker->isComplete() ) { tracker->open(); }
tracker->open();
}
return tracker; return tracker;
} }
@ -84,25 +91,26 @@ namespace Catch {
// This catches cases where `GENERATE` is placed between two // This catches cases where `GENERATE` is placed between two
// `SECTION`s. // `SECTION`s.
// **The check for m_children.empty cannot be removed**. // **The check for m_children.empty cannot be removed**.
// doing so would break `GENERATE` _not_ followed by `SECTION`s. // doing so would break `GENERATE` _not_ followed by
// `SECTION`s.
const bool should_wait_for_child = [&]() { const bool should_wait_for_child = [&]() {
// No children -> nobody to wait for // No children -> nobody to wait for
if ( m_children.empty() ) { if ( m_children.empty() ) { return false; }
return false;
}
// If at least one child started executing, don't wait // If at least one child started executing, don't wait
if ( std::find_if( if ( std::find_if(
m_children.begin(), m_children.begin(),
m_children.end(), m_children.end(),
[]( TestCaseTracking::ITrackerPtr const& tracker ) { []( TestCaseTracking::ITrackerPtr const&
tracker ) {
return tracker->hasStarted(); return tracker->hasStarted();
} ) != m_children.end() ) { } ) != m_children.end() ) {
return false; return false;
} }
// No children have started. We need to check if they _can_ // No children have started. We need to check if they
// start, and thus we should wait for them, or they cannot // _can_ start, and thus we should wait for them, or
// start (due to filters), and we shouldn't wait for them // they cannot start (due to filters), and we shouldn't
// wait for them
ITracker* parent = m_parent; ITracker* parent = m_parent;
// This is safe: there is always at least one section // This is safe: there is always at least one section
// tracker in a test case tracking tree // tracker in a test case tracking tree
@ -116,17 +124,16 @@ namespace Catch {
static_cast<SectionTracker const&>( *parent ); static_cast<SectionTracker const&>( *parent );
auto const& filters = parentSection.getFilters(); auto const& filters = parentSection.getFilters();
// No filters -> no restrictions on running sections // No filters -> no restrictions on running sections
if ( filters.empty() ) { if ( filters.empty() ) { return true; }
return true;
}
for ( auto const& child : m_children ) { for ( auto const& child : m_children ) {
if ( child->isSectionTracker() && if ( child->isSectionTracker() &&
std::find( std::find( filters.begin(),
filters.begin(),
filters.end(), filters.end(),
static_cast<SectionTracker const&>( *child ) static_cast<SectionTracker const&>(
.trimmedName() ) != filters.end() ) { *child )
.trimmedName() ) !=
filters.end() ) {
return true; return true;
} }
} }
@ -155,6 +162,7 @@ namespace Catch {
} }
}; };
GeneratorTracker::~GeneratorTracker() = default; GeneratorTracker::~GeneratorTracker() = default;
} // namespace
} }
RunContext::RunContext(IConfig const* _config, IEventListenerPtr&& reporter) RunContext::RunContext(IConfig const* _config, IEventListenerPtr&& reporter)