1 /* 2 * Created by Phil Nash on 23/7/2013 3 * Copyright 2013 Two Blue Cubes Ltd. All rights reserved. 4 * 5 * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 */ 8 #ifndef TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 9 #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 10 11 #include "catch_compiler_capabilities.h" 12 #include "catch_common.h" 13 14 #include <string> 15 #include <vector> 16 #include <memory> 17 18 namespace Catch { 19 namespace TestCaseTracking { 20 21 struct NameAndLocation { 22 std::string name; 23 SourceLineInfo location; 24 25 NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); 26 }; 27 28 struct ITracker; 29 30 using ITrackerPtr = std::shared_ptr<ITracker>; 31 32 struct ITracker { 33 virtual ~ITracker(); 34 35 // static queries 36 virtual NameAndLocation const& nameAndLocation() const = 0; 37 38 // dynamic queries 39 virtual bool isComplete() const = 0; // Successfully completed or failed 40 virtual bool isSuccessfullyCompleted() const = 0; 41 virtual bool isOpen() const = 0; // Started but not complete 42 virtual bool hasChildren() const = 0; 43 44 virtual ITracker& parent() = 0; 45 46 // actions 47 virtual void close() = 0; // Successfully complete 48 virtual void fail() = 0; 49 virtual void markAsNeedingAnotherRun() = 0; 50 51 virtual void addChild( ITrackerPtr const& child ) = 0; 52 virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0; 53 virtual void openChild() = 0; 54 55 // Debug/ checking 56 virtual bool isSectionTracker() const = 0; 57 virtual bool isGeneratorTracker() const = 0; 58 }; 59 60 class TrackerContext { 61 62 enum RunState { 63 NotStarted, 64 Executing, 65 CompletedCycle 66 }; 67 68 ITrackerPtr m_rootTracker; 69 ITracker* m_currentTracker = nullptr; 70 RunState m_runState = NotStarted; 71 72 public: 73 74 static TrackerContext& instance(); 75 76 ITracker& startRun(); 77 void endRun(); 78 79 void startCycle(); 80 void completeCycle(); 81 82 bool completedCycle() const; 83 ITracker& currentTracker(); 84 void setCurrentTracker( ITracker* tracker ); 85 }; 86 87 class TrackerBase : public ITracker { 88 protected: 89 enum CycleState { 90 NotStarted, 91 Executing, 92 ExecutingChildren, 93 NeedsAnotherRun, 94 CompletedSuccessfully, 95 Failed 96 }; 97 98 using Children = std::vector<ITrackerPtr>; 99 NameAndLocation m_nameAndLocation; 100 TrackerContext& m_ctx; 101 ITracker* m_parent; 102 Children m_children; 103 CycleState m_runState = NotStarted; 104 105 public: 106 TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); 107 108 NameAndLocation const& nameAndLocation() const override; 109 bool isComplete() const override; 110 bool isSuccessfullyCompleted() const override; 111 bool isOpen() const override; 112 bool hasChildren() const override; 113 114 115 void addChild( ITrackerPtr const& child ) override; 116 117 ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; 118 ITracker& parent() override; 119 120 void openChild() override; 121 122 bool isSectionTracker() const override; 123 bool isGeneratorTracker() const override; 124 125 void open(); 126 127 void close() override; 128 void fail() override; 129 void markAsNeedingAnotherRun() override; 130 131 private: 132 void moveToParent(); 133 void moveToThis(); 134 }; 135 136 class SectionTracker : public TrackerBase { 137 std::vector<std::string> m_filters; 138 public: 139 SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); 140 141 bool isSectionTracker() const override; 142 143 bool isComplete() const override; 144 145 static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); 146 147 void tryOpen(); 148 149 void addInitialFilters( std::vector<std::string> const& filters ); 150 void addNextFilters( std::vector<std::string> const& filters ); 151 }; 152 153 } // namespace TestCaseTracking 154 155 using TestCaseTracking::ITracker; 156 using TestCaseTracking::TrackerContext; 157 using TestCaseTracking::SectionTracker; 158 159 } // namespace Catch 160 161 #endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 162