| /* |
| * 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 <string> |
| #include <vector> |
| #include <memory> |
| |
| 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<ITracker>; |
| |
| struct ITracker { |
| virtual ~ITracker(); |
| |
| // 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 isGeneratorTracker() 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 |
| }; |
| |
| using Children = std::vector<ITrackerPtr>; |
| 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 ); |
| |
| NameAndLocation const& nameAndLocation() const override; |
| bool isComplete() const override; |
| bool isSuccessfullyCompleted() const override; |
| bool isOpen() const override; |
| bool hasChildren() const override; |
| |
| |
| void addChild( ITrackerPtr const& child ) override; |
| |
| ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; |
| ITracker& parent() override; |
| |
| void openChild() override; |
| |
| bool isSectionTracker() const override; |
| bool isGeneratorTracker() const override; |
| |
| void open(); |
| |
| void close() override; |
| void fail() override; |
| void markAsNeedingAnotherRun() override; |
| |
| private: |
| void moveToParent(); |
| void moveToThis(); |
| }; |
| |
| class SectionTracker : public TrackerBase { |
| std::vector<std::string> m_filters; |
| public: |
| SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); |
| |
| bool isSectionTracker() const override; |
| |
| bool isComplete() const override; |
| |
| static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); |
| |
| void tryOpen(); |
| |
| void addInitialFilters( std::vector<std::string> const& filters ); |
| void addNextFilters( std::vector<std::string> const& filters ); |
| }; |
| |
| } // namespace TestCaseTracking |
| |
| using TestCaseTracking::ITracker; |
| using TestCaseTracking::TrackerContext; |
| using TestCaseTracking::SectionTracker; |
| |
| } // namespace Catch |
| |
| #endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED |