Further refactoring of StreamingReporterBase

This commit is contained in:
Martin Hořeňovský 2021-11-14 11:40:06 +01:00
parent b2ac27423a
commit edc2f6e8a3
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
8 changed files with 76 additions and 91 deletions

View File

@ -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

View File

@ -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 );
}

View File

@ -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<SummaryColumn
for (auto col : cols) {
std::string value = col.rows[row];
if (col.label.empty()) {
stream << label << ": ";
m_stream << label << ": ";
if (value != "0")
stream << value;
m_stream << value;
else
stream << Colour(Colour::Warning) << "- none -";
m_stream << Colour(Colour::Warning) << "- none -";
} else if (value != "0") {
stream << Colour(Colour::LightGrey) << " | ";
stream << Colour(col.colour)
m_stream << Colour(Colour::LightGrey) << " | ";
m_stream << Colour(col.colour)
<< value << ' ' << col.label;
}
}
stream << '\n';
m_stream << '\n';
}
void ConsoleReporter::printTotalsDivider(Totals const& totals) {
@ -674,25 +674,25 @@ void ConsoleReporter::printTotalsDivider(Totals const& totals) {
while (failedRatio + failedButOkRatio + passedRatio > 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';
}
}

View File

@ -66,6 +66,7 @@ namespace Catch {
private:
bool m_headerPrinted = false;
bool m_testRunInfoPrinted = false;
};
} // end namespace Catch

View File

@ -19,22 +19,21 @@ namespace Catch {
void StreamingReporterBase::testRunEnded( TestRunStats const& ) {
currentTestCaseInfo = nullptr;
currentTestRunInfo.reset();
}
void StreamingReporterBase::listReporters(std::vector<ReporterDescription> const& descriptions) {
defaultListReporters( stream, descriptions, m_config->verbosity() );
defaultListReporters( m_stream, descriptions, m_config->verbosity() );
}
void StreamingReporterBase::listTests(std::vector<TestCaseHandle> const& tests) {
defaultListTests(stream,
defaultListTests(m_stream,
tests,
m_config->hasTestFilters(),
m_config->verbosity());
}
void StreamingReporterBase::listTags(std::vector<TagInfo> const& tags) {
defaultListTags( stream, tags, m_config->hasTestFilters() );
defaultListTags( m_stream, tags, m_config->hasTestFilters() );
}
} // end namespace Catch

View File

@ -10,34 +10,17 @@
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
#include <catch2/internal/catch_optional.hpp>
#include <iosfwd>
#include <string>
#include <vector>
namespace Catch {
template<typename T>
struct LazyStat : Optional<T> {
LazyStat& operator=(T const& _value) {
Optional<T>::operator=(_value);
used = false;
return *this;
}
void reset() {
Optional<T>::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<TagInfo> const& tags ) override;
protected:
std::ostream& stream;
//! Stream that the reporter output should be written to
std::ostream& m_stream;
LazyStat<TestRunInfo> 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<SectionInfo> m_sectionStack;
};

View File

@ -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);
}

View File

@ -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) {