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 ITracker& startRun(); 75 void endRun(); 76 77 void startCycle(); 78 void completeCycle(); 79 80 bool completedCycle() const; 81 ITracker& currentTracker(); 82 void setCurrentTracker( ITracker* tracker ); 83 }; 84 85 class TrackerBase : public ITracker { 86 protected: 87 enum CycleState { 88 NotStarted, 89 Executing, 90 ExecutingChildren, 91 NeedsAnotherRun, 92 CompletedSuccessfully, 93 Failed 94 }; 95 96 using Children = std::vector<ITrackerPtr>; 97 NameAndLocation m_nameAndLocation; 98 TrackerContext& m_ctx; 99 ITracker* m_parent; 100 Children m_children; 101 CycleState m_runState = NotStarted; 102 103 public: 104 TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); 105 106 NameAndLocation const& nameAndLocation() const override; 107 bool isComplete() const override; 108 bool isSuccessfullyCompleted() const override; 109 bool isOpen() const override; 110 bool hasChildren() const override; 111 112 113 void addChild( ITrackerPtr const& child ) override; 114 115 ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; 116 ITracker& parent() override; 117 118 void openChild() override; 119 120 bool isSectionTracker() const override; 121 bool isGeneratorTracker() const override; 122 123 void open(); 124 125 void close() override; 126 void fail() override; 127 void markAsNeedingAnotherRun() override; 128 129 private: 130 void moveToParent(); 131 void moveToThis(); 132 }; 133 134 class SectionTracker : public TrackerBase { 135 std::vector<std::string> m_filters; 136 std::string m_trimmed_name; 137 public: 138 SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); 139 140 bool isSectionTracker() const override; 141 142 bool isComplete() const override; 143 144 static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); 145 146 void tryOpen(); 147 148 void addInitialFilters( std::vector<std::string> const& filters ); 149 void addNextFilters( std::vector<std::string> const& filters ); 150 }; 151 152 } // namespace TestCaseTracking 153 154 using TestCaseTracking::ITracker; 155 using TestCaseTracking::TrackerContext; 156 using TestCaseTracking::SectionTracker; 157 158 } // namespace Catch 159 160 #endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED 161