// 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 #include #include #include #include #include #include #include #include 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 << ""; } 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 const& Config::getTestsOrTags() const { return m_data.testsOrTags; } std::vector const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } std::vector 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 Config::openStream(std::string const& outputFileName) { return Catch::makeStream(outputFileName); } } // end namespace Catch