1 /*
2  *  Created by Phil on 31/12/2010.
3  *  Copyright 2010 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_CONTEXT_IMPL_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
10 
11 #include "catch_run_context.hpp"
12 
13 #include "catch_context.h"
14 #include "catch_stream.hpp"
15 #include "catch_common.h"
16 
17 namespace Catch {
18 
19     class Context : public IMutableContext {
20 
Context()21         Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
22         Context( Context const& );
23         void operator=( Context const& );
24 
25     public:
~Context()26         virtual ~Context() {
27             deleteAllValues( m_generatorsByTestName );
28         }
29 
30     public: // IContext
getResultCapture()31         virtual IResultCapture* getResultCapture() {
32             return m_resultCapture;
33         }
getRunner()34         virtual IRunner* getRunner() {
35             return m_runner;
36         }
getGeneratorIndex(std::string const & fileInfo,size_t totalSize)37         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
38             return getGeneratorsForCurrentTest()
39             .getGeneratorInfo( fileInfo, totalSize )
40             .getCurrentIndex();
41         }
advanceGeneratorsForCurrentTest()42         virtual bool advanceGeneratorsForCurrentTest() {
43             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
44             return generators && generators->moveNext();
45         }
46 
getConfig() const47         virtual Ptr<IConfig const> getConfig() const {
48             return m_config;
49         }
50 
51     public: // IMutableContext
setResultCapture(IResultCapture * resultCapture)52         virtual void setResultCapture( IResultCapture* resultCapture ) {
53             m_resultCapture = resultCapture;
54         }
setRunner(IRunner * runner)55         virtual void setRunner( IRunner* runner ) {
56             m_runner = runner;
57         }
setConfig(Ptr<IConfig const> const & config)58         virtual void setConfig( Ptr<IConfig const> const& config ) {
59             m_config = config;
60         }
61 
62         friend IMutableContext& getCurrentMutableContext();
63 
64     private:
findGeneratorsForCurrentTest()65         IGeneratorsForTest* findGeneratorsForCurrentTest() {
66             std::string testName = getResultCapture()->getCurrentTestName();
67 
68             std::map<std::string, IGeneratorsForTest*>::const_iterator it =
69                 m_generatorsByTestName.find( testName );
70             return it != m_generatorsByTestName.end()
71                 ? it->second
72                 : CATCH_NULL;
73         }
74 
getGeneratorsForCurrentTest()75         IGeneratorsForTest& getGeneratorsForCurrentTest() {
76             IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
77             if( !generators ) {
78                 std::string testName = getResultCapture()->getCurrentTestName();
79                 generators = createGeneratorsForTest();
80                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
81             }
82             return *generators;
83         }
84 
85     private:
86         Ptr<IConfig const> m_config;
87         IRunner* m_runner;
88         IResultCapture* m_resultCapture;
89         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
90     };
91 
92     namespace {
93         Context* currentContext = CATCH_NULL;
94     }
getCurrentMutableContext()95     IMutableContext& getCurrentMutableContext() {
96         if( !currentContext )
97             currentContext = new Context();
98         return *currentContext;
99     }
getCurrentContext()100     IContext& getCurrentContext() {
101         return getCurrentMutableContext();
102     }
103 
cleanUpContext()104     void cleanUpContext() {
105         delete currentContext;
106         currentContext = CATCH_NULL;
107     }
108 }
109 
110 #endif // TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
111