From 74f2f4ba5e84355e4f123ec807c1ec3b29a0daa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 16 Jan 2021 15:27:47 +0100 Subject: [PATCH 1/5] Hold reporter's IConfig instance in the interface Previously, every base derived from the IStreamingReporter had its own `IConfig const* m_config` member, so this just centralizes the handling thereof. Part of #2061 --- src/catch2/catch_session.cpp | 2 +- src/catch2/interfaces/catch_interfaces_reporter.hpp | 5 +++++ src/catch2/reporters/catch_reporter_cumulative_base.hpp | 4 ++-- src/catch2/reporters/catch_reporter_event_listener.hpp | 4 +--- src/catch2/reporters/catch_reporter_listening.cpp | 5 ----- src/catch2/reporters/catch_reporter_listening.hpp | 7 ++++++- src/catch2/reporters/catch_reporter_streaming_base.hpp | 5 ++--- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/catch2/catch_session.cpp b/src/catch2/catch_session.cpp index a9519e7519..5b1a50a929 100644 --- a/src/catch2/catch_session.cpp +++ b/src/catch2/catch_session.cpp @@ -48,7 +48,7 @@ namespace Catch { // doesn't compile without a std::move call. However, this causes // a warning on newer platforms. Thus, we have to work around // it a bit and downcast the pointer manually. - auto ret = Detail::unique_ptr(new ListeningReporter); + auto ret = Detail::unique_ptr(new ListeningReporter(config)); auto& multi = static_cast(*ret); auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners(); for (auto const& listener : listeners) { diff --git a/src/catch2/interfaces/catch_interfaces_reporter.hpp b/src/catch2/interfaces/catch_interfaces_reporter.hpp index 791cc99294..9dbd18473f 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.hpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.hpp @@ -176,7 +176,12 @@ namespace Catch { protected: //! Derived classes can set up their preferences here ReporterPreferences m_preferences; + //! The test run's config as filled in from CLI and defaults + IConfig const* m_config; + public: + IStreamingReporter( IConfig const* config ): m_config( config ) {} + virtual ~IStreamingReporter() = default; // Implementing class must also provide the following static methods: diff --git a/src/catch2/reporters/catch_reporter_cumulative_base.hpp b/src/catch2/reporters/catch_reporter_cumulative_base.hpp index 0b643ff15e..0729567c47 100644 --- a/src/catch2/reporters/catch_reporter_cumulative_base.hpp +++ b/src/catch2/reporters/catch_reporter_cumulative_base.hpp @@ -46,7 +46,8 @@ namespace Catch { using TestRunNode = Node; CumulativeReporterBase( ReporterConfig const& _config ): - m_config( _config.fullConfig() ), stream( _config.stream() ) {} + IStreamingReporter( _config.fullConfig() ), + stream( _config.stream() ) {} ~CumulativeReporterBase() override; void testRunStarting( TestRunInfo const& ) override {} @@ -68,7 +69,6 @@ namespace Catch { void skipTest(TestCaseInfo const&) override {} - IConfig const* m_config; std::ostream& stream; // Note: We rely on pointer identity being stable, which is why // which is why we store around pointers rather than values. diff --git a/src/catch2/reporters/catch_reporter_event_listener.hpp b/src/catch2/reporters/catch_reporter_event_listener.hpp index 816e42f63b..df089c08de 100644 --- a/src/catch2/reporters/catch_reporter_event_listener.hpp +++ b/src/catch2/reporters/catch_reporter_event_listener.hpp @@ -20,11 +20,9 @@ namespace Catch { * member functions it actually cares about. */ class EventListenerBase : public IStreamingReporter { - IConfig const* m_config; - public: EventListenerBase( ReporterConfig const& config ): - m_config( config.fullConfig() ) {} + IStreamingReporter( config.fullConfig() ) {} void assertionStarting( AssertionInfo const& assertionInfo ) override; bool assertionEnded( AssertionStats const& assertionStats ) override; diff --git a/src/catch2/reporters/catch_reporter_listening.cpp b/src/catch2/reporters/catch_reporter_listening.cpp index f197842454..60059c8457 100644 --- a/src/catch2/reporters/catch_reporter_listening.cpp +++ b/src/catch2/reporters/catch_reporter_listening.cpp @@ -11,11 +11,6 @@ namespace Catch { - ListeningReporter::ListeningReporter() { - // We will assume that listeners will always want all assertions - m_preferences.shouldReportAllAssertions = true; - } - void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) { m_listeners.push_back( std::move( listener ) ); } diff --git a/src/catch2/reporters/catch_reporter_listening.hpp b/src/catch2/reporters/catch_reporter_listening.hpp index 8ac5283976..c6485300b6 100644 --- a/src/catch2/reporters/catch_reporter_listening.hpp +++ b/src/catch2/reporters/catch_reporter_listening.hpp @@ -18,7 +18,12 @@ namespace Catch { IStreamingReporterPtr m_reporter = nullptr; public: - ListeningReporter(); + ListeningReporter( IConfig const* config ): + IStreamingReporter( config ) { + // We will assume that listeners will always want all assertions + m_preferences.shouldReportAllAssertions = true; + } + void addListener( IStreamingReporterPtr&& listener ); void addReporter( IStreamingReporterPtr&& reporter ); diff --git a/src/catch2/reporters/catch_reporter_streaming_base.hpp b/src/catch2/reporters/catch_reporter_streaming_base.hpp index 5826f63b84..ebf0638501 100644 --- a/src/catch2/reporters/catch_reporter_streaming_base.hpp +++ b/src/catch2/reporters/catch_reporter_streaming_base.hpp @@ -36,8 +36,8 @@ namespace Catch { struct StreamingReporterBase : IStreamingReporter { StreamingReporterBase( ReporterConfig const& _config ): - m_config( _config.fullConfig() ), stream( _config.stream() ) { - } + IStreamingReporter( _config.fullConfig() ), + stream( _config.stream() ) {} ~StreamingReporterBase() override; @@ -71,7 +71,6 @@ namespace Catch { // It can optionally be overridden in the derived class. } - IConfig const* m_config; std::ostream& stream; LazyStat currentTestRunInfo; From 5509ceff608aafc402116a081200f3ff2b4805ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 16 Jan 2021 15:48:22 +0100 Subject: [PATCH 2/5] Remove superfluous IConfig argument from IStreamingReporter::list* The previous commit made it so that the `IConfig` is stored in `IStreamingReporter` and thus always available. --- .../interfaces/catch_interfaces_reporter.cpp | 21 ++++++++++--------- .../interfaces/catch_interfaces_reporter.hpp | 6 +++--- src/catch2/internal/catch_list.cpp | 10 ++++----- .../reporters/catch_reporter_combined_tu.cpp | 11 ++++------ .../catch_reporter_event_listener.hpp | 11 ++++------ .../reporters/catch_reporter_listening.cpp | 18 ++++++++-------- .../reporters/catch_reporter_listening.hpp | 6 +++--- src/catch2/reporters/catch_reporter_xml.cpp | 6 +++--- src/catch2/reporters/catch_reporter_xml.hpp | 6 +++--- 9 files changed, 45 insertions(+), 50 deletions(-) diff --git a/src/catch2/interfaces/catch_interfaces_reporter.cpp b/src/catch2/interfaces/catch_interfaces_reporter.cpp index 948869e7ae..1fd6b6d10b 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.cpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.cpp @@ -127,14 +127,14 @@ namespace Catch { void IStreamingReporter::fatalErrorEncountered( StringRef ) {} - void IStreamingReporter::listReporters(std::vector const& descriptions, IConfig const& config) { + void IStreamingReporter::listReporters(std::vector const& descriptions) { Catch::cout() << "Available reporters:\n"; const auto maxNameLen = std::max_element(descriptions.begin(), descriptions.end(), [](ReporterDescription const& lhs, ReporterDescription const& rhs) { return lhs.name.size() < rhs.name.size(); }) ->name.size(); for (auto const& desc : descriptions) { - if (config.verbosity() == Verbosity::Quiet) { + if (m_config->verbosity() == Verbosity::Quiet) { Catch::cout() << TextFlow::Column(desc.name) .indent(2) @@ -154,16 +154,16 @@ namespace Catch { Catch::cout() << std::endl; } - void IStreamingReporter::listTests(std::vector const& tests, IConfig const& config) { + void IStreamingReporter::listTests(std::vector const& tests) { // We special case this to provide the equivalent of old // `--list-test-names-only`, which could then be used by the // `--input-file` option. - if (config.verbosity() == Verbosity::Quiet) { + if (m_config->verbosity() == Verbosity::Quiet) { listTestNamesOnly(tests); return; } - if (config.hasTestFilters()) { + if (m_config->hasTestFilters()) { Catch::cout() << "Matching test cases:\n"; } else { Catch::cout() << "All available test cases:\n"; @@ -177,23 +177,24 @@ namespace Catch { Colour colourGuard(colour); Catch::cout() << TextFlow::Column(testCaseInfo.name).initialIndent(2).indent(4) << '\n'; - if (config.verbosity() >= Verbosity::High) { + if (m_config->verbosity() >= Verbosity::High) { Catch::cout() << TextFlow::Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl; } - if (!testCaseInfo.tags.empty() && config.verbosity() > Verbosity::Quiet) { + if ( !testCaseInfo.tags.empty() && + m_config->verbosity() > Verbosity::Quiet ) { Catch::cout() << TextFlow::Column(testCaseInfo.tagsAsString()).indent(6) << '\n'; } } - if (!config.hasTestFilters()) { + if (!m_config->hasTestFilters()) { Catch::cout() << pluralise(tests.size(), "test case") << '\n' << std::endl; } else { Catch::cout() << pluralise(tests.size(), "matching test case") << '\n' << std::endl; } } - void IStreamingReporter::listTags(std::vector const& tags, IConfig const& config) { - if (config.hasTestFilters()) { + void IStreamingReporter::listTags(std::vector const& tags) { + if (m_config->hasTestFilters()) { Catch::cout() << "Tags for matching test cases:\n"; } else { Catch::cout() << "All available tags:\n"; diff --git a/src/catch2/interfaces/catch_interfaces_reporter.hpp b/src/catch2/interfaces/catch_interfaces_reporter.hpp index 9dbd18473f..5449cc2256 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.hpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.hpp @@ -222,11 +222,11 @@ namespace Catch { virtual void fatalErrorEncountered( StringRef name ); //! Writes out information about provided reporters using reporter-specific format - virtual void listReporters(std::vector const& descriptions, IConfig const& config); + virtual void listReporters(std::vector const& descriptions); //! Writes out information about provided tests using reporter-specific format - virtual void listTests(std::vector const& tests, IConfig const& config); + virtual void listTests(std::vector const& tests); //! Writes out information about the provided tags using reporter-specific format - virtual void listTags(std::vector const& tags, IConfig const& config); + virtual void listTags(std::vector const& tags); }; using IStreamingReporterPtr = Detail::unique_ptr; diff --git a/src/catch2/internal/catch_list.cpp b/src/catch2/internal/catch_list.cpp index 1cedb3ae46..d7969096e3 100644 --- a/src/catch2/internal/catch_list.cpp +++ b/src/catch2/internal/catch_list.cpp @@ -24,7 +24,7 @@ namespace Catch { void listTests(IStreamingReporter& reporter, IConfig const& config) { auto const& testSpec = config.testSpec(); auto matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config); - reporter.listTests(matchedTestCases, config); + reporter.listTests(matchedTestCases); } void listTags(IStreamingReporter& reporter, IConfig const& config) { @@ -46,10 +46,10 @@ namespace Catch { infos.push_back(std::move(tagc.second)); } - reporter.listTags(infos, config); + reporter.listTags(infos); } - void listReporters(IStreamingReporter& reporter, IConfig const& config) { + void listReporters(IStreamingReporter& reporter) { std::vector descriptions; IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); @@ -58,7 +58,7 @@ namespace Catch { descriptions.push_back({ fac.first, fac.second->getDescription() }); } - reporter.listReporters(descriptions, config); + reporter.listReporters(descriptions); } } // end anonymous namespace @@ -96,7 +96,7 @@ namespace Catch { } if (config.listReporters()) { listed = true; - listReporters(reporter, config); + listReporters(reporter); } return listed; } diff --git a/src/catch2/reporters/catch_reporter_combined_tu.cpp b/src/catch2/reporters/catch_reporter_combined_tu.cpp index d9e94aa949..0a15c09836 100644 --- a/src/catch2/reporters/catch_reporter_combined_tu.cpp +++ b/src/catch2/reporters/catch_reporter_combined_tu.cpp @@ -100,13 +100,10 @@ namespace Catch { bool EventListenerBase::assertionEnded( AssertionStats const& ) { return false; } - void - EventListenerBase::listReporters( std::vector const&, - IConfig const& ) {} - void EventListenerBase::listTests( std::vector const&, - IConfig const& ) {} - void EventListenerBase::listTags( std::vector const&, - IConfig const& ) {} + void EventListenerBase::listReporters( + std::vector const& ) {} + void EventListenerBase::listTests( std::vector const& ) {} + void EventListenerBase::listTags( std::vector const& ) {} void EventListenerBase::noMatchingTestCases( std::string const& ) {} void EventListenerBase::testRunStarting( TestRunInfo const& ) {} void EventListenerBase::testGroupStarting( GroupInfo const& ) {} diff --git a/src/catch2/reporters/catch_reporter_event_listener.hpp b/src/catch2/reporters/catch_reporter_event_listener.hpp index df089c08de..ee65eebdfa 100644 --- a/src/catch2/reporters/catch_reporter_event_listener.hpp +++ b/src/catch2/reporters/catch_reporter_event_listener.hpp @@ -27,13 +27,10 @@ namespace Catch { void assertionStarting( AssertionInfo const& assertionInfo ) override; bool assertionEnded( AssertionStats const& assertionStats ) override; - void - listReporters( std::vector const& descriptions, - IConfig const& config ) override; - void listTests( std::vector const& tests, - IConfig const& config ) override; - void listTags( std::vector const& tagInfos, - IConfig const& config ) override; + void listReporters( + std::vector const& descriptions ) override; + void listTests( std::vector const& tests ) override; + void listTags( std::vector const& tagInfos ) override; void noMatchingTestCases( std::string const& spec ) override; void testRunStarting( TestRunInfo const& testRunInfo ) override; diff --git a/src/catch2/reporters/catch_reporter_listening.cpp b/src/catch2/reporters/catch_reporter_listening.cpp index 60059c8457..d189388b1c 100644 --- a/src/catch2/reporters/catch_reporter_listening.cpp +++ b/src/catch2/reporters/catch_reporter_listening.cpp @@ -141,25 +141,25 @@ namespace Catch { m_reporter->skipTest( testInfo ); } - void ListeningReporter::listReporters(std::vector const& descriptions, IConfig const& config) { + void ListeningReporter::listReporters(std::vector const& descriptions) { for (auto const& listener : m_listeners) { - listener->listReporters(descriptions, config); + listener->listReporters(descriptions); } - m_reporter->listReporters(descriptions, config); + m_reporter->listReporters(descriptions); } - void ListeningReporter::listTests(std::vector const& tests, IConfig const& config) { + void ListeningReporter::listTests(std::vector const& tests) { for (auto const& listener : m_listeners) { - listener->listTests(tests, config); + listener->listTests(tests); } - m_reporter->listTests(tests, config); + m_reporter->listTests(tests); } - void ListeningReporter::listTags(std::vector const& tags, IConfig const& config) { + void ListeningReporter::listTags(std::vector const& tags) { for (auto const& listener : m_listeners) { - listener->listTags(tags, config); + listener->listTags(tags); } - m_reporter->listTags(tags, config); + m_reporter->listTags(tags); } } // end namespace Catch diff --git a/src/catch2/reporters/catch_reporter_listening.hpp b/src/catch2/reporters/catch_reporter_listening.hpp index c6485300b6..88234cdc33 100644 --- a/src/catch2/reporters/catch_reporter_listening.hpp +++ b/src/catch2/reporters/catch_reporter_listening.hpp @@ -54,9 +54,9 @@ namespace Catch { void skipTest( TestCaseInfo const& testInfo ) override; - void listReporters(std::vector const& descriptions, IConfig const& config) override; - void listTests(std::vector const& tests, IConfig const& config) override; - void listTags(std::vector const& tags, IConfig const& config) override; + void listReporters(std::vector const& descriptions) override; + void listTests(std::vector const& tests) override; + void listTags(std::vector const& tags) override; }; diff --git a/src/catch2/reporters/catch_reporter_xml.cpp b/src/catch2/reporters/catch_reporter_xml.cpp index 06b9739c96..273a9689dc 100644 --- a/src/catch2/reporters/catch_reporter_xml.cpp +++ b/src/catch2/reporters/catch_reporter_xml.cpp @@ -272,7 +272,7 @@ namespace Catch { m_xml.endElement(); } - void XmlReporter::listReporters(std::vector const& descriptions, IConfig const&) { + void XmlReporter::listReporters(std::vector const& descriptions) { auto outerTag = m_xml.scopedElement("AvailableReporters"); for (auto const& reporter : descriptions) { auto inner = m_xml.scopedElement("Reporter"); @@ -285,7 +285,7 @@ namespace Catch { } } - void XmlReporter::listTests(std::vector const& tests, IConfig const&) { + void XmlReporter::listTests(std::vector const& tests) { auto outerTag = m_xml.scopedElement("MatchingTests"); for (auto const& test : tests) { auto innerTag = m_xml.scopedElement("TestCase"); @@ -310,7 +310,7 @@ namespace Catch { } } - void XmlReporter::listTags(std::vector const& tags, IConfig const&) { + void XmlReporter::listTags(std::vector const& tags) { auto outerTag = m_xml.scopedElement("TagsFromMatchingTests"); for (auto const& tag : tags) { auto innerTag = m_xml.scopedElement("Tag"); diff --git a/src/catch2/reporters/catch_reporter_xml.hpp b/src/catch2/reporters/catch_reporter_xml.hpp index 20ee87ff5c..dbcaaa9322 100644 --- a/src/catch2/reporters/catch_reporter_xml.hpp +++ b/src/catch2/reporters/catch_reporter_xml.hpp @@ -56,9 +56,9 @@ namespace Catch { void benchmarkEnded(BenchmarkStats<> const&) override; void benchmarkFailed(std::string const&) override; - void listReporters(std::vector const& descriptions, IConfig const& config) override; - void listTests(std::vector const& tests, IConfig const& config) override; - void listTags(std::vector const& tags, IConfig const& config) override; + void listReporters(std::vector const& descriptions) override; + void listTests(std::vector const& tests) override; + void listTags(std::vector const& tags) override; private: Timer m_testCaseTimer; From 7111b2a8e232e4a35bd63d772ae889d05185797a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Sat, 16 Jan 2021 15:50:52 +0100 Subject: [PATCH 3/5] Cleanup IStreamingReporter::listTests --- src/catch2/interfaces/catch_interfaces_reporter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/catch2/interfaces/catch_interfaces_reporter.cpp b/src/catch2/interfaces/catch_interfaces_reporter.cpp index 1fd6b6d10b..a2a8bebfe5 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.cpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.cpp @@ -186,10 +186,10 @@ namespace Catch { } } - if (!m_config->hasTestFilters()) { - Catch::cout() << pluralise(tests.size(), "test case") << '\n' << std::endl; - } else { + if (m_config->hasTestFilters()) { Catch::cout() << pluralise(tests.size(), "matching test case") << '\n' << std::endl; + } else { + Catch::cout() << pluralise(tests.size(), "test case") << '\n' << std::endl; } } From 6798c139a65f97ce5ed0105a2a8adb28262ef7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Mon, 25 Jan 2021 12:22:54 +0100 Subject: [PATCH 4/5] Extract the default listing implementation out of reporter interface Also generalized the implementations to write to the provided output stream, which will be required for the follow up changes, where the listings should happen to the location user asked for by specifying the `-o` flag. --- .../interfaces/catch_interfaces_reporter.cpp | 105 ++------------- .../reporters/catch_reporter_combined_tu.cpp | 124 +++++++++++++++++- .../reporters/catch_reporter_helpers.hpp | 40 ++++++ 3 files changed, 171 insertions(+), 98 deletions(-) diff --git a/src/catch2/interfaces/catch_interfaces_reporter.cpp b/src/catch2/interfaces/catch_interfaces_reporter.cpp index a2a8bebfe5..29fafecfd3 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.cpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.cpp @@ -11,34 +11,15 @@ #include #include #include -#include #include #include -#include +#include #include #include namespace Catch { - namespace { - void listTestNamesOnly( std::vector const& tests ) { - for ( auto const& test : tests ) { - auto const& testCaseInfo = test.getTestCaseInfo(); - - if ( startsWith( testCaseInfo.name, '#' ) ) { - Catch::cout() << '"' << testCaseInfo.name << '"'; - } else { - Catch::cout() << testCaseInfo.name; - } - - Catch::cout() << '\n'; - } - Catch::cout() << std::flush; - } - } // end unnamed namespace - - ReporterConfig::ReporterConfig( IConfig const* _fullConfig ) : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} @@ -128,89 +109,19 @@ namespace Catch { void IStreamingReporter::fatalErrorEncountered( StringRef ) {} void IStreamingReporter::listReporters(std::vector const& descriptions) { - Catch::cout() << "Available reporters:\n"; - const auto maxNameLen = std::max_element(descriptions.begin(), descriptions.end(), - [](ReporterDescription const& lhs, ReporterDescription const& rhs) { return lhs.name.size() < rhs.name.size(); }) - ->name.size(); - - for (auto const& desc : descriptions) { - if (m_config->verbosity() == Verbosity::Quiet) { - Catch::cout() - << TextFlow::Column(desc.name) - .indent(2) - .width(5 + maxNameLen) << '\n'; - } else { - Catch::cout() - << TextFlow::Column(desc.name + ":") - .indent(2) - .width(5 + maxNameLen) - + TextFlow::Column(desc.description) - .initialIndent(0) - .indent(2) - .width(CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8) - << '\n'; - } - } - Catch::cout() << std::endl; + defaultListReporters( + Catch::cout(), descriptions, m_config->verbosity() ); } void IStreamingReporter::listTests(std::vector const& tests) { - // We special case this to provide the equivalent of old - // `--list-test-names-only`, which could then be used by the - // `--input-file` option. - if (m_config->verbosity() == Verbosity::Quiet) { - listTestNamesOnly(tests); - return; - } - - if (m_config->hasTestFilters()) { - Catch::cout() << "Matching test cases:\n"; - } else { - Catch::cout() << "All available test cases:\n"; - } - - for (auto const& test : tests) { - auto const& testCaseInfo = test.getTestCaseInfo(); - Colour::Code colour = testCaseInfo.isHidden() - ? Colour::SecondaryText - : Colour::None; - Colour colourGuard(colour); - - Catch::cout() << TextFlow::Column(testCaseInfo.name).initialIndent(2).indent(4) << '\n'; - if (m_config->verbosity() >= Verbosity::High) { - Catch::cout() << TextFlow::Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl; - } - if ( !testCaseInfo.tags.empty() && - m_config->verbosity() > Verbosity::Quiet ) { - Catch::cout() << TextFlow::Column(testCaseInfo.tagsAsString()).indent(6) << '\n'; - } - } - - if (m_config->hasTestFilters()) { - Catch::cout() << pluralise(tests.size(), "matching test case") << '\n' << std::endl; - } else { - Catch::cout() << pluralise(tests.size(), "test case") << '\n' << std::endl; - } + defaultListTests( Catch::cout(), + tests, + m_config->hasTestFilters(), + m_config->verbosity() ); } void IStreamingReporter::listTags(std::vector const& tags) { - if (m_config->hasTestFilters()) { - Catch::cout() << "Tags for matching test cases:\n"; - } else { - Catch::cout() << "All available tags:\n"; - } - - for (auto const& tagCount : tags) { - ReusableStringStream rss; - rss << " " << std::setw(2) << tagCount.count << " "; - auto str = rss.str(); - auto wrapper = TextFlow::Column(tagCount.all()) - .initialIndent(0) - .indent(str.size()) - .width(CATCH_CONFIG_CONSOLE_WIDTH - 10); - Catch::cout() << str << wrapper << '\n'; - } - Catch::cout() << pluralise(tags.size(), "tag") << '\n' << std::endl; + defaultListTags( Catch::cout(), tags, m_config->hasTestFilters() ); } } // end namespace Catch diff --git a/src/catch2/reporters/catch_reporter_combined_tu.cpp b/src/catch2/reporters/catch_reporter_combined_tu.cpp index 0a15c09836..25a52e9dac 100644 --- a/src/catch2/reporters/catch_reporter_combined_tu.cpp +++ b/src/catch2/reporters/catch_reporter_combined_tu.cpp @@ -21,13 +21,40 @@ #include #include #include - +#include +#include +#include +#include +#include +#include + +#include #include #include #include +#include namespace Catch { + namespace { + void listTestNamesOnly(std::ostream& out, + std::vector const& tests) { + for (auto const& test : tests) { + auto const& testCaseInfo = test.getTestCaseInfo(); + + if (startsWith(testCaseInfo.name, '#')) { + out << '"' << testCaseInfo.name << '"'; + } else { + out << testCaseInfo.name; + } + + out << '\n'; + } + out << std::flush; + } + } // end unnamed namespace + + // Because formatting using c++ streams is stateful, drop down to C is // required Alternatively we could use stringstream, but its performance // is... not good. @@ -89,6 +116,101 @@ namespace Catch { return out; } + void + defaultListReporters( std::ostream& out, + std::vector const& descriptions, + Verbosity verbosity ) { + out << "Available reporters:\n"; + const auto maxNameLen = + std::max_element( descriptions.begin(), + descriptions.end(), + []( ReporterDescription const& lhs, + ReporterDescription const& rhs ) { + return lhs.name.size() < rhs.name.size(); + } ) + ->name.size(); + + for ( auto const& desc : descriptions ) { + if ( verbosity == Verbosity::Quiet ) { + out << TextFlow::Column( desc.name ) + .indent( 2 ) + .width( 5 + maxNameLen ) + << '\n'; + } else { + out << TextFlow::Column( desc.name + ":" ) + .indent( 2 ) + .width( 5 + maxNameLen ) + + TextFlow::Column( desc.description ) + .initialIndent( 0 ) + .indent( 2 ) + .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8 ) + << '\n'; + } + } + out << '\n' << std::flush; + } + + void defaultListTags( std::ostream& out, + std::vector const& tags, + bool isFiltered ) { + if ( isFiltered ) { + out << "Tags for matching test cases:\n"; + } else { + out << "All available tags:\n"; + } + + for ( auto const& tagCount : tags ) { + ReusableStringStream rss; + rss << " " << std::setw( 2 ) << tagCount.count << " "; + auto str = rss.str(); + auto wrapper = TextFlow::Column( tagCount.all() ) + .initialIndent( 0 ) + .indent( str.size() ) + .width( CATCH_CONFIG_CONSOLE_WIDTH - 10 ); + out << str << wrapper << '\n'; + } + out << pluralise( tags.size(), "tag" ) << '\n' << std::endl; + } + + void defaultListTests(std::ostream& out, std::vector const& tests, bool isFiltered, Verbosity verbosity) { + // We special case this to provide the equivalent of old + // `--list-test-names-only`, which could then be used by the + // `--input-file` option. + if (verbosity == Verbosity::Quiet) { + listTestNamesOnly(out, tests); + return; + } + + if (isFiltered) { + out << "Matching test cases:\n"; + } else { + out << "All available test cases:\n"; + } + + for (auto const& test : tests) { + auto const& testCaseInfo = test.getTestCaseInfo(); + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard(colour); + + out << TextFlow::Column(testCaseInfo.name).initialIndent(2).indent(4) << '\n'; + if (verbosity >= Verbosity::High) { + out << TextFlow::Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl; + } + if (!testCaseInfo.tags.empty() && + verbosity > Verbosity::Quiet) { + out << TextFlow::Column(testCaseInfo.tagsAsString()).indent(6) << '\n'; + } + } + + if (isFiltered) { + out << pluralise(tests.size(), "matching test case") << '\n' << std::endl; + } else { + out << pluralise(tests.size(), "test case") << '\n' << std::endl; + } + } + } // namespace Catch diff --git a/src/catch2/reporters/catch_reporter_helpers.hpp b/src/catch2/reporters/catch_reporter_helpers.hpp index c86863baa1..d16d92f207 100644 --- a/src/catch2/reporters/catch_reporter_helpers.hpp +++ b/src/catch2/reporters/catch_reporter_helpers.hpp @@ -12,9 +12,13 @@ #include #include +#include +#include + namespace Catch { struct IConfig; + class TestCaseHandle; // Returns double formatted as %.3f (format expected on output) std::string getFormattedDuration( double duration ); @@ -31,6 +35,42 @@ namespace Catch { friend std::ostream& operator<<( std::ostream& out, lineOfChars value ); }; + /** + * Lists reporter descriptions to the provided stream in user-friendly + * format + * + * Used as the default listing implementation by the first party reporter + * bases. The output should be backwards compatible with the output of + * Catch2 v2 binaries. + */ + void + defaultListReporters( std::ostream& out, + std::vector const& descriptions, + Verbosity verbosity ); + + /** + * Lists tag information to the provided stream in user-friendly format + * + * Used as the default listing implementation by the first party reporter + * bases. The output should be backwards compatible with the output of + * Catch2 v2 binaries. + */ + void defaultListTags( std::ostream& out, std::vector const& tags, bool isFiltered ); + + /** + * Lists test case information to the provided stream in user-friendly + * format + * + * Used as the default listing implementation by the first party reporter + * bases. The output is backwards compatible with the output of Catch2 + * v2 binaries, and also supports the format specific to the old + * `--list-test-names-only` option, for people who used it in integrations. + */ + void defaultListTests( std::ostream& out, + std::vector const& tests, + bool isFiltered, + Verbosity verbosity ); + } // end namespace Catch #endif // CATCH_REPORTER_HELPERS_HPP_INCLUDED From 971b1fc32a857caa10eb166f39442cee5237267b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Tue, 26 Jan 2021 17:53:59 +0100 Subject: [PATCH 5/5] --list-* flags write to target specified by the -o flag Also added tests for the default implementations of list* reporter helpers. Closes #2061 --- .../interfaces/catch_interfaces_reporter.cpp | 16 - .../interfaces/catch_interfaces_reporter.hpp | 6 +- .../catch_reporter_cumulative_base.cpp | 16 + .../catch_reporter_cumulative_base.hpp | 5 + .../catch_reporter_streaming_base.cpp | 16 + .../catch_reporter_streaming_base.hpp | 4 + tests/CMakeLists.txt | 1 + .../Baselines/automake.sw.approved.txt | 2 + .../Baselines/compact.sw.approved.txt | 178 ++++ .../Baselines/console.std.approved.txt | 4 +- .../Baselines/console.sw.approved.txt | 767 +++++++++++++++++- .../SelfTest/Baselines/junit.sw.approved.txt | 30 +- .../Baselines/sonarqube.sw.approved.txt | 30 + tests/SelfTest/Baselines/tap.sw.approved.txt | 104 ++- .../Baselines/teamcity.sw.approved.txt | 4 + tests/SelfTest/Baselines/xml.sw.approved.txt | 702 +++++++++++++++- .../IntrospectiveTests/Reporters.tests.cpp | 109 +++ 17 files changed, 1965 insertions(+), 29 deletions(-) create mode 100644 tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp diff --git a/src/catch2/interfaces/catch_interfaces_reporter.cpp b/src/catch2/interfaces/catch_interfaces_reporter.cpp index 29fafecfd3..194161302d 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.cpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.cpp @@ -108,20 +108,4 @@ namespace Catch { void IStreamingReporter::fatalErrorEncountered( StringRef ) {} - void IStreamingReporter::listReporters(std::vector const& descriptions) { - defaultListReporters( - Catch::cout(), descriptions, m_config->verbosity() ); - } - - void IStreamingReporter::listTests(std::vector const& tests) { - defaultListTests( Catch::cout(), - tests, - m_config->hasTestFilters(), - m_config->verbosity() ); - } - - void IStreamingReporter::listTags(std::vector const& tags) { - defaultListTags( Catch::cout(), tags, m_config->hasTestFilters() ); - } - } // end namespace Catch diff --git a/src/catch2/interfaces/catch_interfaces_reporter.hpp b/src/catch2/interfaces/catch_interfaces_reporter.hpp index 5449cc2256..5a4c31a8df 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.hpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.hpp @@ -222,11 +222,11 @@ namespace Catch { virtual void fatalErrorEncountered( StringRef name ); //! Writes out information about provided reporters using reporter-specific format - virtual void listReporters(std::vector const& descriptions); + virtual void listReporters(std::vector const& descriptions) = 0; //! Writes out information about provided tests using reporter-specific format - virtual void listTests(std::vector const& tests); + virtual void listTests(std::vector const& tests) = 0; //! Writes out information about the provided tags using reporter-specific format - virtual void listTags(std::vector const& tags); + virtual void listTags(std::vector const& tags) = 0; }; using IStreamingReporterPtr = Detail::unique_ptr; diff --git a/src/catch2/reporters/catch_reporter_cumulative_base.cpp b/src/catch2/reporters/catch_reporter_cumulative_base.cpp index bba6f67dbd..a83a9ad0ab 100644 --- a/src/catch2/reporters/catch_reporter_cumulative_base.cpp +++ b/src/catch2/reporters/catch_reporter_cumulative_base.cpp @@ -6,6 +6,7 @@ // SPDX-License-Identifier: BSL-1.0 #include +#include #include #include @@ -110,4 +111,19 @@ namespace Catch { testRunEndedCumulative(); } + void CumulativeReporterBase::listReporters(std::vector const& descriptions) { + defaultListReporters(stream, descriptions, m_config->verbosity()); + } + + void CumulativeReporterBase::listTests(std::vector const& tests) { + defaultListTests(stream, + tests, + m_config->hasTestFilters(), + m_config->verbosity()); + } + + void CumulativeReporterBase::listTags(std::vector const& tags) { + defaultListTags( stream, tags, m_config->hasTestFilters() ); + } + } // end namespace Catch diff --git a/src/catch2/reporters/catch_reporter_cumulative_base.hpp b/src/catch2/reporters/catch_reporter_cumulative_base.hpp index 0729567c47..2820e9f622 100644 --- a/src/catch2/reporters/catch_reporter_cumulative_base.hpp +++ b/src/catch2/reporters/catch_reporter_cumulative_base.hpp @@ -69,6 +69,11 @@ namespace Catch { void skipTest(TestCaseInfo const&) override {} + void listReporters( std::vector const& descriptions ) override; + void listTests( std::vector const& tests ) override; + void listTags( std::vector const& tags ) override; + + std::ostream& stream; // Note: We rely on pointer identity being stable, which is why // which is why we store around pointers rather than values. diff --git a/src/catch2/reporters/catch_reporter_streaming_base.cpp b/src/catch2/reporters/catch_reporter_streaming_base.cpp index e4bbb26167..d0b8ae9491 100644 --- a/src/catch2/reporters/catch_reporter_streaming_base.cpp +++ b/src/catch2/reporters/catch_reporter_streaming_base.cpp @@ -6,6 +6,7 @@ // SPDX-License-Identifier: BSL-1.0 #include +#include namespace Catch { @@ -31,4 +32,19 @@ namespace Catch { currentTestRunInfo.reset(); } + void StreamingReporterBase::listReporters(std::vector const& descriptions) { + defaultListReporters( stream, descriptions, m_config->verbosity() ); + } + + void StreamingReporterBase::listTests(std::vector const& tests) { + defaultListTests(stream, + tests, + m_config->hasTestFilters(), + m_config->verbosity()); + } + + void StreamingReporterBase::listTags(std::vector const& tags) { + defaultListTags( 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 ebf0638501..b0f1dd4969 100644 --- a/src/catch2/reporters/catch_reporter_streaming_base.hpp +++ b/src/catch2/reporters/catch_reporter_streaming_base.hpp @@ -71,6 +71,10 @@ namespace Catch { // It can optionally be overridden in the derived class. } + void listReporters( std::vector const& descriptions ) override; + void listTests( std::vector const& tests ) override; + void listTags( std::vector const& tags ) override; + std::ostream& stream; LazyStat currentTestRunInfo; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7a3c6deb66..f8bdb3b4d0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -23,6 +23,7 @@ set(TEST_SOURCES ${SELF_TEST_DIR}/IntrospectiveTests/InternalBenchmark.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/PartTracker.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/RandomNumberGeneration.tests.cpp + ${SELF_TEST_DIR}/IntrospectiveTests/Reporters.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/Tag.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/String.tests.cpp ${SELF_TEST_DIR}/IntrospectiveTests/StringManip.tests.cpp diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt index 87f2a189e0..983d976484 100644 --- a/tests/SelfTest/Baselines/automake.sw.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.approved.txt @@ -185,6 +185,7 @@ Nor would this :test-result: FAIL Reconstruction should be based on stringification: #914 :test-result: FAIL Regex string matcher :test-result: PASS Regression test #1 +:test-result: PASS Reporter's write listings to provided stream :test-result: PASS SUCCEED counts as a test pass :test-result: PASS SUCCEED does not require an argument :test-result: PASS Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods @@ -231,6 +232,7 @@ Message from section two :test-result: PASS Test enum bit values :test-result: PASS Test with special, characters "in name :test-result: FAIL The NO_FAIL macro reports a failure but does not fail the test +:test-result: PASS The default listing implementation write to provided stream :test-result: FAIL This test 'should' fail but doesn't :test-result: FAIL Thrown string literals are translated :test-result: PASS Tracker diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt index 4042f17147..3b19a962d7 100644 --- a/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -1273,6 +1273,169 @@ Matchers.tests.cpp:: failed: testStringForMatching(), Matches("this Matchers.tests.cpp:: failed: testStringForMatching(), Matches("contains 'abc' as a substring") for: "this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively Matchers.tests.cpp:: failed: testStringForMatching(), Matches("this string contains 'abc' as a") for: "this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively Matchers.tests.cpp:: passed: actual, !UnorderedEquals(expected) for: { 'a', 'b' } not UnorderedEquals: { 'c', 'b' } +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" with 1 message: 'Tested reporter: automake' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: automake' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: automake' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" with 1 message: 'Tested reporter: compact' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: compact' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: compact' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" with 1 message: 'Tested reporter: console' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: console' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: console' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: " +All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" with 1 message: 'Tested reporter: junit' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: " +Available reporters: + fake reporter: fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: junit' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: " +All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: junit' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: " +All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" with 1 message: 'Tested reporter: sonarqube' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: " +Available reporters: + fake reporter: fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: sonarqube' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: " +All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: sonarqube' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" with 1 message: 'Tested reporter: tap' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: tap' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: tap' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" with 1 message: 'Tested reporter: teamcity' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: teamcity' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: teamcity' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fakeTag"s) for: " + + + 1 + + fakeTag + + +" contains: "fakeTag" with 1 message: 'Tested reporter: xml' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: " + + + fake reporter + fake description + +" contains: "fake reporter" with 1 message: 'Tested reporter: xml' +Reporters.tests.cpp:: passed: !(factories.empty()) for: !false +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: " + + + fake test name + + [fakeTestTag] + + fake-file.cpp + 123456789 + + +" ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: xml' Message.tests.cpp:: passed: with 1 message: 'this is a success' Message.tests.cpp:: passed: BDD.tests.cpp:: passed: before == 0 for: 0 == 0 @@ -1563,6 +1726,21 @@ VariadicMacros.tests.cpp:: passed: with 1 message: 'no assertions' Tricky.tests.cpp:: passed: 0x == bit30and31 for: 3221225472 (0x) == 3221225472 CmdLine.tests.cpp:: passed: Message.tests.cpp:: failed - but was ok: 1 == 2 +Reporters.tests.cpp:: passed: listingString, Contains("[fakeTag]"s) for: "All available tags: + 1 [fakeTag] +1 tag + +" contains: "[fakeTag]" +Reporters.tests.cpp:: passed: listingString, Contains("fake reporter"s) for: "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +Reporters.tests.cpp:: passed: listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) Misc.tests.cpp:: passed: with 1 message: 'oops!' Exception.tests.cpp:: failed: unexpected exception with message: 'For some reason someone is throwing a string literal!' PartTracker.tests.cpp:: passed: testCase.isOpen() for: true diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt index 149bed95be..d781a60e31 100644 --- a/tests/SelfTest/Baselines/console.std.approved.txt +++ b/tests/SelfTest/Baselines/console.std.approved.txt @@ -1380,6 +1380,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 354 | 280 passed | 70 failed | 4 failed as expected -assertions: 2037 | 1885 passed | 131 failed | 21 failed as expected +test cases: 356 | 282 passed | 70 failed | 4 failed as expected +assertions: 2088 | 1936 passed | 131 failed | 21 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index 1a8d3ef4d2..7066d5938e 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -9399,6 +9399,721 @@ Matchers.tests.cpp:: PASSED: with expansion: { 'a', 'b' } not UnorderedEquals: { 'c', 'b' } +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + automake reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + "All available tags: + 1 [fakeTag] + 1 tag + +" contains: "fakeTag" +with message: + Tested reporter: automake + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + automake reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +with message: + Tested reporter: automake + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + automake reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + "All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: automake + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + compact reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + "All available tags: + 1 [fakeTag] + 1 tag + +" contains: "fakeTag" +with message: + Tested reporter: compact + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + compact reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +with message: + Tested reporter: compact + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + compact reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + "All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: compact + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + console reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + "All available tags: + 1 [fakeTag] + 1 tag + +" contains: "fakeTag" +with message: + Tested reporter: console + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + console reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +with message: + Tested reporter: console + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + console reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + "All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: console + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + junit reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + " + All available tags: + 1 [fakeTag] + 1 tag + +" contains: "fakeTag" +with message: + Tested reporter: junit + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + junit reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + " + Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +with message: + Tested reporter: junit + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + junit reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + " + All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: junit + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + sonarqube reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + " + All available tags: + 1 [fakeTag] + 1 tag + +" contains: "fakeTag" +with message: + Tested reporter: sonarqube + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + sonarqube reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + " + Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +with message: + Tested reporter: sonarqube + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + sonarqube reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + " + All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: sonarqube + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + tap reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + "All available tags: + 1 [fakeTag] + 1 tag + +" contains: "fakeTag" +with message: + Tested reporter: tap + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + tap reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +with message: + Tested reporter: tap + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + tap reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + "All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: tap + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + teamcity reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + "All available tags: + 1 [fakeTag] + 1 tag + +" contains: "fakeTag" +with message: + Tested reporter: teamcity + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + teamcity reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" +with message: + Tested reporter: teamcity + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + teamcity reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + "All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: teamcity + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + xml reporter lists tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fakeTag"s) ) +with expansion: + " + + + 1 + + fakeTag + + + " contains: "fakeTag" +with message: + Tested reporter: xml + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + xml reporter lists reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + " + + + fake reporter + fake description + + " contains: "fake reporter" +with message: + Tested reporter: xml + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_FALSE( factories.empty() ) +with expansion: + !false + +------------------------------------------------------------------------------- +Reporter's write listings to provided stream + xml reporter lists tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + " + + + fake test name + + [fakeTestTag] + + fake-file.cpp + 123456789 + + + " ( contains: "fake test name" and contains: "fakeTestTag" ) +with message: + Tested reporter: xml + ------------------------------------------------------------------------------- SUCCEED counts as a test pass ------------------------------------------------------------------------------- @@ -11641,6 +12356,54 @@ Message.tests.cpp:: FAILED - but was ok: No assertions in test case 'The NO_FAIL macro reports a failure but does not fail the test' +------------------------------------------------------------------------------- +The default listing implementation write to provided stream + Listing tags +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("[fakeTag]"s) ) +with expansion: + "All available tags: + 1 [fakeTag] + 1 tag + +" contains: "[fakeTag]" + +------------------------------------------------------------------------------- +The default listing implementation write to provided stream + Listing reporters +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains("fake reporter"s) ) +with expansion: + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + +------------------------------------------------------------------------------- +The default listing implementation write to provided stream + Listing tests +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) ) +with expansion: + "All available test cases: + fake test name + [fakeTestTag] + 1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + ------------------------------------------------------------------------------- This test 'should' fail but doesn't ------------------------------------------------------------------------------- @@ -16005,6 +16768,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 354 | 264 passed | 86 failed | 4 failed as expected -assertions: 2054 | 1885 passed | 148 failed | 21 failed as expected +test cases: 356 | 266 passed | 86 failed | 4 failed as expected +assertions: 2105 | 1936 passed | 148 failed | 21 failed as expected diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index c7e3d02cd9..5206ed2d18 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -1101,6 +1101,31 @@ Matchers.tests.cpp: + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1252,6 +1277,9 @@ Misc.tests.cpp: + + + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index 736b1b4f3f..1f0cc5dad5 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -150,6 +150,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index b699781e35..edf6d1ed95 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -2468,6 +2468,102 @@ not ok {test-number} - testStringForMatching(), Matches("contains 'abc' as a sub not ok {test-number} - testStringForMatching(), Matches("this string contains 'abc' as a") for: "this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively # Regression test #1 ok {test-number} - actual, !UnorderedEquals(expected) for: { 'a', 'b' } not UnorderedEquals: { 'c', 'b' } +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: "All available tags: 1 [fakeTag] 1 tag " contains: "fakeTag" with 1 message: 'Tested reporter: automake' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: "Available reporters: fake reporter: fake description " contains: "fake reporter" with 1 message: 'Tested reporter: automake' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: automake' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: "All available tags: 1 [fakeTag] 1 tag " contains: "fakeTag" with 1 message: 'Tested reporter: compact' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: "Available reporters: fake reporter: fake description " contains: "fake reporter" with 1 message: 'Tested reporter: compact' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: compact' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: "All available tags: 1 [fakeTag] 1 tag " contains: "fakeTag" with 1 message: 'Tested reporter: console' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: "Available reporters: fake reporter: fake description " contains: "fake reporter" with 1 message: 'Tested reporter: console' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: console' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: " All available tags: 1 [fakeTag] 1 tag " contains: "fakeTag" with 1 message: 'Tested reporter: junit' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: " Available reporters: fake reporter: fake description " contains: "fake reporter" with 1 message: 'Tested reporter: junit' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: " All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: junit' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: " All available tags: 1 [fakeTag] 1 tag " contains: "fakeTag" with 1 message: 'Tested reporter: sonarqube' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: " Available reporters: fake reporter: fake description " contains: "fake reporter" with 1 message: 'Tested reporter: sonarqube' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: " All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: sonarqube' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: "All available tags: 1 [fakeTag] 1 tag " contains: "fakeTag" with 1 message: 'Tested reporter: tap' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: "Available reporters: fake reporter: fake description " contains: "fake reporter" with 1 message: 'Tested reporter: tap' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: tap' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: "All available tags: 1 [fakeTag] 1 tag " contains: "fakeTag" with 1 message: 'Tested reporter: teamcity' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: "Available reporters: fake reporter: fake description " contains: "fake reporter" with 1 message: 'Tested reporter: teamcity' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: teamcity' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fakeTag"s) for: " 1 fakeTag " contains: "fakeTag" with 1 message: 'Tested reporter: xml' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: " fake reporter fake description " contains: "fake reporter" with 1 message: 'Tested reporter: xml' +# Reporter's write listings to provided stream +ok {test-number} - !(factories.empty()) for: !false +# Reporter's write listings to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: " fake test name [fakeTestTag] fake-file.cpp 123456789 " ( contains: "fake test name" and contains: "fakeTestTag" ) with 1 message: 'Tested reporter: xml' # SUCCEED counts as a test pass ok {test-number} - with 1 message: 'this is a success' # SUCCEED does not require an argument @@ -3001,6 +3097,12 @@ ok {test-number} - 0x == bit30and31 for: 3221225472 (0x) ok {test-number} - # The NO_FAIL macro reports a failure but does not fail the test ok {test-number} - 1 == 2 # TODO +# The default listing implementation write to provided stream +ok {test-number} - listingString, Contains("[fakeTag]"s) for: "All available tags: 1 [fakeTag] 1 tag " contains: "[fakeTag]" +# The default listing implementation write to provided stream +ok {test-number} - listingString, Contains("fake reporter"s) for: "Available reporters: fake reporter: fake description " contains: "fake reporter" +# The default listing implementation write to provided stream +ok {test-number} - listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) # This test 'should' fail but doesn't ok {test-number} - with 1 message: 'oops!' # Thrown string literals are translated @@ -4100,5 +4202,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2054 +1..2105 diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt index 413e5153dc..e64c984fb1 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt @@ -475,6 +475,8 @@ Matchers.tests.cpp:|nexpression failed|n CHECK_THAT( testStringFor ##teamcity[testFinished name='Regex string matcher' duration="{duration}"] ##teamcity[testStarted name='Regression test #1'] ##teamcity[testFinished name='Regression test #1' duration="{duration}"] +##teamcity[testStarted name='Reporter|'s write listings to provided stream'] +##teamcity[testFinished name='Reporter|'s write listings to provided stream' duration="{duration}"] ##teamcity[testStarted name='SUCCEED counts as a test pass'] ##teamcity[testFinished name='SUCCEED counts as a test pass' duration="{duration}"] ##teamcity[testStarted name='SUCCEED does not require an argument'] @@ -563,6 +565,8 @@ Misc.tests.cpp:|nexpression failed|n CHECK( s1 == s2 )|nwith expan ##teamcity[testFinished name='Test with special, characters "in name' duration="{duration}"] ##teamcity[testStarted name='The NO_FAIL macro reports a failure but does not fail the test'] ##teamcity[testFinished name='The NO_FAIL macro reports a failure but does not fail the test' duration="{duration}"] +##teamcity[testStarted name='The default listing implementation write to provided stream'] +##teamcity[testFinished name='The default listing implementation write to provided stream' duration="{duration}"] ##teamcity[testStarted name='This test |'should|' fail but doesn|'t'] ##teamcity[testFinished name='This test |'should|' fail but doesn|'t' duration="{duration}"] ##teamcity[testStarted name='Thrown string literals are translated'] diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index e13949a085..ceaa32bcb8 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -11483,6 +11483,652 @@ Nor would this + + + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: automake + + + + listingString, Contains("fakeTag"s) + + + "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: automake + + + + listingString, Contains("fake reporter"s) + + + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: automake + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: compact + + + + listingString, Contains("fakeTag"s) + + + "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: compact + + + + listingString, Contains("fake reporter"s) + + + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: compact + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: console + + + + listingString, Contains("fakeTag"s) + + + "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: console + + + + listingString, Contains("fake reporter"s) + + + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: console + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: junit + + + + listingString, Contains("fakeTag"s) + + + "<?xml version="1.0" encoding="UTF-8"?> +All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: junit + + + + listingString, Contains("fake reporter"s) + + + "<?xml version="1.0" encoding="UTF-8"?> +Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: junit + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "<?xml version="1.0" encoding="UTF-8"?> +All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: sonarqube + + + + listingString, Contains("fakeTag"s) + + + "<?xml version="1.0" encoding="UTF-8"?> +All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: sonarqube + + + + listingString, Contains("fake reporter"s) + + + "<?xml version="1.0" encoding="UTF-8"?> +Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: sonarqube + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "<?xml version="1.0" encoding="UTF-8"?> +All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: tap + + + + listingString, Contains("fakeTag"s) + + + "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: tap + + + + listingString, Contains("fake reporter"s) + + + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: tap + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: teamcity + + + + listingString, Contains("fakeTag"s) + + + "All available tags: + 1 [fakeTag] +1 tag + +" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: teamcity + + + + listingString, Contains("fake reporter"s) + + + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: teamcity + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: xml + + + + listingString, Contains("fakeTag"s) + + + "<?xml version="1.0" encoding="UTF-8"?> +<TagsFromMatchingTests> + <Tag> + <Count>1</Count> + <Aliases> + <Alias>fakeTag</Alias> + </Aliases> + </Tag> +</TagsFromMatchingTests>" contains: "fakeTag" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: xml + + + + listingString, Contains("fake reporter"s) + + + "<?xml version="1.0" encoding="UTF-8"?> +<AvailableReporters> + <Reporter> + <Name>fake reporter</Name> + <Description>fake description</Description> + </Reporter> +</AvailableReporters>" contains: "fake reporter" + + + +
+ + + !(factories.empty()) + + + !false + + +
+ + Tested reporter: xml + + + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "<?xml version="1.0" encoding="UTF-8"?> +<MatchingTests> + <TestCase> + <Name>fake test name</Name> + <ClassName/> + <Tags>[fakeTestTag]</Tags> + <SourceInfo> + <File>fake-file.cpp</File> + <Line>123456789</Line> + </SourceInfo> + </TestCase> +</MatchingTests>" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ +
@@ -13838,6 +14484,54 @@ Message from section two
+ +
+ + + listingString, Contains("[fakeTag]"s) + + + "All available tags: + 1 [fakeTag] +1 tag + +" contains: "[fakeTag]" + + + +
+
+ + + listingString, Contains("fake reporter"s) + + + "Available reporters: + fake reporter: fake description + +" contains: "fake reporter" + + + +
+
+ + + listingString, Contains( "fake test name"s ) && Contains( "fakeTestTag"s ) + + + "All available test cases: + fake test name + [fakeTestTag] +1 test case + +" ( contains: "fake test name" and contains: "fakeTestTag" ) + + + +
+ +
@@ -19021,9 +19715,9 @@ loose text artifact
- - + + - - + + diff --git a/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp b/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp new file mode 100644 index 0000000000..c5c97998b8 --- /dev/null +++ b/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp @@ -0,0 +1,109 @@ + +// 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 + +#include + +TEST_CASE( "The default listing implementation write to provided stream", + "[reporters][reporter-helpers]" ) { + using Catch::Matchers::Contains; + using namespace std::string_literals; + + std::stringstream sstream; + SECTION( "Listing tags" ) { + std::vector tags(1); + tags[0].add("fakeTag"_catch_sr); + Catch::defaultListTags(sstream, tags, false); + + auto listingString = sstream.str(); + REQUIRE_THAT(listingString, Contains("[fakeTag]"s)); + } + SECTION( "Listing reporters" ) { + std::vector reporters( + { { "fake reporter", "fake description" } } ); + Catch::defaultListReporters(sstream, reporters, Catch::Verbosity::Normal); + + auto listingString = sstream.str(); + REQUIRE_THAT(listingString, Contains("fake reporter"s)); + } + SECTION( "Listing tests" ) { + Catch::TestCaseInfo fakeInfo{ + ""s, + { "fake test name"_catch_sr, "[fakeTestTag]"_catch_sr }, + { "fake-file.cpp", 123456789 } }; + std::vector tests({ {&fakeInfo, nullptr} }); + Catch::defaultListTests(sstream, tests, false, Catch::Verbosity::Normal); + + auto listingString = sstream.str(); + REQUIRE_THAT( listingString, + Contains( "fake test name"s ) && + Contains( "fakeTestTag"s ) ); + } +} + +TEST_CASE( "Reporter's write listings to provided stream", "[reporters]" ) { + using Catch::Matchers::Contains; + using namespace std::string_literals; + + auto const& factories = Catch::getRegistryHub().getReporterRegistry().getFactories(); + // If there are no reporters, the test would pass falsely + // while there is something obviously broken + REQUIRE_FALSE(factories.empty()); + + for (auto const& factory : factories) { + INFO("Tested reporter: " << factory.first); + std::stringstream sstream; + + Catch::ConfigData config_data; + Catch::Config config( config_data ); + Catch::ReporterConfig rep_config( &config, sstream ); + auto reporter = factory.second->create( rep_config ); + + DYNAMIC_SECTION( factory.first << " reporter lists tags" ) { + std::vector tags(1); + tags[0].add("fakeTag"_catch_sr); + reporter->listTags(tags); + + auto listingString = sstream.str(); + REQUIRE_THAT(listingString, Contains("fakeTag"s)); + } + + DYNAMIC_SECTION( factory.first << " reporter lists reporters" ) { + std::vector reporters( + { { "fake reporter", "fake description" } } ); + reporter->listReporters(reporters); + + auto listingString = sstream.str(); + REQUIRE_THAT(listingString, Contains("fake reporter"s)); + } + + DYNAMIC_SECTION( factory.first << " reporter lists tests" ) { + Catch::TestCaseInfo fakeInfo{ + ""s, + { "fake test name"_catch_sr, "[fakeTestTag]"_catch_sr }, + { "fake-file.cpp", 123456789 } }; + std::vector tests({ {&fakeInfo, nullptr} }); + reporter->listTests(tests); + + auto listingString = sstream.str(); + REQUIRE_THAT( listingString, + Contains( "fake test name"s ) && + Contains( "fakeTestTag"s ) ); + } + } +}