/* * Created by Phil Nash on 23/7/2013 * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. * * 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) */ #ifndef TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED #include "catch_compiler_capabilities.h" #include "catch_common.h" #include #include #include CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS namespace Catch { namespace TestCaseTracking { struct NameAndLocation { std::string name; SourceLineInfo location; NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); }; struct ITracker; using ITrackerPtr = std::shared_ptr; struct ITracker { virtual ~ITracker() = default; // static queries virtual NameAndLocation const& nameAndLocation() 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( ITrackerPtr const& child ) = 0; virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0; virtual void openChild() = 0; // Debug/ checking virtual bool isSectionTracker() const = 0; virtual bool isIndexTracker() const = 0; }; class TrackerContext { enum RunState { NotStarted, Executing, CompletedCycle }; ITrackerPtr m_rootTracker; ITracker* m_currentTracker = nullptr; RunState m_runState = NotStarted; public: static TrackerContext& instance(); ITracker& startRun(); void endRun(); void startCycle(); void completeCycle(); bool completedCycle() const; ITracker& currentTracker(); void setCurrentTracker( ITracker* tracker ); }; class TrackerBase : public ITracker { protected: enum CycleState { NotStarted, Executing, ExecutingChildren, NeedsAnotherRun, CompletedSuccessfully, Failed }; class TrackerHasName { NameAndLocation m_nameAndLocation; public: TrackerHasName( NameAndLocation const& nameAndLocation ); bool operator ()( ITrackerPtr const& tracker ); }; typedef std::vector Children; NameAndLocation m_nameAndLocation; TrackerContext& m_ctx; ITracker* m_parent; Children m_children; CycleState m_runState = NotStarted; public: TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); virtual ~TrackerBase() = default; virtual NameAndLocation const& nameAndLocation() const override; virtual bool isComplete() const override; virtual bool isSuccessfullyCompleted() const override; virtual bool isOpen() const override; virtual bool hasChildren() const override; virtual void addChild( ITrackerPtr const& child ) override; virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; virtual ITracker& parent() override; virtual void openChild() override; virtual bool isSectionTracker() const override; virtual bool isIndexTracker() const override; void open(); virtual void close() override; virtual void fail() override; virtual void markAsNeedingAnotherRun() override; private: void moveToParent(); void moveToThis(); }; class SectionTracker : public TrackerBase { std::vector m_filters; public: SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); virtual ~SectionTracker() = default; virtual bool isSectionTracker() const override; static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); void tryOpen(); void addInitialFilters( std::vector const& filters ); void addNextFilters( std::vector const& filters ); }; class IndexTracker : public TrackerBase { int m_size; int m_index = -1; public: IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ); virtual ~IndexTracker() = default; virtual bool isIndexTracker() const override; static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ); int index() const; void moveNext(); virtual void close() override; }; } // namespace TestCaseTracking using TestCaseTracking::ITracker; using TestCaseTracking::TrackerContext; using TestCaseTracking::SectionTracker; using TestCaseTracking::IndexTracker; } // namespace Catch CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS #endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED