Files
Catch2/src/catch2/catch_config.cpp
T
Martin Hořeňovský fc5552d27b Push down handling of default reporter to Config's constructor
This simplifies the handling of default reporter in console
parsing, at the cost of making `Config`'s constructor responsible
for more things.
2022-02-17 23:02:30 +01:00

154 lines
6.5 KiB
C++

// Copyright Catch2 Authors
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
// SPDX-License-Identifier: BSL-1.0
#include <catch2/catch_config.hpp>
#include <catch2/catch_user_config.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <catch2/internal/catch_stream.hpp>
#include <catch2/internal/catch_stringref.hpp>
#include <catch2/internal/catch_string_manip.hpp>
#include <catch2/internal/catch_test_spec_parser.hpp>
#include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
#include <ostream>
namespace Catch {
namespace Detail {
namespace {
class RDBufStream : public IStream {
mutable std::ostream m_os;
public:
//! The streambuf `sb` must outlive the constructed object.
RDBufStream( std::streambuf* sb ): m_os( sb ) {}
~RDBufStream() override = default;
public: // IStream
std::ostream& stream() const override { return m_os; }
};
} // unnamed namespace
} // namespace Detail
std::ostream& operator<<( std::ostream& os,
ConfigData::ReporterAndFile const& reporter ) {
os << "{ " << reporter.reporterName << ", ";
if ( reporter.outputFileName ) {
os << *reporter.outputFileName;
} else {
os << "<default-output>";
}
return os << " }";
}
Config::Config( ConfigData const& data ):
m_data( data ),
m_defaultStream( openStream( data.defaultOutputFilename ) ) {
// We need to trim filter specs to avoid trouble with superfluous
// whitespace (esp. important for bdd macros, as those are manually
// aligned with whitespace).
for (auto& elem : m_data.testsOrTags) {
elem = trim(elem);
}
for (auto& elem : m_data.sectionsToRun) {
elem = trim(elem);
}
TestSpecParser parser(ITagAliasRegistry::get());
if (!m_data.testsOrTags.empty()) {
m_hasTestFilters = true;
for (auto const& testOrTags : m_data.testsOrTags) {
parser.parse(testOrTags);
}
}
m_testSpec = parser.testSpec();
// Insert the default reporter if user hasn't asked for a specfic one
if ( m_data.reporterSpecifications.empty() ) {
m_data.reporterSpecifications.push_back( {
#if defined( CATCH_CONFIG_DEFAULT_REPORTER )
CATCH_CONFIG_DEFAULT_REPORTER,
#else
"console",
#endif
{}
} );
}
m_reporterStreams.reserve( m_data.reporterSpecifications.size() );
for ( auto const& reporterAndFile : m_data.reporterSpecifications ) {
if ( reporterAndFile.outputFileName.none() ) {
m_reporterStreams.emplace_back( new Detail::RDBufStream(
m_defaultStream->stream().rdbuf() ) );
} else {
m_reporterStreams.emplace_back(
openStream( *reporterAndFile.outputFileName ) );
}
}
}
Config::~Config() = default;
bool Config::listTests() const { return m_data.listTests; }
bool Config::listTags() const { return m_data.listTags; }
bool Config::listReporters() const { return m_data.listReporters; }
std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
std::vector<ConfigData::ReporterAndFile> const& Config::getReportersAndOutputFiles() const {
return m_data.reporterSpecifications;
}
std::ostream& Config::getReporterOutputStream(std::size_t reporterIdx) const {
return m_reporterStreams.at(reporterIdx)->stream();
}
TestSpec const& Config::testSpec() const { return m_testSpec; }
bool Config::hasTestFilters() const { return m_hasTestFilters; }
bool Config::showHelp() const { return m_data.showHelp; }
// IConfig interface
bool Config::allowThrows() const { return !m_data.noThrow; }
std::ostream& Config::defaultStream() const { return m_defaultStream->stream(); }
StringRef Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
bool Config::warnAboutMissingAssertions() const {
return !!( m_data.warnings & WarnAbout::NoAssertions );
}
bool Config::warnAboutUnmatchedTestSpecs() const {
return !!( m_data.warnings & WarnAbout::UnmatchedTestSpec );
}
bool Config::zeroTestsCountAsSuccess() const { return m_data.allowZeroTests; }
ShowDurations Config::showDurations() const { return m_data.showDurations; }
double Config::minDuration() const { return m_data.minDuration; }
TestRunOrder Config::runOrder() const { return m_data.runOrder; }
uint32_t Config::rngSeed() const { return m_data.rngSeed; }
unsigned int Config::shardCount() const { return m_data.shardCount; }
unsigned int Config::shardIndex() const { return m_data.shardIndex; }
UseColour Config::useColour() const { return m_data.useColour; }
bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
int Config::abortAfter() const { return m_data.abortAfter; }
bool Config::showInvisibles() const { return m_data.showInvisibles; }
Verbosity Config::verbosity() const { return m_data.verbosity; }
bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
unsigned int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
Detail::unique_ptr<IStream const> Config::openStream(std::string const& outputFileName) {
return Catch::makeStream(outputFileName);
}
} // end namespace Catch