Store IStream instance owning ptrs in reporter instances

This ended up being a surprisingly large refactoring, motivated
by removing a `const_cast` from `Config`'s handling of reporter
streams, forced by previous commit.
This commit is contained in:
Martin Hořeňovský 2022-04-12 21:22:43 +02:00
parent 4f09f1120b
commit 79d1e82381
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
38 changed files with 124 additions and 109 deletions

View File

@ -76,20 +76,28 @@ namespace Catch {
} }
#endif #endif
// We now fixup the reporter specs to handle default output spec,
// default colour spec, etc
bool defaultOutputUsed = false; bool defaultOutputUsed = false;
m_reporterStreams.reserve( m_data.reporterSpecifications.size() ); for ( auto& reporterSpec : m_data.reporterSpecifications ) {
for ( auto const& reporterSpec : m_data.reporterSpecifications ) {
if ( reporterSpec.outputFile().none() ) { if ( reporterSpec.outputFile().none() ) {
CATCH_ENFORCE( !defaultOutputUsed, CATCH_ENFORCE( !defaultOutputUsed,
"Internal error: cannot use default output for " "Internal error: cannot use default output for "
"multiple reporters" ); "multiple reporters" );
defaultOutputUsed = true; defaultOutputUsed = true;
m_reporterStreams.push_back( reporterSpec = ReporterSpec{ reporterSpec.name(),
makeStream( data.defaultOutputFilename ) ); data.defaultOutputFilename,
} else { reporterSpec.colourMode(),
m_reporterStreams.push_back( reporterSpec.customOptions() };
makeStream( *reporterSpec.outputFile() ) ); }
if ( reporterSpec.colourMode().none() ) {
reporterSpec = ReporterSpec{ reporterSpec.name(),
reporterSpec.outputFile(),
data.defaultColourMode,
reporterSpec.customOptions() };
} }
} }
} }
@ -108,10 +116,6 @@ namespace Catch {
return m_data.reporterSpecifications; return m_data.reporterSpecifications;
} }
IStream* Config::getReporterOutputStream(std::size_t reporterIdx) const {
return const_cast<IStream*>(m_reporterStreams.at(reporterIdx).get());
}
TestSpec const& Config::testSpec() const { return m_testSpec; } TestSpec const& Config::testSpec() const { return m_testSpec; }
bool Config::hasTestFilters() const { return m_hasTestFilters; } bool Config::hasTestFilters() const { return m_hasTestFilters; }

View File

@ -81,7 +81,6 @@ namespace Catch {
bool listReporters() const; bool listReporters() const;
std::vector<ReporterSpec> const& getReporterSpecs() const; std::vector<ReporterSpec> const& getReporterSpecs() const;
IStream* getReporterOutputStream(std::size_t reporterIdx) const;
std::vector<std::string> const& getTestsOrTags() const override; std::vector<std::string> const& getTestsOrTags() const override;
std::vector<std::string> const& getSectionsToRun() const override; std::vector<std::string> const& getSectionsToRun() const override;
@ -117,8 +116,6 @@ namespace Catch {
private: private:
ConfigData m_data; ConfigData m_data;
std::vector<Detail::unique_ptr<IStream>> m_reporterStreams;
TestSpec m_testSpec; TestSpec m_testSpec;
bool m_hasTestFilters = false; bool m_hasTestFilters = false;
}; };

View File

@ -34,8 +34,8 @@ namespace Catch {
namespace { namespace {
const int MaxExitCode = 255; const int MaxExitCode = 255;
IEventListenerPtr createReporter(std::string const& reporterName, ReporterConfig const& config) { IEventListenerPtr createReporter(std::string const& reporterName, ReporterConfig&& config) {
auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config); auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, CATCH_MOVE(config));
CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << '\''); CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << '\'');
return reporter; return reporter;
@ -45,13 +45,12 @@ namespace Catch {
if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty() if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()
&& config->getReporterSpecs().size() == 1) { && config->getReporterSpecs().size() == 1) {
auto const& spec = config->getReporterSpecs()[0]; auto const& spec = config->getReporterSpecs()[0];
auto stream = config->getReporterOutputStream(0);
return createReporter( return createReporter(
config->getReporterSpecs()[0].name(), spec.name(),
ReporterConfig( ReporterConfig(
config, config,
stream, makeStream(*spec.outputFile()),
spec.colourMode().valueOr( config->defaultColourMode() ), *spec.colourMode(),
spec.customOptions() ) ); spec.customOptions() ) );
} }
@ -64,13 +63,11 @@ namespace Catch {
std::size_t reporterIdx = 0; std::size_t reporterIdx = 0;
for (auto const& reporterSpec : config->getReporterSpecs()) { for (auto const& reporterSpec : config->getReporterSpecs()) {
auto stream = config->getReporterOutputStream(reporterIdx);
multi->addReporter( createReporter( multi->addReporter( createReporter(
reporterSpec.name(), reporterSpec.name(),
ReporterConfig( config, ReporterConfig( config,
stream, makeStream( *reporterSpec.outputFile() ),
reporterSpec.colourMode().valueOr( *reporterSpec.colourMode(),
config->defaultColourMode() ),
reporterSpec.customOptions() ) ) ); reporterSpec.customOptions() ) ) );
reporterIdx++; reporterIdx++;
} }

View File

@ -17,21 +17,25 @@
#include <catch2/internal/catch_move_and_forward.hpp> #include <catch2/internal/catch_move_and_forward.hpp>
#include <algorithm> #include <algorithm>
#include <cassert>
#include <iomanip> #include <iomanip>
namespace Catch { namespace Catch {
ReporterConfig::ReporterConfig( ReporterConfig::ReporterConfig(
IConfig const* _fullConfig, IConfig const* _fullConfig,
IStream* _stream, Detail::unique_ptr<IStream> _stream,
ColourMode colourMode, ColourMode colourMode,
std::map<std::string, std::string> customOptions ): std::map<std::string, std::string> customOptions ):
m_stream( _stream ), m_stream( CATCH_MOVE(_stream) ),
m_fullConfig( _fullConfig ), m_fullConfig( _fullConfig ),
m_colourMode( colourMode ), m_colourMode( colourMode ),
m_customOptions( CATCH_MOVE( customOptions ) ) {} m_customOptions( CATCH_MOVE( customOptions ) ) {}
IStream* ReporterConfig::stream() const { return m_stream; } Detail::unique_ptr<IStream> ReporterConfig::takeStream() && {
assert( m_stream );
return CATCH_MOVE( m_stream );
}
IConfig const * ReporterConfig::fullConfig() const { return m_fullConfig; } IConfig const * ReporterConfig::fullConfig() const { return m_fullConfig; }
ColourMode ReporterConfig::colourMode() const { return m_colourMode; } ColourMode ReporterConfig::colourMode() const { return m_colourMode; }

View File

@ -36,17 +36,17 @@ namespace Catch {
struct ReporterConfig { struct ReporterConfig {
ReporterConfig( IConfig const* _fullConfig, ReporterConfig( IConfig const* _fullConfig,
IStream* _stream, Detail::unique_ptr<IStream> _stream,
ColourMode colourMode, ColourMode colourMode,
std::map<std::string, std::string> customOptions ); std::map<std::string, std::string> customOptions );
IStream* stream() const; Detail::unique_ptr<IStream> takeStream() &&;
IConfig const* fullConfig() const; IConfig const* fullConfig() const;
ColourMode colourMode() const; ColourMode colourMode() const;
std::map<std::string, std::string> const& customOptions() const; std::map<std::string, std::string> const& customOptions() const;
private: private:
IStream* m_stream; Detail::unique_ptr<IStream> m_stream;
IConfig const* m_fullConfig; IConfig const* m_fullConfig;
ColourMode m_colourMode; ColourMode m_colourMode;
std::map<std::string, std::string> m_customOptions; std::map<std::string, std::string> m_customOptions;

View File

@ -25,7 +25,7 @@ namespace Catch {
virtual ~IReporterFactory(); // = default virtual ~IReporterFactory(); // = default
virtual IEventListenerPtr virtual IEventListenerPtr
create( ReporterConfig const& config ) const = 0; create( ReporterConfig&& config ) const = 0;
virtual std::string getDescription() const = 0; virtual std::string getDescription() const = 0;
}; };
using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>; using IReporterFactoryPtr = Detail::unique_ptr<IReporterFactory>;

View File

@ -32,7 +32,7 @@ namespace Catch {
using Listeners = std::vector<Detail::unique_ptr<EventListenerFactory>>; using Listeners = std::vector<Detail::unique_ptr<EventListenerFactory>>;
virtual ~IReporterRegistry(); // = default virtual ~IReporterRegistry(); // = default
virtual IEventListenerPtr create( std::string const& name, ReporterConfig const& config ) const = 0; virtual IEventListenerPtr create( std::string const& name, ReporterConfig&& config ) const = 0;
virtual FactoryMap const& getFactories() const = 0; virtual FactoryMap const& getFactories() const = 0;
virtual Listeners const& getListeners() const = 0; virtual Listeners const& getListeners() const = 0;
}; };

View File

@ -37,11 +37,11 @@ namespace Catch {
ReporterRegistry::~ReporterRegistry() = default; ReporterRegistry::~ReporterRegistry() = default;
IEventListenerPtr ReporterRegistry::create( std::string const& name, ReporterConfig const& config ) const { IEventListenerPtr ReporterRegistry::create( std::string const& name, ReporterConfig&& config ) const {
auto it = m_factories.find( name ); auto it = m_factories.find( name );
if( it == m_factories.end() ) if( it == m_factories.end() )
return nullptr; return nullptr;
return it->second->create( config ); return it->second->create( CATCH_MOVE(config) );
} }
void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr factory ) { void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr factory ) {

View File

@ -21,7 +21,7 @@ namespace Catch {
ReporterRegistry(); ReporterRegistry();
~ReporterRegistry() override; // = default, out of line to allow fwd decl ~ReporterRegistry() override; // = default, out of line to allow fwd decl
IEventListenerPtr create( std::string const& name, ReporterConfig const& config ) const override; IEventListenerPtr create( std::string const& name, ReporterConfig&& config ) const override;
void registerReporter( std::string const& name, IReporterFactoryPtr factory ); void registerReporter( std::string const& name, IReporterFactoryPtr factory );
void registerListener( Detail::unique_ptr<EventListenerFactory> factory ); void registerListener( Detail::unique_ptr<EventListenerFactory> factory );

View File

@ -15,7 +15,6 @@ namespace Catch {
class AutomakeReporter final : public StreamingReporterBase { class AutomakeReporter final : public StreamingReporterBase {
public: public:
using StreamingReporterBase::StreamingReporterBase; using StreamingReporterBase::StreamingReporterBase;
~AutomakeReporter() override; ~AutomakeReporter() override;
static std::string getDescription() { static std::string getDescription() {

View File

@ -14,11 +14,11 @@
namespace Catch { namespace Catch {
ReporterBase::ReporterBase( ReporterConfig const& config ): ReporterBase::ReporterBase( ReporterConfig&& config ):
IEventListener( config.fullConfig() ), IEventListener( config.fullConfig() ),
m_wrapped_stream( config.stream() ), m_wrapped_stream( CATCH_MOVE(config).takeStream() ),
m_stream( m_wrapped_stream->stream() ), m_stream( m_wrapped_stream->stream() ),
m_colour( makeColourImpl( config.colourMode(), m_wrapped_stream ) ), m_colour( makeColourImpl( config.colourMode(), m_wrapped_stream.get() ) ),
m_customOptions( config.customOptions() ) m_customOptions( config.customOptions() )
{} {}

View File

@ -29,7 +29,7 @@ namespace Catch {
class ReporterBase : public IEventListener { class ReporterBase : public IEventListener {
protected: protected:
//! The stream wrapper as passed to us by outside code //! The stream wrapper as passed to us by outside code
IStream* m_wrapped_stream; Detail::unique_ptr<IStream> m_wrapped_stream;
//! Cached output stream from `m_wrapped_stream` to reduce //! Cached output stream from `m_wrapped_stream` to reduce
//! number of indirect calls needed to write output. //! number of indirect calls needed to write output.
std::ostream& m_stream; std::ostream& m_stream;
@ -39,7 +39,7 @@ namespace Catch {
std::map<std::string, std::string> m_customOptions; std::map<std::string, std::string> m_customOptions;
public: public:
ReporterBase( ReporterConfig const& config ); ReporterBase( ReporterConfig&& config );
~ReporterBase() override; // = default; ~ReporterBase() override; // = default;
/** /**

View File

@ -354,8 +354,8 @@ public:
} }
}; };
ConsoleReporter::ConsoleReporter(ReporterConfig const& config) ConsoleReporter::ConsoleReporter(ReporterConfig&& config):
: StreamingReporterBase(config), StreamingReporterBase( CATCH_MOVE( config ) ),
m_tablePrinter(Detail::make_unique<TablePrinter>(m_stream, m_tablePrinter(Detail::make_unique<TablePrinter>(m_stream,
[&config]() -> std::vector<ColumnInfo> { [&config]() -> std::vector<ColumnInfo> {
if (config.fullConfig()->benchmarkNoAnalysis()) if (config.fullConfig()->benchmarkNoAnalysis())

View File

@ -20,7 +20,7 @@ namespace Catch {
Detail::unique_ptr<TablePrinter> m_tablePrinter; Detail::unique_ptr<TablePrinter> m_tablePrinter;
public: public:
ConsoleReporter(ReporterConfig const& config); ConsoleReporter(ReporterConfig&& config);
~ConsoleReporter() override; ~ConsoleReporter() override;
static std::string getDescription(); static std::string getDescription();

View File

@ -13,6 +13,7 @@
#include <catch2/internal/catch_textflow.hpp> #include <catch2/internal/catch_textflow.hpp>
#include <catch2/interfaces/catch_interfaces_config.hpp> #include <catch2/interfaces/catch_interfaces_config.hpp>
#include <catch2/catch_test_case_info.hpp> #include <catch2/catch_test_case_info.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <cassert> #include <cassert>
#include <ctime> #include <ctime>
@ -68,8 +69,8 @@ namespace Catch {
} // anonymous namespace } // anonymous namespace
JunitReporter::JunitReporter( ReporterConfig const& _config ) JunitReporter::JunitReporter( ReporterConfig&& _config )
: CumulativeReporterBase( _config ), : CumulativeReporterBase( CATCH_MOVE(_config) ),
xml( m_stream ) xml( m_stream )
{ {
m_preferences.shouldRedirectStdOut = true; m_preferences.shouldRedirectStdOut = true;

View File

@ -17,7 +17,7 @@ namespace Catch {
class JunitReporter final : public CumulativeReporterBase { class JunitReporter final : public CumulativeReporterBase {
public: public:
JunitReporter(ReporterConfig const& _config); JunitReporter(ReporterConfig&& _config);
~JunitReporter() override = default; ~JunitReporter() override = default;

View File

@ -13,6 +13,7 @@
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp> #include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
#include <catch2/internal/catch_compiler_capabilities.hpp> #include <catch2/internal/catch_compiler_capabilities.hpp>
#include <catch2/internal/catch_unique_ptr.hpp> #include <catch2/internal/catch_unique_ptr.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
namespace Catch { namespace Catch {
@ -22,8 +23,8 @@ namespace Catch {
template <typename T> template <typename T>
class ReporterFactory : public IReporterFactory { class ReporterFactory : public IReporterFactory {
IEventListenerPtr create( ReporterConfig const& config ) const override { IEventListenerPtr create( ReporterConfig&& config ) const override {
return Detail::make_unique<T>( config ); return Detail::make_unique<T>( CATCH_MOVE(config) );
} }
std::string getDescription() const override { std::string getDescription() const override {

View File

@ -11,13 +11,14 @@
#include <catch2/reporters/catch_reporter_cumulative_base.hpp> #include <catch2/reporters/catch_reporter_cumulative_base.hpp>
#include <catch2/internal/catch_xmlwriter.hpp> #include <catch2/internal/catch_xmlwriter.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
namespace Catch { namespace Catch {
class SonarQubeReporter final : public CumulativeReporterBase { class SonarQubeReporter final : public CumulativeReporterBase {
public: public:
SonarQubeReporter(ReporterConfig const& config) SonarQubeReporter(ReporterConfig&& config)
: CumulativeReporterBase(config) : CumulativeReporterBase(CATCH_MOVE(config))
, xml(m_stream) { , xml(m_stream) {
m_preferences.shouldRedirectStdOut = true; m_preferences.shouldRedirectStdOut = true;
m_preferences.shouldReportAllAssertions = true; m_preferences.shouldReportAllAssertions = true;

View File

@ -9,13 +9,14 @@
#define CATCH_REPORTER_TAP_HPP_INCLUDED #define CATCH_REPORTER_TAP_HPP_INCLUDED
#include <catch2/reporters/catch_reporter_streaming_base.hpp> #include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
namespace Catch { namespace Catch {
class TAPReporter final : public StreamingReporterBase { class TAPReporter final : public StreamingReporterBase {
public: public:
TAPReporter( ReporterConfig const& config ): TAPReporter( ReporterConfig&& config ):
StreamingReporterBase( config ) { StreamingReporterBase( CATCH_MOVE(config) ) {
m_preferences.shouldReportAllAssertions = true; m_preferences.shouldReportAllAssertions = true;
} }
~TAPReporter() override = default; ~TAPReporter() override = default;

View File

@ -22,8 +22,8 @@ namespace Catch {
class TeamCityReporter final : public StreamingReporterBase { class TeamCityReporter final : public StreamingReporterBase {
public: public:
TeamCityReporter( ReporterConfig const& _config ) TeamCityReporter( ReporterConfig&& _config )
: StreamingReporterBase( _config ) : StreamingReporterBase( CATCH_MOVE(_config) )
{ {
m_preferences.shouldRedirectStdOut = true; m_preferences.shouldRedirectStdOut = true;
} }

View File

@ -13,6 +13,7 @@
#include <catch2/internal/catch_string_manip.hpp> #include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_list.hpp> #include <catch2/internal/catch_list.hpp>
#include <catch2/catch_test_case_info.hpp> #include <catch2/catch_test_case_info.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(push) #pragma warning(push)
@ -22,8 +23,8 @@
#endif #endif
namespace Catch { namespace Catch {
XmlReporter::XmlReporter( ReporterConfig const& _config ) XmlReporter::XmlReporter( ReporterConfig&& _config )
: StreamingReporterBase( _config ), : StreamingReporterBase( CATCH_MOVE(_config) ),
m_xml(m_stream) m_xml(m_stream)
{ {
m_preferences.shouldRedirectStdOut = true; m_preferences.shouldRedirectStdOut = true;

View File

@ -17,7 +17,7 @@
namespace Catch { namespace Catch {
class XmlReporter : public StreamingReporterBase { class XmlReporter : public StreamingReporterBase {
public: public:
XmlReporter(ReporterConfig const& _config); XmlReporter(ReporterConfig&& _config);
~XmlReporter() override; ~XmlReporter() override;

View File

@ -20,12 +20,13 @@
#include <catch2/reporters/catch_reporter_registrars.hpp> #include <catch2/reporters/catch_reporter_registrars.hpp>
#include <iostream> #include <iostream>
#include <utility>
class CumulativeBenchmarkReporter final : public Catch::CumulativeReporterBase { class CumulativeBenchmarkReporter final : public Catch::CumulativeReporterBase {
public: public:
CumulativeBenchmarkReporter(Catch::ReporterConfig const& _config) : CumulativeBenchmarkReporter(Catch::ReporterConfig&& _config) :
CumulativeReporterBase(_config) { CumulativeReporterBase(std::move(_config)) {
m_preferences.shouldReportAllAssertions = true; m_preferences.shouldReportAllAssertions = true;
} }

View File

@ -19,11 +19,12 @@
#include <catch2/reporters/catch_reporter_registrars.hpp> #include <catch2/reporters/catch_reporter_registrars.hpp>
#include <iostream> #include <iostream>
#include <utility>
class TestReporter : public Catch::StreamingReporterBase { class TestReporter : public Catch::StreamingReporterBase {
public: public:
TestReporter(Catch::ReporterConfig const& _config): TestReporter(Catch::ReporterConfig&& _config):
StreamingReporterBase(_config) { StreamingReporterBase(std::move(_config)) {
std::cout << "TestReporter constructed\n"; std::cout << "TestReporter constructed\n";
} }

View File

@ -16,13 +16,14 @@
#include <catch2/reporters/catch_reporter_registrars.hpp> #include <catch2/reporters/catch_reporter_registrars.hpp>
#include <iostream> #include <iostream>
#include <utility>
namespace { namespace {
class TestReporter : public Catch::StreamingReporterBase { class TestReporter : public Catch::StreamingReporterBase {
public: public:
TestReporter(Catch::ReporterConfig const& _config): TestReporter(Catch::ReporterConfig&& _config):
StreamingReporterBase(_config) { StreamingReporterBase(std::move(_config)) {
m_preferences.shouldReportAllAssertions = false; m_preferences.shouldReportAllAssertions = false;
std::cout << "X26 - TestReporter constructed\n"; std::cout << "X26 - TestReporter constructed\n";
} }

View File

@ -26,6 +26,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <utility>
class TestReporter : public Catch::StreamingReporterBase { class TestReporter : public Catch::StreamingReporterBase {
std::string stdOutString( uint64_t iter ){ std::string stdOutString( uint64_t iter ){
@ -36,8 +37,8 @@ class TestReporter : public Catch::StreamingReporterBase {
} }
public: public:
TestReporter( Catch::ReporterConfig const& _config ): TestReporter( Catch::ReporterConfig&& _config ):
StreamingReporterBase( _config ) { StreamingReporterBase( std::move(_config) ) {
m_preferences.shouldRedirectStdOut = true; m_preferences.shouldRedirectStdOut = true;
std::cout << "X27 - TestReporter constructed\n"; std::cout << "X27 - TestReporter constructed\n";
} }

View File

@ -19,7 +19,9 @@
#include <catch2/reporters/catch_reporter_event_listener.hpp> #include <catch2/reporters/catch_reporter_event_listener.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp> #include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp> #include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <iostream> #include <iostream>
#include <utility>
namespace { namespace {
@ -54,8 +56,8 @@ namespace {
class TestReporter : public Catch::StreamingReporterBase { class TestReporter : public Catch::StreamingReporterBase {
public: public:
TestReporter( Catch::ReporterConfig const& _config ): TestReporter( Catch::ReporterConfig&& _config ):
StreamingReporterBase( _config ) { StreamingReporterBase( std::move(_config) ) {
std::cout << "X28 - TestReporter constructed\n"; std::cout << "X28 - TestReporter constructed\n";
} }

View File

@ -25,8 +25,8 @@
class TestReporter : public Catch::StreamingReporterBase { class TestReporter : public Catch::StreamingReporterBase {
public: public:
TestReporter( Catch::ReporterConfig const& _config ): TestReporter( Catch::ReporterConfig&& _config ):
StreamingReporterBase( _config ) { StreamingReporterBase( std::move(_config) ) {
std::cout << "X29 - TestReporter constructed\n"; std::cout << "X29 - TestReporter constructed\n";
} }

View File

@ -1317,7 +1317,7 @@ CmdLine.tests.cpp:<line number>: passed: config.noThrow == false for: false == f
CmdLine.tests.cpp:<line number>: passed: config.reporterSpecifications.empty() for: true CmdLine.tests.cpp:<line number>: passed: config.reporterSpecifications.empty() for: true
CmdLine.tests.cpp:<line number>: passed: !(cfg.hasTestFilters()) for: !false CmdLine.tests.cpp:<line number>: passed: !(cfg.hasTestFilters()) for: !false
CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs().size() == 1 for: 1 == 1 CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs().size() == 1 for: 1 == 1
CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } for: {?} == {?} CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} } for: {?} == {?}
CmdLine.tests.cpp:<line number>: passed: result for: {?} CmdLine.tests.cpp:<line number>: passed: result for: {?}
CmdLine.tests.cpp:<line number>: passed: cfg.hasTestFilters() for: true CmdLine.tests.cpp:<line number>: passed: cfg.hasTestFilters() for: true
CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(*fakeTestCase("notIncluded")) == false for: false == false CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(*fakeTestCase("notIncluded")) == false for: false == false

View File

@ -1315,7 +1315,7 @@ CmdLine.tests.cpp:<line number>: passed: config.noThrow == false for: false == f
CmdLine.tests.cpp:<line number>: passed: config.reporterSpecifications.empty() for: true CmdLine.tests.cpp:<line number>: passed: config.reporterSpecifications.empty() for: true
CmdLine.tests.cpp:<line number>: passed: !(cfg.hasTestFilters()) for: !false CmdLine.tests.cpp:<line number>: passed: !(cfg.hasTestFilters()) for: !false
CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs().size() == 1 for: 1 == 1 CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs().size() == 1 for: 1 == 1
CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } for: {?} == {?} CmdLine.tests.cpp:<line number>: passed: cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} } for: {?} == {?}
CmdLine.tests.cpp:<line number>: passed: result for: {?} CmdLine.tests.cpp:<line number>: passed: result for: {?}
CmdLine.tests.cpp:<line number>: passed: cfg.hasTestFilters() for: true CmdLine.tests.cpp:<line number>: passed: cfg.hasTestFilters() for: true
CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(*fakeTestCase("notIncluded")) == false for: false == false CmdLine.tests.cpp:<line number>: passed: cfg.testSpec().matches(*fakeTestCase("notIncluded")) == false for: false == false

View File

@ -9438,7 +9438,7 @@ with expansion:
1 == 1 1 == 1
CmdLine.tests.cpp:<line number>: PASSED: CmdLine.tests.cpp:<line number>: PASSED:
CHECK( cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } ) CHECK( cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} } )
with expansion: with expansion:
{?} == {?} {?} == {?}

View File

@ -9436,7 +9436,7 @@ with expansion:
1 == 1 1 == 1
CmdLine.tests.cpp:<line number>: PASSED: CmdLine.tests.cpp:<line number>: PASSED:
CHECK( cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } ) CHECK( cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} } )
with expansion: with expansion:
{?} == {?} {?} == {?}

View File

@ -2481,7 +2481,7 @@ ok {test-number} - !(cfg.hasTestFilters()) for: !false
# Process can be configured on command line # Process can be configured on command line
ok {test-number} - cfg.getReporterSpecs().size() == 1 for: 1 == 1 ok {test-number} - cfg.getReporterSpecs().size() == 1 for: 1 == 1
# Process can be configured on command line # Process can be configured on command line
ok {test-number} - cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } for: {?} == {?} ok {test-number} - cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} } for: {?} == {?}
# Process can be configured on command line # Process can be configured on command line
ok {test-number} - result for: {?} ok {test-number} - result for: {?}
# Process can be configured on command line # Process can be configured on command line

View File

@ -2479,7 +2479,7 @@ ok {test-number} - !(cfg.hasTestFilters()) for: !false
# Process can be configured on command line # Process can be configured on command line
ok {test-number} - cfg.getReporterSpecs().size() == 1 for: 1 == 1 ok {test-number} - cfg.getReporterSpecs().size() == 1 for: 1 == 1
# Process can be configured on command line # Process can be configured on command line
ok {test-number} - cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } for: {?} == {?} ok {test-number} - cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} } for: {?} == {?}
# Process can be configured on command line # Process can be configured on command line
ok {test-number} - result for: {?} ok {test-number} - result for: {?}
# Process can be configured on command line # Process can be configured on command line

View File

@ -11476,7 +11476,7 @@ C
</Expression> </Expression>
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" > <Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original> <Original>
cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} }
</Original> </Original>
<Expanded> <Expanded>
{?} == {?} {?} == {?}

View File

@ -11476,7 +11476,7 @@ C
</Expression> </Expression>
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" > <Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original> <Original>
cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, {}, {}, {} } cfg.getReporterSpecs()[0] == Catch::ReporterSpec{ expectedReporter, std::string{}, Catch::ColourMode::PlatformDefault, {} }
</Original> </Original>
<Expanded> <Expanded>
{?} == {?} {?} == {?}

View File

@ -363,7 +363,10 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
CHECK( cfg.getReporterSpecs().size() == 1 ); CHECK( cfg.getReporterSpecs().size() == 1 );
CHECK( cfg.getReporterSpecs()[0] == CHECK( cfg.getReporterSpecs()[0] ==
Catch::ReporterSpec{ expectedReporter, {}, {}, {} } ); Catch::ReporterSpec{ expectedReporter,
std::string{},
Catch::ColourMode::PlatformDefault,
{} } );
} }
SECTION("test lists") { SECTION("test lists") {

View File

@ -23,6 +23,7 @@
#include <catch2/reporters/catch_reporter_event_listener.hpp> #include <catch2/reporters/catch_reporter_event_listener.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp> #include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <catch2/reporters/catch_reporter_multi.hpp> #include <catch2/reporters/catch_reporter_multi.hpp>
#include <catch2/internal/catch_move_and_forward.hpp>
#include <sstream> #include <sstream>
@ -34,6 +35,15 @@ namespace {
private: private:
std::stringstream sstr; std::stringstream sstr;
}; };
//! config must outlive the function
Catch::ReporterConfig makeDummyRepConfig( Catch::Config const& config ) {
return Catch::ReporterConfig{
&config,
Catch::Detail::make_unique<StringIStream>(),
Catch::ColourMode::None,
{} };
}
} }
TEST_CASE( "The default listing implementation write to provided stream", TEST_CASE( "The default listing implementation write to provided stream",
@ -85,20 +95,19 @@ TEST_CASE( "Reporter's write listings to provided stream", "[reporters]" ) {
for (auto const& factory : factories) { for (auto const& factory : factories) {
INFO("Tested reporter: " << factory.first); INFO("Tested reporter: " << factory.first);
StringIStream sstream; auto sstream = Catch::Detail::make_unique<StringIStream>();
auto& sstreamRef = *sstream.get();
Catch::ConfigData config_data; Catch::Config config( Catch::ConfigData{} );
Catch::Config config( config_data ); auto reporter = factory.second->create( Catch::ReporterConfig{
Catch::ReporterConfig rep_config( &config, CATCH_MOVE( sstream ), Catch::ColourMode::None, {} } );
&config, &sstream, Catch::ColourMode::None, {} );
auto reporter = factory.second->create( rep_config );
DYNAMIC_SECTION( factory.first << " reporter lists tags" ) { DYNAMIC_SECTION( factory.first << " reporter lists tags" ) {
std::vector<Catch::TagInfo> tags(1); std::vector<Catch::TagInfo> tags(1);
tags[0].add("fakeTag"_catch_sr); tags[0].add("fakeTag"_catch_sr);
reporter->listTags(tags); reporter->listTags(tags);
auto listingString = sstream.str(); auto listingString = sstreamRef.str();
REQUIRE_THAT(listingString, ContainsSubstring("fakeTag"s)); REQUIRE_THAT(listingString, ContainsSubstring("fakeTag"s));
} }
@ -107,7 +116,7 @@ TEST_CASE( "Reporter's write listings to provided stream", "[reporters]" ) {
{ { "fake reporter", "fake description" } } ); { { "fake reporter", "fake description" } } );
reporter->listReporters(reporters); reporter->listReporters(reporters);
auto listingString = sstream.str(); auto listingString = sstreamRef.str();
REQUIRE_THAT(listingString, ContainsSubstring("fake reporter"s)); REQUIRE_THAT(listingString, ContainsSubstring("fake reporter"s));
} }
@ -119,7 +128,7 @@ TEST_CASE( "Reporter's write listings to provided stream", "[reporters]" ) {
std::vector<Catch::TestCaseHandle> tests({ {&fakeInfo, nullptr} }); std::vector<Catch::TestCaseHandle> tests({ {&fakeInfo, nullptr} });
reporter->listTests(tests); reporter->listTests(tests);
auto listingString = sstream.str(); auto listingString = sstreamRef.str();
REQUIRE_THAT( listingString, REQUIRE_THAT( listingString,
ContainsSubstring( "fake test name"s ) && ContainsSubstring( "fake test name"s ) &&
ContainsSubstring( "fakeTestTag"s ) ); ContainsSubstring( "fakeTestTag"s ) );
@ -159,8 +168,8 @@ namespace {
public: public:
MockReporter( std::string witness, MockReporter( std::string witness,
std::vector<std::string>& recorder, std::vector<std::string>& recorder,
Catch::ReporterConfig const& config ): Catch::ReporterConfig&& config ):
StreamingReporterBase( config ), StreamingReporterBase( CATCH_MOVE(config) ),
m_witness( witness ), m_witness( witness ),
m_recorder( recorder ) m_recorder( recorder )
{} {}
@ -173,25 +182,20 @@ namespace {
TEST_CASE("Multireporter calls reporters and listeners in correct order", TEST_CASE("Multireporter calls reporters and listeners in correct order",
"[reporters][multi-reporter]") { "[reporters][multi-reporter]") {
Catch::Config config( Catch::ConfigData{} );
Catch::ConfigData config_data;
Catch::Config config( config_data );
StringIStream sstream;
Catch::ReporterConfig rep_config(
&config, &sstream, Catch::ColourMode::None, {} );
// We add reporters before listeners, to check that internally they // We add reporters before listeners, to check that internally they
// get sorted properly, and listeners are called first anyway. // get sorted properly, and listeners are called first anyway.
Catch::MultiReporter multiReporter( &config ); Catch::MultiReporter multiReporter( &config );
std::vector<std::string> records; std::vector<std::string> records;
multiReporter.addReporter( Catch::Detail::make_unique<MockReporter>( multiReporter.addReporter( Catch::Detail::make_unique<MockReporter>(
"Goodbye", records, rep_config ) ); "Goodbye", records, makeDummyRepConfig(config) ) );
multiReporter.addListener( multiReporter.addListener(
Catch::Detail::make_unique<MockListener>( "Hello", records, &config ) ); Catch::Detail::make_unique<MockListener>( "Hello", records, &config ) );
multiReporter.addListener( multiReporter.addListener(
Catch::Detail::make_unique<MockListener>( "world", records, &config ) ); Catch::Detail::make_unique<MockListener>( "world", records, &config ) );
multiReporter.addReporter( Catch::Detail::make_unique<MockReporter>( multiReporter.addReporter( Catch::Detail::make_unique<MockReporter>(
"world", records, rep_config ) ); "world", records, makeDummyRepConfig(config) ) );
multiReporter.testRunStarting( { "" } ); multiReporter.testRunStarting( { "" } );
std::vector<std::string> expected( { "Hello", "world", "Goodbye", "world" } ); std::vector<std::string> expected( { "Hello", "world", "Goodbye", "world" } );
@ -217,8 +221,8 @@ namespace {
public: public:
PreferenceReporter( bool redirectStdout, PreferenceReporter( bool redirectStdout,
bool reportAllAssertions, bool reportAllAssertions,
Catch::ReporterConfig const& config ): Catch::ReporterConfig&& config ):
StreamingReporterBase( config ) { StreamingReporterBase( CATCH_MOVE(config) ) {
m_preferences.shouldRedirectStdOut = redirectStdout; m_preferences.shouldRedirectStdOut = redirectStdout;
m_preferences.shouldReportAllAssertions = reportAllAssertions; m_preferences.shouldReportAllAssertions = reportAllAssertions;
} }
@ -228,11 +232,7 @@ namespace {
TEST_CASE("Multireporter updates ReporterPreferences properly", TEST_CASE("Multireporter updates ReporterPreferences properly",
"[reporters][multi-reporter]") { "[reporters][multi-reporter]") {
Catch::ConfigData config_data; Catch::Config config( Catch::ConfigData{} );
Catch::Config config( config_data );
StringIStream sstream;
Catch::ReporterConfig rep_config(
&config, &sstream, Catch::ColourMode::None, {} );
Catch::MultiReporter multiReporter( &config ); Catch::MultiReporter multiReporter( &config );
// Post init defaults // Post init defaults
@ -261,19 +261,19 @@ TEST_CASE("Multireporter updates ReporterPreferences properly",
SECTION( "Adding reporters" ) { SECTION( "Adding reporters" ) {
multiReporter.addReporter( multiReporter.addReporter(
Catch::Detail::make_unique<PreferenceReporter>( Catch::Detail::make_unique<PreferenceReporter>(
true, false, rep_config ) ); true, false, makeDummyRepConfig(config) ) );
REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true ); REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == false ); REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == false );
multiReporter.addReporter( multiReporter.addReporter(
Catch::Detail::make_unique<PreferenceReporter>( Catch::Detail::make_unique<PreferenceReporter>(
false, true, rep_config ) ); false, true, makeDummyRepConfig( config ) ) );
REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true ); REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true ); REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true );
multiReporter.addReporter( multiReporter.addReporter(
Catch::Detail::make_unique<PreferenceReporter>( Catch::Detail::make_unique<PreferenceReporter>(
false, false, rep_config ) ); false, false, makeDummyRepConfig( config ) ) );
REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true ); REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true ); REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true );
} }
@ -281,7 +281,7 @@ TEST_CASE("Multireporter updates ReporterPreferences properly",
namespace { namespace {
class TestReporterFactory : public Catch::IReporterFactory { class TestReporterFactory : public Catch::IReporterFactory {
Catch::IEventListenerPtr create( Catch::ReporterConfig const& ) const override { Catch::IEventListenerPtr create( Catch::ReporterConfig&& ) const override {
CATCH_INTERNAL_ERROR( CATCH_INTERNAL_ERROR(
"This factory should never create a reporter" ); "This factory should never create a reporter" );
} }