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 friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) { 27 return lhs.name == rhs.name 28 && lhs.location == rhs.location; 29 } 30 }; 31 32 class ITracker; 33 34 using ITrackerPtr = std::shared_ptr<ITracker>; 35 36 class ITracker { 37 NameAndLocation m_nameAndLocation; 38 39 public: ITracker(NameAndLocation const & nameAndLoc)40 ITracker(NameAndLocation const& nameAndLoc) : 41 m_nameAndLocation(nameAndLoc) 42 {} 43 44 45 // static queries nameAndLocation()46 NameAndLocation const& nameAndLocation() const { 47 return m_nameAndLocation; 48 } 49 50 virtual ~ITracker(); 51 52 53 // dynamic queries 54 virtual bool isComplete() const = 0; // Successfully completed or failed 55 virtual bool isSuccessfullyCompleted() const = 0; 56 virtual bool isOpen() const = 0; // Started but not complete 57 virtual bool hasChildren() const = 0; 58 virtual bool hasStarted() const = 0; 59 60 virtual ITracker& parent() = 0; 61 62 // actions 63 virtual void close() = 0; // Successfully complete 64 virtual void fail() = 0; 65 virtual void markAsNeedingAnotherRun() = 0; 66 67 virtual void addChild( ITrackerPtr const& child ) = 0; 68 virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0; 69 virtual void openChild() = 0; 70 71 // Debug/ checking 72 virtual bool isSectionTracker() const = 0; 73 virtual bool isGeneratorTracker() const = 0; 74 }; 75 76 class TrackerContext { 77 78 enum RunState { 79 NotStarted, 80 Executing, 81 CompletedCycle 82 }; 83 84 ITrackerPtr m_rootTracker; 85 ITracker* m_currentTracker = nullptr; 86 RunState m_runState = NotStarted; 87 88 public: 89 90 ITracker& startRun(); 91 void endRun(); 92 93 void startCycle(); 94 void completeCycle(); 95 96 bool completedCycle() const; 97 ITracker& currentTracker(); 98 void setCurrentTracker( ITracker* tracker ); 99 }; 100 101 class TrackerBase : public ITracker { 102 protected: 103 enum CycleState { 104 NotStarted, 105 Executing, 106 ExecutingChildren, 107 NeedsAnotherRun, 108 CompletedSuccessfully, 109 Failed 110 }; 111 112 using Children = std::vector<ITrackerPtr>; 113 TrackerContext& m_ctx; 114 ITracker* m_parent; 115 Children m_children; 116 CycleState m_runState = NotStarted; 117 118 public: 119 TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); 120 121 bool isComplete() const override; 122 bool isSuccessfullyCompleted() const override; 123 bool isOpen() const override; 124 bool hasChildren() const override; hasStarted()125 bool hasStarted() const override { 126 return m_runState != NotStarted; 127 } 128 129 void addChild( ITrackerPtr const& child ) override; 130 131 ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; 132 ITracker& parent() override; 133 134 void openChild() override; 135 136 bool isSectionTracker() const override; 137 bool isGeneratorTracker() const override; 138 139 void open(); 140 141 void close() override; 142 void fail() override; 143 void markAsNeedingAnotherRun() override; 144 145 private: 146 void moveToParent(); 147 void moveToThis(); 148 }; 149 150 class SectionTracker : public TrackerBase { 151 std::vector<std::string> m_filters; 152 std::string m_trimmed_name; 153 public: 154 SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); 155 156 bool isSectionTracker() const override; 157 158 bool isComplete() const override; 159 160 static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); 161 162 void tryOpen(); 163 164 void addInitialFilters( std::vector<std::string> const& filters ); 165 void addNextFilters( std::vector<std::string> const& filters ); 166 //! Returns filters active in this tracker 167 std::vector<std::string> const& getFilters() const; 168 //! Returns whitespace-trimmed name of the tracked section 169 std::string const& trimmedName() const; 170 }; 171 172 } // namespace TestCaseTracking 173 174 using TestCaseTracking::ITracker; 175 using TestCaseTracking::TrackerContext; 176 using TestCaseTracking::SectionTracker; 177 178 } // namespace Catch 179 180 #endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 181