1  /*
2  *  Created by Phil on 22/10/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_RUNNER_IMPL_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
10 
11 #include "catch_interfaces_generatortracker.h"
12 #include "catch_interfaces_runner.h"
13 #include "catch_interfaces_reporter.h"
14 #include "catch_interfaces_exception.h"
15 #include "catch_config.hpp"
16 #include "catch_test_registry.h"
17 #include "catch_test_case_info.h"
18 #include "catch_capture.hpp"
19 #include "catch_totals.h"
20 #include "catch_test_spec.h"
21 #include "catch_test_case_tracker.h"
22 #include "catch_timer.h"
23 #include "catch_assertionhandler.h"
24 #include "catch_fatal_condition.h"
25 
26 #include <string>
27 
28 namespace Catch {
29 
30     struct IMutableContext;
31 
32     ///////////////////////////////////////////////////////////////////////////
33 
34     class RunContext : public IResultCapture, public IRunner {
35 
36     public:
37         RunContext( RunContext const& ) = delete;
38         RunContext& operator =( RunContext const& ) = delete;
39 
40         explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );
41 
42         ~RunContext() override;
43 
44         void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );
45         void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );
46 
47         Totals runTest(TestCase const& testCase);
48 
49         IConfigPtr config() const;
50         IStreamingReporter& reporter() const;
51 
52     public: // IResultCapture
53 
54         // Assertion handlers
55         void handleExpr
56                 (   AssertionInfo const& info,
57                     ITransientExpression const& expr,
58                     AssertionReaction& reaction ) override;
59         void handleMessage
60                 (   AssertionInfo const& info,
61                     ResultWas::OfType resultType,
62                     StringRef const& message,
63                     AssertionReaction& reaction ) override;
64         void handleUnexpectedExceptionNotThrown
65                 (   AssertionInfo const& info,
66                     AssertionReaction& reaction ) override;
67         void handleUnexpectedInflightException
68                 (   AssertionInfo const& info,
69                     std::string const& message,
70                     AssertionReaction& reaction ) override;
71         void handleIncomplete
72                 (   AssertionInfo const& info ) override;
73         void handleNonExpr
74                 (   AssertionInfo const &info,
75                     ResultWas::OfType resultType,
76                     AssertionReaction &reaction ) override;
77 
78         bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;
79 
80         void sectionEnded( SectionEndInfo const& endInfo ) override;
81         void sectionEndedEarly( SectionEndInfo const& endInfo ) override;
82 
83         auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;
84 
85 #if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)
86         void benchmarkPreparing( std::string const& name ) override;
87         void benchmarkStarting( BenchmarkInfo const& info ) override;
88         void benchmarkEnded( BenchmarkStats<> const& stats ) override;
89         void benchmarkFailed( std::string const& error ) override;
90 #endif // CATCH_CONFIG_ENABLE_BENCHMARKING
91 
92         void pushScopedMessage( MessageInfo const& message ) override;
93         void popScopedMessage( MessageInfo const& message ) override;
94 
95         void emplaceUnscopedMessage( MessageBuilder const& builder ) override;
96 
97         std::string getCurrentTestName() const override;
98 
99         const AssertionResult* getLastResult() const override;
100 
101         void exceptionEarlyReported() override;
102 
103         void handleFatalErrorCondition( StringRef message ) override;
104 
105         bool lastAssertionPassed() override;
106 
107         void assertionPassed() override;
108 
109     public:
110         // !TBD We need to do this another way!
111         bool aborting() const final;
112 
113     private:
114 
115         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );
116         void invokeActiveTestCase();
117 
118         void resetAssertionInfo();
119         bool testForMissingAssertions( Counts& assertions );
120 
121         void assertionEnded( AssertionResult const& result );
122         void reportExpr
123                 (   AssertionInfo const &info,
124                     ResultWas::OfType resultType,
125                     ITransientExpression const *expr,
126                     bool negated );
127 
128         void populateReaction( AssertionReaction& reaction );
129 
130     private:
131 
132         void handleUnfinishedSections();
133 
134         TestRunInfo m_runInfo;
135         IMutableContext& m_context;
136         TestCase const* m_activeTestCase = nullptr;
137         ITracker* m_testCaseTracker = nullptr;
138         Option<AssertionResult> m_lastResult;
139 
140         IConfigPtr m_config;
141         Totals m_totals;
142         IStreamingReporterPtr m_reporter;
143         std::vector<MessageInfo> m_messages;
144         std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */
145         AssertionInfo m_lastAssertionInfo;
146         std::vector<SectionEndInfo> m_unfinishedSections;
147         std::vector<ITracker*> m_activeSections;
148         TrackerContext m_trackerContext;
149         bool m_lastAssertionPassed = false;
150         bool m_shouldReportUnexpected = true;
151         bool m_includeSuccessfulResults;
152     };
153 
154     void seedRng(IConfig const& config);
155     unsigned int rngSeed();
156 } // end namespace Catch
157 
158 #endif // TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
159