1 /*
2  *  Created by Phil on 5/08/2015.
3  *  Copyright 2015 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_REPORTER_MULTI_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
10 
11 #include "../internal/catch_interfaces_reporter.h"
12 
13 namespace Catch {
14 
15 class MultipleReporters : public SharedImpl<IStreamingReporter> {
16     typedef std::vector<Ptr<IStreamingReporter> > Reporters;
17     Reporters m_reporters;
18 
19 public:
add(Ptr<IStreamingReporter> const & reporter)20     void add( Ptr<IStreamingReporter> const& reporter ) {
21         m_reporters.push_back( reporter );
22     }
23 
24 public: // IStreamingReporter
25 
getPreferences() const26     virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
27         return m_reporters[0]->getPreferences();
28     }
29 
noMatchingTestCases(std::string const & spec)30     virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
31         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
32                 it != itEnd;
33                 ++it )
34             (*it)->noMatchingTestCases( spec );
35     }
36 
37 
testRunStarting(TestRunInfo const & testRunInfo)38     virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
39         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
40                 it != itEnd;
41                 ++it )
42             (*it)->testRunStarting( testRunInfo );
43     }
44 
testGroupStarting(GroupInfo const & groupInfo)45     virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
46         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
47                 it != itEnd;
48                 ++it )
49             (*it)->testGroupStarting( groupInfo );
50     }
51 
52 
testCaseStarting(TestCaseInfo const & testInfo)53     virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
54         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
55                 it != itEnd;
56                 ++it )
57             (*it)->testCaseStarting( testInfo );
58     }
59 
sectionStarting(SectionInfo const & sectionInfo)60     virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
61         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
62                 it != itEnd;
63                 ++it )
64             (*it)->sectionStarting( sectionInfo );
65     }
66 
67 
assertionStarting(AssertionInfo const & assertionInfo)68     virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
69         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
70                 it != itEnd;
71                 ++it )
72             (*it)->assertionStarting( assertionInfo );
73     }
74 
75 
76     // The return value indicates if the messages buffer should be cleared:
assertionEnded(AssertionStats const & assertionStats)77     virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
78         bool clearBuffer = false;
79         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
80                 it != itEnd;
81                 ++it )
82             clearBuffer |= (*it)->assertionEnded( assertionStats );
83         return clearBuffer;
84     }
85 
sectionEnded(SectionStats const & sectionStats)86     virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
87         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
88                 it != itEnd;
89                 ++it )
90             (*it)->sectionEnded( sectionStats );
91     }
92 
testCaseEnded(TestCaseStats const & testCaseStats)93     virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
94         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
95                 it != itEnd;
96                 ++it )
97             (*it)->testCaseEnded( testCaseStats );
98     }
99 
testGroupEnded(TestGroupStats const & testGroupStats)100     virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
101         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
102                 it != itEnd;
103                 ++it )
104             (*it)->testGroupEnded( testGroupStats );
105     }
106 
testRunEnded(TestRunStats const & testRunStats)107     virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
108         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
109                 it != itEnd;
110                 ++it )
111             (*it)->testRunEnded( testRunStats );
112     }
113 
114 
skipTest(TestCaseInfo const & testInfo)115     virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
116         for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
117                 it != itEnd;
118                 ++it )
119             (*it)->skipTest( testInfo );
120     }
121 
tryAsMulti()122     virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE {
123         return this;
124     }
125 
126 };
127 
addReporter(Ptr<IStreamingReporter> const & existingReporter,Ptr<IStreamingReporter> const & additionalReporter)128 Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
129     Ptr<IStreamingReporter> resultingReporter;
130 
131     if( existingReporter ) {
132         MultipleReporters* multi = existingReporter->tryAsMulti();
133         if( !multi ) {
134             multi = new MultipleReporters;
135             resultingReporter = Ptr<IStreamingReporter>( multi );
136             if( existingReporter )
137                 multi->add( existingReporter );
138         }
139         else
140             resultingReporter = existingReporter;
141         multi->add( additionalReporter );
142     }
143     else
144         resultingReporter = additionalReporter;
145 
146     return resultingReporter;
147 }
148 
149 
150 } // end namespace Catch
151 
152 #endif // TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
153