/ externals / catch / src / catch2 / reporters / catch_reporter_multi.cpp
catch_reporter_multi.cpp
  1  
  2  //              Copyright Catch2 Authors
  3  // Distributed under the Boost Software License, Version 1.0.
  4  //   (See accompanying file LICENSE.txt or copy at
  5  //        https://www.boost.org/LICENSE_1_0.txt)
  6  
  7  // SPDX-License-Identifier: BSL-1.0
  8  #include <catch2/reporters/catch_reporter_multi.hpp>
  9  
 10  #include <catch2/catch_config.hpp>
 11  #include <catch2/internal/catch_move_and_forward.hpp>
 12  #include <catch2/internal/catch_stdstreams.hpp>
 13  
 14  #include <ostream>
 15  
 16  namespace Catch {
 17      void MultiReporter::updatePreferences(IEventListener const& reporterish) {
 18          m_preferences.shouldRedirectStdOut |=
 19              reporterish.getPreferences().shouldRedirectStdOut;
 20          m_preferences.shouldReportAllAssertions |=
 21              reporterish.getPreferences().shouldReportAllAssertions;
 22      }
 23  
 24      void MultiReporter::addListener( IEventListenerPtr&& listener ) {
 25          updatePreferences(*listener);
 26          m_reporterLikes.insert(m_reporterLikes.begin() + m_insertedListeners, CATCH_MOVE(listener) );
 27          ++m_insertedListeners;
 28      }
 29  
 30      void MultiReporter::addReporter( IEventListenerPtr&& reporter ) {
 31          updatePreferences(*reporter);
 32  
 33          // We will need to output the captured stdout if there are reporters
 34          // that do not want it captured.
 35          // We do not consider listeners, because it is generally assumed that
 36          // listeners are output-transparent, even though they can ask for stdout
 37          // capture to do something with it.
 38          m_haveNoncapturingReporters |= !reporter->getPreferences().shouldRedirectStdOut;
 39  
 40          // Reporters can always be placed to the back without breaking the
 41          // reporting order
 42          m_reporterLikes.push_back( CATCH_MOVE( reporter ) );
 43      }
 44  
 45      void MultiReporter::noMatchingTestCases( StringRef unmatchedSpec ) {
 46          for ( auto& reporterish : m_reporterLikes ) {
 47              reporterish->noMatchingTestCases( unmatchedSpec );
 48          }
 49      }
 50  
 51      void MultiReporter::fatalErrorEncountered( StringRef error ) {
 52          for ( auto& reporterish : m_reporterLikes ) {
 53              reporterish->fatalErrorEncountered( error );
 54          }
 55      }
 56  
 57      void MultiReporter::reportInvalidTestSpec( StringRef arg ) {
 58          for ( auto& reporterish : m_reporterLikes ) {
 59              reporterish->reportInvalidTestSpec( arg );
 60          }
 61      }
 62  
 63      void MultiReporter::benchmarkPreparing( StringRef name ) {
 64          for (auto& reporterish : m_reporterLikes) {
 65              reporterish->benchmarkPreparing(name);
 66          }
 67      }
 68      void MultiReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {
 69          for ( auto& reporterish : m_reporterLikes ) {
 70              reporterish->benchmarkStarting( benchmarkInfo );
 71          }
 72      }
 73      void MultiReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {
 74          for ( auto& reporterish : m_reporterLikes ) {
 75              reporterish->benchmarkEnded( benchmarkStats );
 76          }
 77      }
 78  
 79      void MultiReporter::benchmarkFailed( StringRef error ) {
 80          for (auto& reporterish : m_reporterLikes) {
 81              reporterish->benchmarkFailed(error);
 82          }
 83      }
 84  
 85      void MultiReporter::testRunStarting( TestRunInfo const& testRunInfo ) {
 86          for ( auto& reporterish : m_reporterLikes ) {
 87              reporterish->testRunStarting( testRunInfo );
 88          }
 89      }
 90  
 91      void MultiReporter::testCaseStarting( TestCaseInfo const& testInfo ) {
 92          for ( auto& reporterish : m_reporterLikes ) {
 93              reporterish->testCaseStarting( testInfo );
 94          }
 95      }
 96  
 97      void
 98      MultiReporter::testCasePartialStarting( TestCaseInfo const& testInfo,
 99                                                  uint64_t partNumber ) {
100          for ( auto& reporterish : m_reporterLikes ) {
101              reporterish->testCasePartialStarting( testInfo, partNumber );
102          }
103      }
104  
105      void MultiReporter::sectionStarting( SectionInfo const& sectionInfo ) {
106          for ( auto& reporterish : m_reporterLikes ) {
107              reporterish->sectionStarting( sectionInfo );
108          }
109      }
110  
111      void MultiReporter::assertionStarting( AssertionInfo const& assertionInfo ) {
112          for ( auto& reporterish : m_reporterLikes ) {
113              reporterish->assertionStarting( assertionInfo );
114          }
115      }
116  
117      void MultiReporter::assertionEnded( AssertionStats const& assertionStats ) {
118          const bool reportByDefault =
119              assertionStats.assertionResult.getResultType() != ResultWas::Ok ||
120              m_config->includeSuccessfulResults();
121  
122          for ( auto & reporterish : m_reporterLikes ) {
123              if ( reportByDefault ||
124                   reporterish->getPreferences().shouldReportAllAssertions ) {
125                      reporterish->assertionEnded( assertionStats );
126              }
127          }
128      }
129  
130      void MultiReporter::sectionEnded( SectionStats const& sectionStats ) {
131          for ( auto& reporterish : m_reporterLikes ) {
132              reporterish->sectionEnded( sectionStats );
133          }
134      }
135  
136      void MultiReporter::testCasePartialEnded( TestCaseStats const& testStats,
137                                                    uint64_t partNumber ) {
138          if ( m_preferences.shouldRedirectStdOut &&
139               m_haveNoncapturingReporters ) {
140              if ( !testStats.stdOut.empty() ) {
141                  Catch::cout() << testStats.stdOut << std::flush;
142              }
143              if ( !testStats.stdErr.empty() ) {
144                  Catch::cerr() << testStats.stdErr << std::flush;
145              }
146          }
147  
148          for ( auto& reporterish : m_reporterLikes ) {
149              reporterish->testCasePartialEnded( testStats, partNumber );
150          }
151      }
152  
153      void MultiReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
154          for ( auto& reporterish : m_reporterLikes ) {
155              reporterish->testCaseEnded( testCaseStats );
156          }
157      }
158  
159      void MultiReporter::testRunEnded( TestRunStats const& testRunStats ) {
160          for ( auto& reporterish : m_reporterLikes ) {
161              reporterish->testRunEnded( testRunStats );
162          }
163      }
164  
165  
166      void MultiReporter::skipTest( TestCaseInfo const& testInfo ) {
167          for ( auto& reporterish : m_reporterLikes ) {
168              reporterish->skipTest( testInfo );
169          }
170      }
171  
172      void MultiReporter::listReporters(std::vector<ReporterDescription> const& descriptions) {
173          for (auto& reporterish : m_reporterLikes) {
174              reporterish->listReporters(descriptions);
175          }
176      }
177  
178      void MultiReporter::listListeners(
179          std::vector<ListenerDescription> const& descriptions ) {
180          for ( auto& reporterish : m_reporterLikes ) {
181              reporterish->listListeners( descriptions );
182          }
183      }
184  
185      void MultiReporter::listTests(std::vector<TestCaseHandle> const& tests) {
186          for (auto& reporterish : m_reporterLikes) {
187              reporterish->listTests(tests);
188          }
189      }
190  
191      void MultiReporter::listTags(std::vector<TagInfo> const& tags) {
192          for (auto& reporterish : m_reporterLikes) {
193              reporterish->listTags(tags);
194          }
195      }
196  
197  } // end namespace Catch