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_INTERFACES_REPORTER_H_INCLUDED
9 #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
10 
11 #include "catch_section_info.h"
12 #include "catch_common.h"
13 #include "catch_totals.hpp"
14 #include "catch_ptr.hpp"
15 #include "catch_config.hpp"
16 #include "catch_test_case_info.h"
17 #include "catch_assertionresult.h"
18 #include "catch_message.h"
19 #include "catch_option.hpp"
20 
21 #include <string>
22 #include <ostream>
23 #include <map>
24 
25 namespace Catch
26 {
27     struct ReporterConfig {
ReporterConfigReporterConfig28         explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
29         :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
30 
ReporterConfigReporterConfig31         ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
32         :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
33 
streamReporterConfig34         std::ostream& stream() const    { return *m_stream; }
fullConfigReporterConfig35         Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
36 
37     private:
38         std::ostream* m_stream;
39         Ptr<IConfig const> m_fullConfig;
40     };
41 
42     struct ReporterPreferences {
ReporterPreferencesReporterPreferences43         ReporterPreferences()
44         : shouldRedirectStdOut( false )
45         {}
46 
47         bool shouldRedirectStdOut;
48     };
49 
50     template<typename T>
51     struct LazyStat : Option<T> {
LazyStatLazyStat52         LazyStat() : used( false ) {}
53         LazyStat& operator=( T const& _value ) {
54             Option<T>::operator=( _value );
55             used = false;
56             return *this;
57         }
resetLazyStat58         void reset() {
59             Option<T>::reset();
60             used = false;
61         }
62         bool used;
63     };
64 
65     struct TestRunInfo {
TestRunInfoTestRunInfo66         TestRunInfo( std::string const& _name ) : name( _name ) {}
67         std::string name;
68     };
69     struct GroupInfo {
GroupInfoGroupInfo70         GroupInfo(  std::string const& _name,
71                     std::size_t _groupIndex,
72                     std::size_t _groupsCount )
73         :   name( _name ),
74             groupIndex( _groupIndex ),
75             groupsCounts( _groupsCount )
76         {}
77 
78         std::string name;
79         std::size_t groupIndex;
80         std::size_t groupsCounts;
81     };
82 
83     struct AssertionStats {
AssertionStatsAssertionStats84         AssertionStats( AssertionResult const& _assertionResult,
85                         std::vector<MessageInfo> const& _infoMessages,
86                         Totals const& _totals )
87         :   assertionResult( _assertionResult ),
88             infoMessages( _infoMessages ),
89             totals( _totals )
90         {
91             if( assertionResult.hasMessage() ) {
92                 // Copy message into messages list.
93                 // !TBD This should have been done earlier, somewhere
94                 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
95                 builder << assertionResult.getMessage();
96                 builder.m_info.message = builder.m_stream.str();
97 
98                 infoMessages.push_back( builder.m_info );
99             }
100         }
101         virtual ~AssertionStats();
102 
103 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
104         AssertionStats( AssertionStats const& )              = default;
105         AssertionStats( AssertionStats && )                  = default;
106         AssertionStats& operator = ( AssertionStats const& ) = default;
107         AssertionStats& operator = ( AssertionStats && )     = default;
108 #  endif
109 
110         AssertionResult assertionResult;
111         std::vector<MessageInfo> infoMessages;
112         Totals totals;
113     };
114 
115     struct SectionStats {
SectionStatsSectionStats116         SectionStats(   SectionInfo const& _sectionInfo,
117                         Counts const& _assertions,
118                         double _durationInSeconds,
119                         bool _missingAssertions )
120         :   sectionInfo( _sectionInfo ),
121             assertions( _assertions ),
122             durationInSeconds( _durationInSeconds ),
123             missingAssertions( _missingAssertions )
124         {}
125         virtual ~SectionStats();
126 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
127         SectionStats( SectionStats const& )              = default;
128         SectionStats( SectionStats && )                  = default;
129         SectionStats& operator = ( SectionStats const& ) = default;
130         SectionStats& operator = ( SectionStats && )     = default;
131 #  endif
132 
133         SectionInfo sectionInfo;
134         Counts assertions;
135         double durationInSeconds;
136         bool missingAssertions;
137     };
138 
139     struct TestCaseStats {
TestCaseStatsTestCaseStats140         TestCaseStats(  TestCaseInfo const& _testInfo,
141                         Totals const& _totals,
142                         std::string const& _stdOut,
143                         std::string const& _stdErr,
144                         bool _aborting )
145         : testInfo( _testInfo ),
146             totals( _totals ),
147             stdOut( _stdOut ),
148             stdErr( _stdErr ),
149             aborting( _aborting )
150         {}
151         virtual ~TestCaseStats();
152 
153 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
154         TestCaseStats( TestCaseStats const& )              = default;
155         TestCaseStats( TestCaseStats && )                  = default;
156         TestCaseStats& operator = ( TestCaseStats const& ) = default;
157         TestCaseStats& operator = ( TestCaseStats && )     = default;
158 #  endif
159 
160         TestCaseInfo testInfo;
161         Totals totals;
162         std::string stdOut;
163         std::string stdErr;
164         bool aborting;
165     };
166 
167     struct TestGroupStats {
TestGroupStatsTestGroupStats168         TestGroupStats( GroupInfo const& _groupInfo,
169                         Totals const& _totals,
170                         bool _aborting )
171         :   groupInfo( _groupInfo ),
172             totals( _totals ),
173             aborting( _aborting )
174         {}
TestGroupStatsTestGroupStats175         TestGroupStats( GroupInfo const& _groupInfo )
176         :   groupInfo( _groupInfo ),
177             aborting( false )
178         {}
179         virtual ~TestGroupStats();
180 
181 #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
182         TestGroupStats( TestGroupStats const& )              = default;
183         TestGroupStats( TestGroupStats && )                  = default;
184         TestGroupStats& operator = ( TestGroupStats const& ) = default;
185         TestGroupStats& operator = ( TestGroupStats && )     = default;
186 #  endif
187 
188         GroupInfo groupInfo;
189         Totals totals;
190         bool aborting;
191     };
192 
193     struct TestRunStats {
TestRunStatsTestRunStats194         TestRunStats(   TestRunInfo const& _runInfo,
195                         Totals const& _totals,
196                         bool _aborting )
197         :   runInfo( _runInfo ),
198             totals( _totals ),
199             aborting( _aborting )
200         {}
201         virtual ~TestRunStats();
202 
203 #  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
TestRunStatsTestRunStats204         TestRunStats( TestRunStats const& _other )
205         :   runInfo( _other.runInfo ),
206             totals( _other.totals ),
207             aborting( _other.aborting )
208         {}
209 #  else
210         TestRunStats( TestRunStats const& )              = default;
211         TestRunStats( TestRunStats && )                  = default;
212         TestRunStats& operator = ( TestRunStats const& ) = default;
213         TestRunStats& operator = ( TestRunStats && )     = default;
214 #  endif
215 
216         TestRunInfo runInfo;
217         Totals totals;
218         bool aborting;
219     };
220 
221     class MultipleReporters;
222 
223     struct IStreamingReporter : IShared {
224         virtual ~IStreamingReporter();
225 
226         // Implementing class must also provide the following static method:
227         // static std::string getDescription();
228 
229         virtual ReporterPreferences getPreferences() const = 0;
230 
231         virtual void noMatchingTestCases( std::string const& spec ) = 0;
232 
233         virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
234         virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
235 
236         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
237         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
238 
239         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
240 
241         // The return value indicates if the messages buffer should be cleared:
242         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
243 
244         virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
245         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
246         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
247         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
248 
249         virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
250 
tryAsMultiIStreamingReporter251         virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; }
252     };
253 
254 
255     struct IReporterFactory : IShared {
256         virtual ~IReporterFactory();
257         virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
258         virtual std::string getDescription() const = 0;
259     };
260 
261     struct IReporterRegistry {
262         typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
263         typedef std::vector<Ptr<IReporterFactory> > Listeners;
264 
265         virtual ~IReporterRegistry();
266         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
267         virtual FactoryMap const& getFactories() const = 0;
268         virtual Listeners const& getListeners() const = 0;
269     };
270 
271     Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
272 
273 }
274 
275 #endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
276