| 
									
										
										
										
											2013-07-23 18:48:36 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-01 07:33:27 +01:00
										 |  |  | #include "catch_compiler_capabilities.h"
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  | #include "catch_ptr.hpp"
 | 
					
						
							| 
									
										
										
										
											2015-07-01 07:33:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:38:19 +01:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2013-07-23 18:48:36 +01:00
										 |  |  | #include <string>
 | 
					
						
							|  |  |  | #include <assert.h>
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2017-02-12 12:17:07 +01:00
										 |  |  | #include <stdexcept>
 | 
					
						
							| 
									
										
										
										
											2013-07-23 18:48:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-29 20:30:59 +02:00
										 |  |  | CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-23 18:48:36 +01:00
										 |  |  | namespace Catch { | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  | namespace TestCaseTracking { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |     struct NameAndLocation { | 
					
						
							|  |  |  |         std::string name; | 
					
						
							|  |  |  |         SourceLineInfo location; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) | 
					
						
							|  |  |  |         :   name( _name ), | 
					
						
							|  |  |  |             location( _location ) | 
					
						
							|  |  |  |         {} | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     struct ITracker : SharedImpl<> { | 
					
						
							|  |  |  |         virtual ~ITracker(); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         // static queries
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         virtual NameAndLocation const& nameAndLocation() const = 0; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         // 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
 | 
					
						
							| 
									
										
										
										
											2015-11-02 19:21:46 +00:00
										 |  |  |         virtual bool hasChildren() const = 0; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual ITracker& parent() = 0; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         // actions
 | 
					
						
							|  |  |  |         virtual void close() = 0; // Successfully complete
 | 
					
						
							|  |  |  |         virtual void fail() = 0; | 
					
						
							|  |  |  |         virtual void markAsNeedingAnotherRun() = 0; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual void addChild( Ptr<ITracker> const& child ) = 0; | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0; | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual void openChild() = 0; | 
					
						
							| 
									
										
										
										
											2017-01-26 23:13:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 08:10:10 +01:00
										 |  |  |         // Debug/ checking
 | 
					
						
							|  |  |  |         virtual bool isSectionTracker() const = 0; | 
					
						
							|  |  |  |         virtual bool isIndexTracker() const = 0; | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |     class  TrackerContext { | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         enum RunState { | 
					
						
							|  |  |  |             NotStarted, | 
					
						
							|  |  |  |             Executing, | 
					
						
							|  |  |  |             CompletedCycle | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         Ptr<ITracker> m_rootTracker; | 
					
						
							|  |  |  |         ITracker* m_currentTracker; | 
					
						
							|  |  |  |         RunState m_runState; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         static TrackerContext& instance() { | 
					
						
							|  |  |  |             static TrackerContext s_instance; | 
					
						
							|  |  |  |             return s_instance; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         TrackerContext() | 
					
						
							|  |  |  |         :   m_currentTracker( CATCH_NULL ), | 
					
						
							|  |  |  |             m_runState( NotStarted ) | 
					
						
							|  |  |  |         {} | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         ITracker& startRun(); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         void endRun() { | 
					
						
							|  |  |  |             m_rootTracker.reset(); | 
					
						
							|  |  |  |             m_currentTracker = CATCH_NULL; | 
					
						
							|  |  |  |             m_runState = NotStarted; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         void startCycle() { | 
					
						
							|  |  |  |             m_currentTracker = m_rootTracker.get(); | 
					
						
							|  |  |  |             m_runState = Executing; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         void completeCycle() { | 
					
						
							|  |  |  |             m_runState = CompletedCycle; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         bool completedCycle() const { | 
					
						
							|  |  |  |             return m_runState == CompletedCycle; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         ITracker& currentTracker() { | 
					
						
							|  |  |  |             return *m_currentTracker; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         void setCurrentTracker( ITracker* tracker ) { | 
					
						
							|  |  |  |             m_currentTracker = tracker; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     class TrackerBase : public ITracker { | 
					
						
							|  |  |  |     protected: | 
					
						
							|  |  |  |         enum CycleState { | 
					
						
							|  |  |  |             NotStarted, | 
					
						
							|  |  |  |             Executing, | 
					
						
							|  |  |  |             ExecutingChildren, | 
					
						
							|  |  |  |             NeedsAnotherRun, | 
					
						
							|  |  |  |             CompletedSuccessfully, | 
					
						
							|  |  |  |             Failed | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         class TrackerHasName { | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |             NameAndLocation m_nameAndLocation; | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         public: | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |             TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             bool operator ()( Ptr<ITracker> const& tracker ) { | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |                 return | 
					
						
							|  |  |  |                     tracker->nameAndLocation().name == m_nameAndLocation.name && | 
					
						
							|  |  |  |                     tracker->nameAndLocation().location == m_nameAndLocation.location; | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         typedef std::vector<Ptr<ITracker> > Children; | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         NameAndLocation m_nameAndLocation; | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         TrackerContext& m_ctx; | 
					
						
							|  |  |  |         ITracker* m_parent; | 
					
						
							|  |  |  |         Children m_children; | 
					
						
							|  |  |  |         CycleState m_runState; | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) | 
					
						
							|  |  |  |         :   m_nameAndLocation( nameAndLocation ), | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             m_ctx( ctx ), | 
					
						
							|  |  |  |             m_parent( parent ), | 
					
						
							|  |  |  |             m_runState( NotStarted ) | 
					
						
							|  |  |  |         {} | 
					
						
							|  |  |  |         virtual ~TrackerBase(); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE { | 
					
						
							|  |  |  |             return m_nameAndLocation; | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         virtual bool isComplete() const CATCH_OVERRIDE { | 
					
						
							|  |  |  |             return m_runState == CompletedSuccessfully || m_runState == Failed; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { | 
					
						
							|  |  |  |             return m_runState == CompletedSuccessfully; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         virtual bool isOpen() const CATCH_OVERRIDE { | 
					
						
							|  |  |  |             return m_runState != NotStarted && !isComplete(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-02 19:21:46 +00:00
										 |  |  |         virtual bool hasChildren() const CATCH_OVERRIDE { | 
					
						
							|  |  |  |             return !m_children.empty(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE { | 
					
						
							|  |  |  |             m_children.push_back( child ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE { | 
					
						
							|  |  |  |             Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             return( it != m_children.end() ) | 
					
						
							|  |  |  |                 ? it->get() | 
					
						
							|  |  |  |                 : CATCH_NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         virtual ITracker& parent() CATCH_OVERRIDE { | 
					
						
							|  |  |  |             assert( m_parent ); // Should always be non-null except for root
 | 
					
						
							|  |  |  |             return *m_parent; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual void openChild() CATCH_OVERRIDE { | 
					
						
							|  |  |  |             if( m_runState != ExecutingChildren ) { | 
					
						
							|  |  |  |                 m_runState = ExecutingChildren; | 
					
						
							|  |  |  |                 if( m_parent ) | 
					
						
							|  |  |  |                     m_parent->openChild(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-04-28 08:10:10 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } | 
					
						
							|  |  |  |         virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } | 
					
						
							| 
									
										
										
										
											2017-01-26 23:13:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         void open() { | 
					
						
							|  |  |  |             m_runState = Executing; | 
					
						
							|  |  |  |             moveToThis(); | 
					
						
							|  |  |  |             if( m_parent ) | 
					
						
							|  |  |  |                 m_parent->openChild(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual void close() CATCH_OVERRIDE { | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             // Close any still open children (e.g. generators)
 | 
					
						
							|  |  |  |             while( &m_ctx.currentTracker() != this ) | 
					
						
							|  |  |  |                 m_ctx.currentTracker().close(); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             switch( m_runState ) { | 
					
						
							|  |  |  |                 case NotStarted: | 
					
						
							|  |  |  |                 case CompletedSuccessfully: | 
					
						
							|  |  |  |                 case Failed: | 
					
						
							|  |  |  |                     throw std::logic_error( "Illogical state" ); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |                 case NeedsAnotherRun: | 
					
						
							|  |  |  |                     break;; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |                 case Executing: | 
					
						
							|  |  |  |                     m_runState = CompletedSuccessfully; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case ExecutingChildren: | 
					
						
							|  |  |  |                     if( m_children.empty() || m_children.back()->isComplete() ) | 
					
						
							|  |  |  |                         m_runState = CompletedSuccessfully; | 
					
						
							|  |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |                 default: | 
					
						
							|  |  |  |                     throw std::logic_error( "Unexpected state" ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             moveToParent(); | 
					
						
							|  |  |  |             m_ctx.completeCycle(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         virtual void fail() CATCH_OVERRIDE { | 
					
						
							|  |  |  |             m_runState = Failed; | 
					
						
							|  |  |  |             if( m_parent ) | 
					
						
							|  |  |  |                 m_parent->markAsNeedingAnotherRun(); | 
					
						
							|  |  |  |             moveToParent(); | 
					
						
							|  |  |  |             m_ctx.completeCycle(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { | 
					
						
							|  |  |  |             m_runState = NeedsAnotherRun; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         void moveToParent() { | 
					
						
							|  |  |  |             assert( m_parent ); | 
					
						
							|  |  |  |             m_ctx.setCurrentTracker( m_parent ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         void moveToThis() { | 
					
						
							|  |  |  |             m_ctx.setCurrentTracker( this ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     class SectionTracker : public TrackerBase { | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         std::vector<std::string> m_filters; | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     public: | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) | 
					
						
							|  |  |  |         :   TrackerBase( nameAndLocation, ctx, parent ) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if( parent ) { | 
					
						
							|  |  |  |                 while( !parent->isSectionTracker() ) | 
					
						
							|  |  |  |                     parent = &parent->parent(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 SectionTracker& parentSection = static_cast<SectionTracker&>( *parent ); | 
					
						
							|  |  |  |                 addNextFilters( parentSection.m_filters ); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual ~SectionTracker(); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 08:10:10 +01:00
										 |  |  |         virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } | 
					
						
							| 
									
										
										
										
											2017-01-26 23:13:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             SectionTracker* section = CATCH_NULL; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             ITracker& currentTracker = ctx.currentTracker(); | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |             if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { | 
					
						
							| 
									
										
										
										
											2016-04-28 08:10:10 +01:00
										 |  |  |                 assert( childTracker ); | 
					
						
							|  |  |  |                 assert( childTracker->isSectionTracker() ); | 
					
						
							|  |  |  |                 section = static_cast<SectionTracker*>( childTracker ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |                 section = new SectionTracker( nameAndLocation, ctx, ¤tTracker ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |                 currentTracker.addChild( section ); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |             if( !ctx.completedCycle() ) | 
					
						
							|  |  |  |                 section->tryOpen(); | 
					
						
							|  |  |  |             return *section; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void tryOpen() { | 
					
						
							|  |  |  |             if( !isComplete() && (m_filters.empty() || m_filters[0].empty() ||  m_filters[0] == m_nameAndLocation.name ) ) | 
					
						
							|  |  |  |                 open(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         void addInitialFilters( std::vector<std::string> const& filters ) { | 
					
						
							|  |  |  |             if( !filters.empty() ) { | 
					
						
							|  |  |  |                 m_filters.push_back(""); // Root - should never be consulted
 | 
					
						
							|  |  |  |                 m_filters.push_back(""); // Test Case - not a section filter
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:38:19 +01:00
										 |  |  |                 m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         void addNextFilters( std::vector<std::string> const& filters ) { | 
					
						
							|  |  |  |             if( filters.size() > 1 ) | 
					
						
							| 
									
										
										
										
											2017-03-15 13:38:19 +01:00
										 |  |  |                 m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     class IndexTracker : public TrackerBase { | 
					
						
							|  |  |  |         int m_size; | 
					
						
							|  |  |  |         int m_index; | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) | 
					
						
							|  |  |  |         :   TrackerBase( nameAndLocation, ctx, parent ), | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             m_size( size ), | 
					
						
							|  |  |  |             m_index( -1 ) | 
					
						
							|  |  |  |         {} | 
					
						
							|  |  |  |         virtual ~IndexTracker(); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 08:10:10 +01:00
										 |  |  |         virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } | 
					
						
							| 
									
										
										
										
											2017-01-26 23:13:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             IndexTracker* tracker = CATCH_NULL; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             ITracker& currentTracker = ctx.currentTracker(); | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |             if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { | 
					
						
							| 
									
										
										
										
											2016-04-28 08:10:10 +01:00
										 |  |  |                 assert( childTracker ); | 
					
						
							|  |  |  |                 assert( childTracker->isIndexTracker() ); | 
					
						
							|  |  |  |                 tracker = static_cast<IndexTracker*>( childTracker ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |                 tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |                 currentTracker.addChild( tracker ); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             if( !ctx.completedCycle() && !tracker->isComplete() ) { | 
					
						
							|  |  |  |                 if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) | 
					
						
							|  |  |  |                     tracker->moveNext(); | 
					
						
							|  |  |  |                 tracker->open(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |             return *tracker; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         int index() const { return m_index; } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         void moveNext() { | 
					
						
							|  |  |  |             m_index++; | 
					
						
							|  |  |  |             m_children.clear(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         virtual void close() CATCH_OVERRIDE { | 
					
						
							|  |  |  |             TrackerBase::close(); | 
					
						
							|  |  |  |             if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) | 
					
						
							|  |  |  |                 m_runState = Executing; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |     inline ITracker& TrackerContext::startRun() { | 
					
						
							| 
									
										
										
										
											2017-01-12 17:10:38 +00:00
										 |  |  |         m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL ); | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  |         m_currentTracker = CATCH_NULL; | 
					
						
							|  |  |  |         m_runState = Executing; | 
					
						
							|  |  |  |         return *m_rootTracker; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  | } // namespace TestCaseTracking
 | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-02 06:14:52 +00:00
										 |  |  | using TestCaseTracking::ITracker; | 
					
						
							|  |  |  | using TestCaseTracking::TrackerContext; | 
					
						
							|  |  |  | using TestCaseTracking::SectionTracker; | 
					
						
							|  |  |  | using TestCaseTracking::IndexTracker; | 
					
						
							| 
									
										
										
										
											2013-07-23 18:48:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | } // namespace Catch
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-29 20:30:59 +02:00
										 |  |  | CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-23 18:48:36 +01:00
										 |  |  | #endif // TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
 |