From edc2f6e8a35b6261e83db9c685f44cb3a4c24d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sun, 14 Nov 2021 11:40:06 +0100 Subject: [PATCH] Further refactoring of StreamingReporterBase --- .../reporters/catch_reporter_automake.cpp | 12 +-- .../reporters/catch_reporter_compact.cpp | 12 +-- .../reporters/catch_reporter_console.cpp | 74 +++++++++---------- .../reporters/catch_reporter_console.hpp | 1 + .../catch_reporter_streaming_base.cpp | 7 +- .../catch_reporter_streaming_base.hpp | 25 ++----- src/catch2/reporters/catch_reporter_tap.cpp | 14 ++-- .../reporters/catch_reporter_teamcity.cpp | 22 +++--- 8 files changed, 76 insertions(+), 91 deletions(-) diff --git a/src/catch2/reporters/catch_reporter_automake.cpp b/src/catch2/reporters/catch_reporter_automake.cpp index ec11f605..90b12928 100644 --- a/src/catch2/reporters/catch_reporter_automake.cpp +++ b/src/catch2/reporters/catch_reporter_automake.cpp @@ -16,20 +16,20 @@ namespace Catch { void AutomakeReporter::testCaseEnded(TestCaseStats const& _testCaseStats) { // Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR. - stream << ":test-result: "; + m_stream << ":test-result: "; if (_testCaseStats.totals.assertions.allPassed()) { - stream << "PASS"; + m_stream << "PASS"; } else if (_testCaseStats.totals.assertions.allOk()) { - stream << "XFAIL"; + m_stream << "XFAIL"; } else { - stream << "FAIL"; + m_stream << "FAIL"; } - stream << ' ' << _testCaseStats.testInfo->name << '\n'; + m_stream << ' ' << _testCaseStats.testInfo->name << '\n'; StreamingReporterBase::testCaseEnded(_testCaseStats); } void AutomakeReporter::skipTest(TestCaseInfo const& testInfo) { - stream << ":test-result: SKIP " << testInfo.name << '\n'; + m_stream << ":test-result: SKIP " << testInfo.name << '\n'; } } // end namespace Catch diff --git a/src/catch2/reporters/catch_reporter_compact.cpp b/src/catch2/reporters/catch_reporter_compact.cpp index 1bd997bd..7a92d895 100644 --- a/src/catch2/reporters/catch_reporter_compact.cpp +++ b/src/catch2/reporters/catch_reporter_compact.cpp @@ -259,7 +259,7 @@ private: } void CompactReporter::noMatchingTestCases( StringRef unmatchedSpec ) { - stream << "No test cases matched '" << unmatchedSpec << "'\n"; + m_stream << "No test cases matched '" << unmatchedSpec << "'\n"; } void CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) { @@ -274,22 +274,22 @@ private: printInfoMessages = false; } - AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + AssertionPrinter printer( m_stream, _assertionStats, printInfoMessages ); printer.print(); - stream << '\n' << std::flush; + m_stream << '\n' << std::flush; } void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { double dur = _sectionStats.durationInSeconds; if ( shouldShowDuration( *m_config, dur ) ) { - stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << '\n' << std::flush; + m_stream << getFormattedDuration( dur ) << " s: " << _sectionStats.sectionInfo.name << '\n' << std::flush; } } void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) { - printTotals( stream, _testRunStats.totals ); - stream << "\n\n" << std::flush; + printTotals( m_stream, _testRunStats.totals ); + m_stream << "\n\n" << std::flush; StreamingReporterBase::testRunEnded( _testRunStats ); } diff --git a/src/catch2/reporters/catch_reporter_console.cpp b/src/catch2/reporters/catch_reporter_console.cpp index a1890897..f260da52 100644 --- a/src/catch2/reporters/catch_reporter_console.cpp +++ b/src/catch2/reporters/catch_reporter_console.cpp @@ -382,11 +382,11 @@ std::string ConsoleReporter::getDescription() { } void ConsoleReporter::noMatchingTestCases( StringRef unmatchedSpec ) { - stream << "No test cases matched '" << unmatchedSpec << "'\n"; + m_stream << "No test cases matched '" << unmatchedSpec << "'\n"; } void ConsoleReporter::reportInvalidArguments( StringRef arg ) { - stream << "Invalid Filter: " << arg << '\n'; + m_stream << "Invalid Filter: " << arg << '\n'; } void ConsoleReporter::assertionStarting(AssertionInfo const&) {} @@ -402,9 +402,9 @@ void ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) { lazyPrint(); - ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults); + ConsoleAssertionPrinter printer(m_stream, _assertionStats, includeResults); printer.print(); - stream << '\n' << std::flush; + m_stream << '\n' << std::flush; } void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) { @@ -418,14 +418,14 @@ void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) { lazyPrint(); Colour colour(Colour::ResultError); if (m_sectionStack.size() > 1) - stream << "\nNo assertions in section"; + m_stream << "\nNo assertions in section"; else - stream << "\nNo assertions in test case"; - stream << " '" << _sectionStats.sectionInfo.name << "'\n\n" << std::flush; + m_stream << "\nNo assertions in test case"; + m_stream << " '" << _sectionStats.sectionInfo.name << "'\n\n" << std::flush; } double dur = _sectionStats.durationInSeconds; if (shouldShowDuration(*m_config, dur)) { - stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << '\n' << std::flush; + m_stream << getFormattedDuration(dur) << " s: " << _sectionStats.sectionInfo.name << '\n' << std::flush; } if (m_headerPrinted) { m_headerPrinted = false; @@ -489,7 +489,7 @@ void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) { void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) { printTotalsDivider(_testRunStats.totals); printTotals(_testRunStats.totals); - stream << '\n' << std::flush; + m_stream << '\n' << std::flush; StreamingReporterBase::testRunEnded(_testRunStats); } void ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) { @@ -505,7 +505,7 @@ void ConsoleReporter::lazyPrint() { void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() { - if ( !currentTestRunInfo.used ) { + if ( !m_testRunInfoPrinted ) { lazyPrintRunInfo(); } if (!m_headerPrinted) { @@ -514,15 +514,15 @@ void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() { } } void ConsoleReporter::lazyPrintRunInfo() { - stream << '\n' << lineOfChars('~') << '\n'; + m_stream << '\n' << lineOfChars('~') << '\n'; Colour colour(Colour::SecondaryText); - stream << currentTestRunInfo->name + m_stream << currentTestRunInfo.name << " is a Catch v" << libraryVersion() << " host application.\n" << "Run with -? for options\n\n"; - stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + m_stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; - currentTestRunInfo.used = true; + m_testRunInfoPrinted = true; } void ConsoleReporter::printTestCaseAndSectionHeader() { assert(!m_sectionStack.empty()); @@ -541,18 +541,18 @@ void ConsoleReporter::printTestCaseAndSectionHeader() { SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; - stream << lineOfChars('-') << '\n'; + m_stream << lineOfChars('-') << '\n'; Colour colourGuard(Colour::FileName); - stream << lineInfo << '\n'; - stream << lineOfChars('.') << "\n\n" << std::flush; + m_stream << lineInfo << '\n'; + m_stream << lineOfChars('.') << "\n\n" << std::flush; } void ConsoleReporter::printClosedHeader(std::string const& _name) { printOpenHeader(_name); - stream << lineOfChars('.') << '\n'; + m_stream << lineOfChars('.') << '\n'; } void ConsoleReporter::printOpenHeader(std::string const& _name) { - stream << lineOfChars('-') << '\n'; + m_stream << lineOfChars('-') << '\n'; { Colour colourGuard(Colour::Headers); printHeaderString(_name); @@ -586,7 +586,7 @@ void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t } else { idx = 0; } - stream << TextFlow::Column( _string ) + m_stream << TextFlow::Column( _string ) .indent( indent + idx ) .initialIndent( indent ) << '\n'; @@ -619,10 +619,10 @@ struct SummaryColumn { void ConsoleReporter::printTotals( Totals const& totals ) { if (totals.testCases.total() == 0) { - stream << Colour(Colour::Warning) << "No tests ran\n"; + m_stream << Colour(Colour::Warning) << "No tests ran\n"; } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) { - stream << Colour(Colour::ResultSuccess) << "All tests passed"; - stream << " (" + m_stream << Colour(Colour::ResultSuccess) << "All tests passed"; + m_stream << " (" << pluralise(totals.assertions.passed, "assertion"_sr) << " in " << pluralise(totals.testCases.passed, "test case"_sr) << ')' << '\n'; @@ -650,18 +650,18 @@ void ConsoleReporter::printSummaryRow(StringRef label, std::vector CATCH_CONFIG_CONSOLE_WIDTH - 1) findMax(failedRatio, failedButOkRatio, passedRatio)--; - stream << Colour(Colour::Error) << std::string(failedRatio, '='); - stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '='); + m_stream << Colour(Colour::Error) << std::string(failedRatio, '='); + m_stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '='); if (totals.testCases.allPassed()) - stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '='); + m_stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '='); else - stream << Colour(Colour::Success) << std::string(passedRatio, '='); + m_stream << Colour(Colour::Success) << std::string(passedRatio, '='); } else { - stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '='); + m_stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '='); } - stream << '\n'; + m_stream << '\n'; } void ConsoleReporter::printSummaryDivider() { - stream << lineOfChars('-') << '\n'; + m_stream << lineOfChars('-') << '\n'; } void ConsoleReporter::printTestFilters() { if (m_config->testSpec().hasFilters()) { Colour guard(Colour::BrightYellow); - stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n'; + m_stream << "Filters: " << serializeFilters(m_config->getTestsOrTags()) << '\n'; } } diff --git a/src/catch2/reporters/catch_reporter_console.hpp b/src/catch2/reporters/catch_reporter_console.hpp index ec743093..7d010339 100644 --- a/src/catch2/reporters/catch_reporter_console.hpp +++ b/src/catch2/reporters/catch_reporter_console.hpp @@ -66,6 +66,7 @@ namespace Catch { private: bool m_headerPrinted = false; + bool m_testRunInfoPrinted = false; }; } // end namespace Catch diff --git a/src/catch2/reporters/catch_reporter_streaming_base.cpp b/src/catch2/reporters/catch_reporter_streaming_base.cpp index 1c2787ca..893415fe 100644 --- a/src/catch2/reporters/catch_reporter_streaming_base.cpp +++ b/src/catch2/reporters/catch_reporter_streaming_base.cpp @@ -19,22 +19,21 @@ namespace Catch { void StreamingReporterBase::testRunEnded( TestRunStats const& ) { currentTestCaseInfo = nullptr; - currentTestRunInfo.reset(); } void StreamingReporterBase::listReporters(std::vector const& descriptions) { - defaultListReporters( stream, descriptions, m_config->verbosity() ); + defaultListReporters( m_stream, descriptions, m_config->verbosity() ); } void StreamingReporterBase::listTests(std::vector const& tests) { - defaultListTests(stream, + defaultListTests(m_stream, tests, m_config->hasTestFilters(), m_config->verbosity()); } void StreamingReporterBase::listTags(std::vector const& tags) { - defaultListTags( stream, tags, m_config->hasTestFilters() ); + defaultListTags( m_stream, tags, m_config->hasTestFilters() ); } } // end namespace Catch diff --git a/src/catch2/reporters/catch_reporter_streaming_base.hpp b/src/catch2/reporters/catch_reporter_streaming_base.hpp index 63d3a38a..d32d01f2 100644 --- a/src/catch2/reporters/catch_reporter_streaming_base.hpp +++ b/src/catch2/reporters/catch_reporter_streaming_base.hpp @@ -10,34 +10,17 @@ #include -#include - #include #include #include namespace Catch { - template - struct LazyStat : Optional { - LazyStat& operator=(T const& _value) { - Optional::operator=(_value); - used = false; - return *this; - } - void reset() { - Optional::reset(); - used = false; - } - bool used = false; - }; - - class StreamingReporterBase : public IStreamingReporter { public: StreamingReporterBase( ReporterConfig const& _config ): IStreamingReporter( _config.fullConfig() ), - stream( _config.stream() ) {} + m_stream( _config.stream() ) {} ~StreamingReporterBase() override; @@ -83,11 +66,13 @@ namespace Catch { void listTags( std::vector const& tags ) override; protected: - std::ostream& stream; + //! Stream that the reporter output should be written to + std::ostream& m_stream; - LazyStat currentTestRunInfo; + TestRunInfo currentTestRunInfo{ "test run has not started yet"_sr }; TestCaseInfo const* currentTestCaseInfo = nullptr; + //! Stack of all _active_ sections in the _current_ test case std::vector m_sectionStack; }; diff --git a/src/catch2/reporters/catch_reporter_tap.cpp b/src/catch2/reporters/catch_reporter_tap.cpp index 46a0994d..a887ed6c 100644 --- a/src/catch2/reporters/catch_reporter_tap.cpp +++ b/src/catch2/reporters/catch_reporter_tap.cpp @@ -195,25 +195,25 @@ namespace Catch { } // End anonymous namespace void TAPReporter::noMatchingTestCases( StringRef unmatchedSpec ) { - stream << "# No test cases matched '" << unmatchedSpec << "'\n"; + m_stream << "# No test cases matched '" << unmatchedSpec << "'\n"; } void TAPReporter::assertionEnded(AssertionStats const& _assertionStats) { ++counter; - stream << "# " << currentTestCaseInfo->name << '\n'; - TapAssertionPrinter printer(stream, _assertionStats, counter); + m_stream << "# " << currentTestCaseInfo->name << '\n'; + TapAssertionPrinter printer(m_stream, _assertionStats, counter); printer.print(); - stream << '\n' << std::flush; + m_stream << '\n' << std::flush; } void TAPReporter::testRunEnded(TestRunStats const& _testRunStats) { - stream << "1.." << _testRunStats.totals.assertions.total(); + m_stream << "1.." << _testRunStats.totals.assertions.total(); if (_testRunStats.totals.testCases.total() == 0) { - stream << " # Skipped: No tests ran."; + m_stream << " # Skipped: No tests ran."; } - stream << "\n\n" << std::flush; + m_stream << "\n\n" << std::flush; StreamingReporterBase::testRunEnded(_testRunStats); } diff --git a/src/catch2/reporters/catch_reporter_teamcity.cpp b/src/catch2/reporters/catch_reporter_teamcity.cpp index 1972b8c4..8f16757a 100644 --- a/src/catch2/reporters/catch_reporter_teamcity.cpp +++ b/src/catch2/reporters/catch_reporter_teamcity.cpp @@ -47,12 +47,12 @@ namespace Catch { TeamCityReporter::~TeamCityReporter() {} void TeamCityReporter::testRunStarting( TestRunInfo const& runInfo ) { - stream << "##teamcity[testSuiteStarted name='" << escape( runInfo.name ) + m_stream << "##teamcity[testSuiteStarted name='" << escape( runInfo.name ) << "']\n"; } void TeamCityReporter::testRunEnded( TestRunStats const& runStats ) { - stream << "##teamcity[testSuiteFinished name='" + m_stream << "##teamcity[testSuiteFinished name='" << escape( runStats.runInfo.name ) << "']\n"; } @@ -112,43 +112,43 @@ namespace Catch { if (currentTestCaseInfo->okToFail()) { msg << "- failure ignore as test marked as 'ok to fail'\n"; - stream << "##teamcity[testIgnored" + m_stream << "##teamcity[testIgnored" << " name='" << escape(currentTestCaseInfo->name) << '\'' << " message='" << escape(msg.str()) << '\'' << "]\n"; } else { - stream << "##teamcity[testFailed" + m_stream << "##teamcity[testFailed" << " name='" << escape(currentTestCaseInfo->name) << '\'' << " message='" << escape(msg.str()) << '\'' << "]\n"; } } - stream.flush(); + m_stream.flush(); } void TeamCityReporter::testCaseStarting(TestCaseInfo const& testInfo) { m_testTimer.start(); StreamingReporterBase::testCaseStarting(testInfo); - stream << "##teamcity[testStarted name='" + m_stream << "##teamcity[testStarted name='" << escape(testInfo.name) << "']\n"; - stream.flush(); + m_stream.flush(); } void TeamCityReporter::testCaseEnded(TestCaseStats const& testCaseStats) { StreamingReporterBase::testCaseEnded(testCaseStats); auto const& testCaseInfo = *testCaseStats.testInfo; if (!testCaseStats.stdOut.empty()) - stream << "##teamcity[testStdOut name='" + m_stream << "##teamcity[testStdOut name='" << escape(testCaseInfo.name) << "' out='" << escape(testCaseStats.stdOut) << "']\n"; if (!testCaseStats.stdErr.empty()) - stream << "##teamcity[testStdErr name='" + m_stream << "##teamcity[testStdErr name='" << escape(testCaseInfo.name) << "' out='" << escape(testCaseStats.stdErr) << "']\n"; - stream << "##teamcity[testFinished name='" + m_stream << "##teamcity[testFinished name='" << escape(testCaseInfo.name) << "' duration='" << m_testTimer.getElapsedMilliseconds() << "']\n"; - stream.flush(); + m_stream.flush(); } void TeamCityReporter::printSectionHeader(std::ostream& os) {