From 5a49285e9cf203dd20b00ac7488a6a3233d60fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Tue, 10 May 2022 20:00:36 +0200 Subject: [PATCH] Add --list-listeners option --- docs/command-line.md | 6 ++++ docs/release-notes.md | 1 + src/catch2/catch_config.cpp | 1 + src/catch2/catch_config.hpp | 2 ++ .../interfaces/catch_interfaces_reporter.hpp | 4 ++- .../catch_interfaces_reporter_factory.hpp | 4 +++ src/catch2/internal/catch_commandline.cpp | 5 +++- src/catch2/internal/catch_list.cpp | 17 +++++++++++ src/catch2/internal/catch_list.hpp | 4 +++ .../reporters/catch_reporter_combined_tu.cpp | 29 +++++++++++++++++++ .../reporters/catch_reporter_common_base.cpp | 5 ++++ .../reporters/catch_reporter_common_base.hpp | 8 +++++ .../catch_reporter_event_listener.hpp | 2 ++ .../reporters/catch_reporter_helpers.hpp | 7 +++++ src/catch2/reporters/catch_reporter_multi.cpp | 7 +++++ src/catch2/reporters/catch_reporter_multi.hpp | 1 + .../reporters/catch_reporter_registrars.hpp | 17 ++++++----- tests/CMakeLists.txt | 12 ++++++++ .../Baselines/compact.sw.approved.txt | 4 +++ .../Baselines/compact.sw.multi.approved.txt | 4 +++ .../Baselines/console.std.approved.txt | 2 +- .../Baselines/console.sw.approved.txt | 17 ++++++++++- .../Baselines/console.sw.multi.approved.txt | 17 ++++++++++- .../SelfTest/Baselines/junit.sw.approved.txt | 3 +- .../Baselines/junit.sw.multi.approved.txt | 3 +- .../Baselines/sonarqube.sw.approved.txt | 1 + .../Baselines/sonarqube.sw.multi.approved.txt | 1 + tests/SelfTest/Baselines/tap.sw.approved.txt | 4 ++- .../Baselines/tap.sw.multi.approved.txt | 4 ++- tests/SelfTest/Baselines/xml.sw.approved.txt | 16 +++++++++- .../Baselines/xml.sw.multi.approved.txt | 16 +++++++++- .../IntrospectiveTests/Reporters.tests.cpp | 10 +++++++ tests/SelfTest/TestRegistrations.cpp | 4 +++ 33 files changed, 220 insertions(+), 18 deletions(-) diff --git a/docs/command-line.md b/docs/command-line.md index 2e3db85b..4b9ec7a0 100644 --- a/docs/command-line.md +++ b/docs/command-line.md @@ -59,6 +59,7 @@ Click one of the following links to take you straight to that option - or scroll ` --list-tests`
` --list-tags`
` --list-reporters`
+ ` --list-listeners`
` --order`
` --rng-seed`
` --libidentify`
@@ -200,10 +201,13 @@ Sometimes this results in a flood of failure messages and you'd rather just see --list-tests --list-tags --list-reporters +--list-listeners ``` > The `--list*` options became customizable through reporters in Catch2 X.Y.Z +> The `--list-listeners` option was added in Catch2 X.Y.Z + `--list-tests` lists all registered tests matching specified test spec. Usually this listing also includes tags, and potentially also other information, like source location, based on verbosity and reporter's design. @@ -214,6 +218,8 @@ similar information. `--list-reporters` lists all available reporters and their descriptions. +`--list-listeners` lists all registered listeners and their descriptions. + ## Sending output to a file diff --git a/docs/release-notes.md b/docs/release-notes.md index a342e915..1b0188b4 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -192,6 +192,7 @@ v3 releases. * Added a support for Bazel integration with `XML_OUTPUT_FILE` env var (#2399) * This has to be enabled during compilation. * Added `--skip-benchmarks` flag to run tests without any `BENCHMARK`s (#2392, #2408) +* Added option to list all listeners in the binary via `--list-listeners` ### Fixes diff --git a/src/catch2/catch_config.cpp b/src/catch2/catch_config.cpp index e3ce6b65..670cc4f7 100644 --- a/src/catch2/catch_config.cpp +++ b/src/catch2/catch_config.cpp @@ -111,6 +111,7 @@ namespace Catch { bool Config::listTests() const { return m_data.listTests; } bool Config::listTags() const { return m_data.listTags; } bool Config::listReporters() const { return m_data.listReporters; } + bool Config::listListeners() const { return m_data.listListeners; } std::vector const& Config::getTestsOrTags() const { return m_data.testsOrTags; } std::vector const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } diff --git a/src/catch2/catch_config.hpp b/src/catch2/catch_config.hpp index a3dc010b..10df4d64 100644 --- a/src/catch2/catch_config.hpp +++ b/src/catch2/catch_config.hpp @@ -48,6 +48,7 @@ namespace Catch { bool listTests = false; bool listTags = false; bool listReporters = false; + bool listListeners = false; bool showSuccessfulTests = false; bool shouldDebugBreak = false; @@ -99,6 +100,7 @@ namespace Catch { bool listTests() const; bool listTags() const; bool listReporters() const; + bool listListeners() const; std::vector const& getReporterSpecs() const; std::vector const& diff --git a/src/catch2/interfaces/catch_interfaces_reporter.hpp b/src/catch2/interfaces/catch_interfaces_reporter.hpp index 1a2736f7..42192438 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter.hpp +++ b/src/catch2/interfaces/catch_interfaces_reporter.hpp @@ -27,6 +27,7 @@ namespace Catch { struct ReporterDescription; + struct ListenerDescription; struct TagInfo; struct TestCaseInfo; class TestCaseHandle; @@ -249,11 +250,12 @@ namespace Catch { //! Writes out information about provided reporters using reporter-specific format virtual void listReporters(std::vector const& descriptions) = 0; + //! Writes out the provided listeners descriptions using reporter-specific format + virtual void listListeners(std::vector const& descriptions) = 0; //! Writes out information about provided tests using reporter-specific format 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) = 0; - }; using IEventListenerPtr = Detail::unique_ptr; diff --git a/src/catch2/interfaces/catch_interfaces_reporter_factory.hpp b/src/catch2/interfaces/catch_interfaces_reporter_factory.hpp index 76dce504..323edde2 100644 --- a/src/catch2/interfaces/catch_interfaces_reporter_factory.hpp +++ b/src/catch2/interfaces/catch_interfaces_reporter_factory.hpp @@ -9,6 +9,7 @@ #define CATCH_INTERFACES_REPORTER_FACTORY_HPP_INCLUDED #include +#include #include @@ -34,6 +35,9 @@ namespace Catch { public: virtual ~EventListenerFactory(); // = default virtual IEventListenerPtr create( IConfig const* config ) const = 0; + //! Return a meaningful name for the listener, e.g. its type name + virtual StringRef getName() const = 0; + //! Return listener's description if available virtual std::string getDescription() const = 0; }; } // namespace Catch diff --git a/src/catch2/internal/catch_commandline.cpp b/src/catch2/internal/catch_commandline.cpp index f2f638bc..fda4b2bd 100644 --- a/src/catch2/internal/catch_commandline.cpp +++ b/src/catch2/internal/catch_commandline.cpp @@ -280,7 +280,10 @@ namespace Catch { ( "list all/matching tags" ) | Opt( config.listReporters ) ["--list-reporters"] - ( "list all reporters" ) + ( "list all available reporters" ) + | Opt( config.listListeners ) + ["--list-listeners"] + ( "list all listeners" ) | Opt( setTestOrder, "decl|lex|rand" ) ["--order"] ( "test case order (defaults to decl)" ) diff --git a/src/catch2/internal/catch_list.cpp b/src/catch2/internal/catch_list.cpp index 609d459c..2c22745c 100644 --- a/src/catch2/internal/catch_list.cpp +++ b/src/catch2/internal/catch_list.cpp @@ -63,6 +63,19 @@ namespace Catch { reporter.listReporters(descriptions); } + void listListeners(IEventListener& reporter) { + std::vector descriptions; + + auto const& factories = + getRegistryHub().getReporterRegistry().getListeners(); + descriptions.reserve( factories.size() ); + for ( auto const& fac : factories ) { + descriptions.push_back( { fac->getName(), fac->getDescription() } ); + } + + reporter.listListeners( descriptions ); + } + } // end anonymous namespace void TagInfo::add( StringRef spelling ) { @@ -100,6 +113,10 @@ namespace Catch { listed = true; listReporters(reporter); } + if ( config.listListeners() ) { + listed = true; + listListeners( reporter ); + } return listed; } diff --git a/src/catch2/internal/catch_list.hpp b/src/catch2/internal/catch_list.hpp index 9caf4cf6..6fd759ea 100644 --- a/src/catch2/internal/catch_list.hpp +++ b/src/catch2/internal/catch_list.hpp @@ -23,6 +23,10 @@ namespace Catch { struct ReporterDescription { std::string name, description; }; + struct ListenerDescription { + StringRef name; + std::string description; + }; struct TagInfo { void add(StringRef spelling); diff --git a/src/catch2/reporters/catch_reporter_combined_tu.cpp b/src/catch2/reporters/catch_reporter_combined_tu.cpp index 77d2b52d..06259433 100644 --- a/src/catch2/reporters/catch_reporter_combined_tu.cpp +++ b/src/catch2/reporters/catch_reporter_combined_tu.cpp @@ -152,6 +152,33 @@ namespace Catch { out << '\n' << std::flush; } + void defaultListListeners( std::ostream& out, + std::vector const& descriptions ) { + const auto maxNameLen = + std::max_element( descriptions.begin(), + descriptions.end(), + []( ListenerDescription const& lhs, + ListenerDescription const& rhs ) { + return lhs.name.size() < rhs.name.size(); + } ) + ->name.size(); + + out << "Registered listeners:\n"; + for ( auto const& desc : descriptions ) { + out << TextFlow::Column( static_cast( desc.name ) + + ':' ) + .indent( 2 ) + .width( maxNameLen + 5 ) + + 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 ) { @@ -233,6 +260,8 @@ namespace Catch { void EventListenerBase::assertionEnded( AssertionStats const& ) {} void EventListenerBase::listReporters( std::vector const& ) {} + void EventListenerBase::listListeners( + std::vector const& ) {} void EventListenerBase::listTests( std::vector const& ) {} void EventListenerBase::listTags( std::vector const& ) {} void EventListenerBase::noMatchingTestCases( StringRef ) {} diff --git a/src/catch2/reporters/catch_reporter_common_base.cpp b/src/catch2/reporters/catch_reporter_common_base.cpp index f4736ab2..698435d0 100644 --- a/src/catch2/reporters/catch_reporter_common_base.cpp +++ b/src/catch2/reporters/catch_reporter_common_base.cpp @@ -29,6 +29,11 @@ namespace Catch { defaultListReporters(m_stream, descriptions, m_config->verbosity()); } + void ReporterBase::listListeners( + std::vector const& descriptions ) { + defaultListListeners( m_stream, descriptions ); + } + void ReporterBase::listTests(std::vector const& tests) { defaultListTests(m_stream, m_colour.get(), diff --git a/src/catch2/reporters/catch_reporter_common_base.hpp b/src/catch2/reporters/catch_reporter_common_base.hpp index 5d80ca29..e6888be1 100644 --- a/src/catch2/reporters/catch_reporter_common_base.hpp +++ b/src/catch2/reporters/catch_reporter_common_base.hpp @@ -50,6 +50,14 @@ namespace Catch { */ void listReporters( std::vector const& descriptions ) override; + /** + * Provides a simple default listing of listeners + * + * Looks similarly to listing of reporters, but with listener type + * instead of reporter name. + */ + void listListeners( + std::vector const& descriptions ) override; /** * Provides a simple default listing of tests. * diff --git a/src/catch2/reporters/catch_reporter_event_listener.hpp b/src/catch2/reporters/catch_reporter_event_listener.hpp index 383b080a..3a6d822c 100644 --- a/src/catch2/reporters/catch_reporter_event_listener.hpp +++ b/src/catch2/reporters/catch_reporter_event_listener.hpp @@ -36,6 +36,8 @@ namespace Catch { void listReporters( std::vector const& descriptions ) override; + void listListeners( + std::vector const& descriptions ) override; void listTests( std::vector const& tests ) override; void listTags( std::vector const& tagInfos ) override; diff --git a/src/catch2/reporters/catch_reporter_helpers.hpp b/src/catch2/reporters/catch_reporter_helpers.hpp index 28ab966c..ef43534c 100644 --- a/src/catch2/reporters/catch_reporter_helpers.hpp +++ b/src/catch2/reporters/catch_reporter_helpers.hpp @@ -49,6 +49,13 @@ namespace Catch { std::vector const& descriptions, Verbosity verbosity ); + /** + * Lists listeners descriptions to the provided stream in user-friendly + * format + */ + void defaultListListeners( std::ostream& out, + std::vector const& descriptions ); + /** * Lists tag information to the provided stream in user-friendly format * diff --git a/src/catch2/reporters/catch_reporter_multi.cpp b/src/catch2/reporters/catch_reporter_multi.cpp index e7ba7e5d..cf18cb81 100644 --- a/src/catch2/reporters/catch_reporter_multi.cpp +++ b/src/catch2/reporters/catch_reporter_multi.cpp @@ -176,6 +176,13 @@ namespace Catch { } } + void MultiReporter::listListeners( + std::vector const& descriptions ) { + for ( auto& reporterish : m_reporterLikes ) { + reporterish->listListeners( descriptions ); + } + } + void MultiReporter::listTests(std::vector const& tests) { for (auto& reporterish : m_reporterLikes) { reporterish->listTests(tests); diff --git a/src/catch2/reporters/catch_reporter_multi.hpp b/src/catch2/reporters/catch_reporter_multi.hpp index 29f2693f..e35ea504 100644 --- a/src/catch2/reporters/catch_reporter_multi.hpp +++ b/src/catch2/reporters/catch_reporter_multi.hpp @@ -60,6 +60,7 @@ namespace Catch { void skipTest( TestCaseInfo const& testInfo ) override; void listReporters(std::vector const& descriptions) override; + void listListeners(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_registrars.hpp b/src/catch2/reporters/catch_reporter_registrars.hpp index 19d97b3b..e0922524 100644 --- a/src/catch2/reporters/catch_reporter_registrars.hpp +++ b/src/catch2/reporters/catch_reporter_registrars.hpp @@ -59,33 +59,36 @@ namespace Catch { class ListenerRegistrar { class TypedListenerFactory : public EventListenerFactory { - StringRef m_defaultDescription; + StringRef m_listenerName; std::string getDescriptionImpl( std::true_type ) const { return T::getDescription(); } std::string getDescriptionImpl( std::false_type ) const { - return static_cast(m_defaultDescription); + return "(No description provided)"; } public: - TypedListenerFactory( StringRef defaultDescription ): - m_defaultDescription( defaultDescription ) {} + TypedListenerFactory( StringRef listenerName ): + m_listenerName( listenerName ) {} IEventListenerPtr create( IConfig const* config ) const override { return Detail::make_unique( config ); } + StringRef getName() const override { + return m_listenerName; + } + std::string getDescription() const override { return getDescriptionImpl( Detail::has_description{} ); } }; public: - - ListenerRegistrar(StringRef defaultDescription) { - getMutableRegistryHub().registerListener( Detail::make_unique(defaultDescription) ); + ListenerRegistrar(StringRef listenerName) { + getMutableRegistryHub().registerListener( Detail::make_unique(listenerName) ); } }; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 431dae65..fa63e7c0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -207,6 +207,18 @@ set_tests_properties(List::Reporters::XmlOutput PROPERTIES FAIL_REGULAR_EXPRESSION "Available reporters:" ) +add_test(NAME List::Listeners::Output + COMMAND + $ --list-listeners +) +set_tests_properties(List::Listeners::Output + PROPERTIES + PASS_REGULAR_EXPRESSION "Registered listeners:" +) +add_test(NAME List::Listeners::ExitCode + COMMAND + $ --list-listeners +) add_test(NAME NoAssertions COMMAND $ -w NoAssertions "An empty test with no assertions") diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt index bc88e377..7221ac6a 100644 --- a/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -1898,6 +1898,10 @@ Reporters.tests.cpp:: passed: listingString, ContainsSubstring( "fa 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) +Reporters.tests.cpp:: passed: listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) for: "Registered listeners: + fakeListener: fake description + +" ( contains: "fakeListener" and contains: "fake description" ) 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/compact.sw.multi.approved.txt b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt index 7d33ae33..6945b6be 100644 --- a/tests/SelfTest/Baselines/compact.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.multi.approved.txt @@ -1891,6 +1891,10 @@ Reporters.tests.cpp:: passed: listingString, ContainsSubstring( "fa 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) +Reporters.tests.cpp:: passed: listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) for: "Registered listeners: + fakeListener: fake description + +" ( contains: "fakeListener" and contains: "fake description" ) 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 2f01bf6f..0ad308be 100644 --- a/tests/SelfTest/Baselines/console.std.approved.txt +++ b/tests/SelfTest/Baselines/console.std.approved.txt @@ -1395,5 +1395,5 @@ due to unexpected exception with message: =============================================================================== test cases: 391 | 315 passed | 69 failed | 7 failed as expected -assertions: 2226 | 2071 passed | 128 failed | 27 failed as expected +assertions: 2227 | 2072 passed | 128 failed | 27 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index 0078f507..d4a434cc 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -13444,6 +13444,21 @@ with expansion: " ( contains: "fake test name" and contains: "fakeTestTag" ) +------------------------------------------------------------------------------- +The default listing implementation write to provided stream + Listing listeners +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) ) +with expansion: + "Registered listeners: + fakeListener: fake description + +" ( contains: "fakeListener" and contains: "fake description" ) + ------------------------------------------------------------------------------- This test 'should' fail but doesn't ------------------------------------------------------------------------------- @@ -17935,5 +17950,5 @@ Misc.tests.cpp:: PASSED: =============================================================================== test cases: 391 | 301 passed | 83 failed | 7 failed as expected -assertions: 2241 | 2071 passed | 143 failed | 27 failed as expected +assertions: 2242 | 2072 passed | 143 failed | 27 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.multi.approved.txt b/tests/SelfTest/Baselines/console.sw.multi.approved.txt index 96a8268d..97b95f13 100644 --- a/tests/SelfTest/Baselines/console.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.multi.approved.txt @@ -13437,6 +13437,21 @@ with expansion: " ( contains: "fake test name" and contains: "fakeTestTag" ) +------------------------------------------------------------------------------- +The default listing implementation write to provided stream + Listing listeners +------------------------------------------------------------------------------- +Reporters.tests.cpp: +............................................................................... + +Reporters.tests.cpp:: PASSED: + REQUIRE_THAT( listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) ) +with expansion: + "Registered listeners: + fakeListener: fake description + +" ( contains: "fakeListener" and contains: "fake description" ) + ------------------------------------------------------------------------------- This test 'should' fail but doesn't ------------------------------------------------------------------------------- @@ -17927,5 +17942,5 @@ Misc.tests.cpp:: PASSED: =============================================================================== test cases: 391 | 301 passed | 83 failed | 7 failed as expected -assertions: 2241 | 2071 passed | 143 failed | 27 failed as expected +assertions: 2242 | 2072 passed | 143 failed | 27 failed as expected diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index fc059acd..e37a94ce 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -1379,6 +1379,7 @@ Misc.tests.cpp: + diff --git a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt index 06ade42c..07614974 100644 --- a/tests/SelfTest/Baselines/junit.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.multi.approved.txt @@ -1,6 +1,6 @@ - + @@ -1378,6 +1378,7 @@ Misc.tests.cpp: + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index 4cdab2d3..6e88a61f 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -220,6 +220,7 @@ + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt index d5608195..6756a626 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.multi.approved.txt @@ -219,6 +219,7 @@ + diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index 4cd3cef3..ed0d9e0c 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -3338,6 +3338,8 @@ ok {test-number} - listingString, ContainsSubstring("[fakeTag]"s) for: "All avai ok {test-number} - listingString, ContainsSubstring( "fake reporter"s ) && ContainsSubstring( "fake description"s ) for: "Available reporters: fake reporter: fake description " ( contains: "fake reporter" and contains: "fake description" ) # The default listing implementation write to provided stream ok {test-number} - listingString, ContainsSubstring( "fake test name"s ) && ContainsSubstring( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) +# The default listing implementation write to provided stream +ok {test-number} - listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) for: "Registered listeners: fakeListener: fake description " ( contains: "fakeListener" and contains: "fake description" ) # This test 'should' fail but doesn't ok {test-number} - with 1 message: 'oops!' # Thrown string literals are translated @@ -4485,5 +4487,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2241 +1..2242 diff --git a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt index a87ce7c6..874a825c 100644 --- a/tests/SelfTest/Baselines/tap.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.multi.approved.txt @@ -3331,6 +3331,8 @@ ok {test-number} - listingString, ContainsSubstring("[fakeTag]"s) for: "All avai ok {test-number} - listingString, ContainsSubstring( "fake reporter"s ) && ContainsSubstring( "fake description"s ) for: "Available reporters: fake reporter: fake description " ( contains: "fake reporter" and contains: "fake description" ) # The default listing implementation write to provided stream ok {test-number} - listingString, ContainsSubstring( "fake test name"s ) && ContainsSubstring( "fakeTestTag"s ) for: "All available test cases: fake test name [fakeTestTag] 1 test case " ( contains: "fake test name" and contains: "fakeTestTag" ) +# The default listing implementation write to provided stream +ok {test-number} - listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) for: "Registered listeners: fakeListener: fake description " ( contains: "fakeListener" and contains: "fake description" ) # This test 'should' fail but doesn't ok {test-number} - with 1 message: 'oops!' # Thrown string literals are translated @@ -4477,5 +4479,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2241 +1..2242 diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index 4523d64a..1dad9f6f 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -15754,6 +15754,20 @@ Message from section two +
+ + + listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) + + + "Registered listeners: + fakeListener: fake description + +" ( contains: "fakeListener" and contains: "fake description" ) + + + +
@@ -21061,6 +21075,6 @@ loose text artifact - + diff --git a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt index 4c20e564..6e432e40 100644 --- a/tests/SelfTest/Baselines/xml.sw.multi.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.multi.approved.txt @@ -15754,6 +15754,20 @@ Message from section two +
+ + + listingString, ContainsSubstring( "fakeListener"s ) && ContainsSubstring( "fake description"s ) + + + "Registered listeners: + fakeListener: fake description + +" ( contains: "fakeListener" and contains: "fake description" ) + + + +
@@ -21060,6 +21074,6 @@ There is no extra whitespace here - + diff --git a/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp b/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp index 5e8f11c7..5dde7038 100644 --- a/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp +++ b/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp @@ -84,6 +84,16 @@ TEST_CASE( "The default listing implementation write to provided stream", ContainsSubstring( "fake test name"s ) && ContainsSubstring( "fakeTestTag"s ) ); } + SECTION( "Listing listeners" ) { + std::vector listeners( + { { "fakeListener"_catch_sr, "fake description" } } ); + + Catch::defaultListListeners( sstream.stream(), listeners ); + auto listingString = sstream.str(); + REQUIRE_THAT( listingString, + ContainsSubstring( "fakeListener"s ) && + ContainsSubstring( "fake description"s ) ); + } } TEST_CASE( "Reporter's write listings to provided stream", "[reporters]" ) { diff --git a/tests/SelfTest/TestRegistrations.cpp b/tests/SelfTest/TestRegistrations.cpp index 2586ffab..f24c913f 100644 --- a/tests/SelfTest/TestRegistrations.cpp +++ b/tests/SelfTest/TestRegistrations.cpp @@ -48,6 +48,10 @@ class ValidatingTestListener : public Catch::EventListenerBase { }; public: + static std::string getDescription() { + return "Validates ordering of Catch2's listener events"; + } + ValidatingTestListener(Catch::IConfig const* config) : EventListenerBase(config) { m_preferences.shouldReportAllAssertions = true;