1 /*
2  *  Created by Phil Nash on 4/5/2012
3  *  Copyright 2012 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_SECTION_INFO_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED
10 
11 #include "catch_section_info.h"
12 
13 namespace Catch {
14 
15     class RunningSection {
16     public:
17 
18         typedef std::vector<RunningSection*> SubSections;
19 
20         enum State {
21             Root,
22             Unknown,
23             Branch,
24             TestedBranch,
25             TestedLeaf
26         };
27 
RunningSection(RunningSection * parent,std::string const & name)28         RunningSection( RunningSection* parent, std::string const& name )
29         :   m_state( Unknown ),
30             m_parent( parent ),
31             m_name( name )
32         {}
33 
RunningSection(std::string const & name)34         RunningSection( std::string const& name )
35         :   m_state( Root ),
36             m_parent( CATCH_NULL ),
37             m_name( name )
38         {}
39 
~RunningSection()40         ~RunningSection() {
41             deleteAll( m_subSections );
42         }
43 
getName() const44         std::string getName() const {
45             return m_name;
46         }
47 
shouldRun() const48         bool shouldRun() const {
49             return m_state < TestedBranch;
50         }
51 
isBranch() const52         bool isBranch() const {
53             return m_state == Branch;
54         }
55 
getParent() const56         const RunningSection* getParent() const {
57             return m_parent;
58         }
59 
hasUntestedSections() const60         bool hasUntestedSections() const {
61             if( m_state == Unknown )
62                 return true;
63             for(    SubSections::const_iterator it = m_subSections.begin();
64                     it != m_subSections.end();
65                     ++it)
66                 if( (*it)->hasUntestedSections() )
67                     return true;
68             return false;
69         }
70 
71         // Mutable methods:
72 
getParent()73         RunningSection* getParent() {
74             return m_parent;
75         }
76 
findOrAddSubSection(std::string const & name,bool & changed)77         RunningSection* findOrAddSubSection( std::string const& name, bool& changed ) {
78             for(    SubSections::const_iterator it = m_subSections.begin();
79                     it != m_subSections.end();
80                     ++it)
81                 if( (*it)->getName() == name )
82                     return *it;
83             RunningSection* subSection = new RunningSection( this, name );
84             m_subSections.push_back( subSection );
85             m_state = Branch;
86             changed = true;
87             return subSection;
88         }
89 
ran()90         bool ran() {
91             if( m_state >= Branch )
92                 return false;
93             m_state = TestedLeaf;
94             return true;
95         }
96 
ranToCompletion()97         void ranToCompletion() {
98             if( m_state == Branch && !hasUntestedSections() )
99                 m_state = TestedBranch;
100         }
101 
102     private:
103         State m_state;
104         RunningSection* m_parent;
105         std::string m_name;
106         SubSections m_subSections;
107     };
108 }
109 
110 #endif // TWOBLUECUBES_CATCH_SECTION_INFO_HPP_INCLUDED
111