aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/catch2/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp
diff options
context:
space:
mode:
authorLexi Winter <lexi@le-fay.org>2025-06-29 19:28:09 +0100
committerLexi Winter <lexi@le-fay.org>2025-06-29 19:28:09 +0100
commit67b2fae1fa8b033045a44c1355d9dfd8f83e0d9b (patch)
tree1ecd818f4bcf7d12622d43dc92c4d4bb9b746d0f /contrib/catch2/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp
parenta8b0ea58e60bb0326b7f7c8f3c736d89ce9ef1df (diff)
parentbc524d70253a4ab2fe40c3ca3e5666e267c0a4d1 (diff)
downloadnihil-67b2fae1fa8b033045a44c1355d9dfd8f83e0d9b.tar.gz
nihil-67b2fae1fa8b033045a44c1355d9dfd8f83e0d9b.tar.bz2
Add 'contrib/catch2/' from commit 'bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1'
git-subtree-dir: contrib/catch2 git-subtree-mainline: a8b0ea58e60bb0326b7f7c8f3c736d89ce9ef1df git-subtree-split: bc524d70253a4ab2fe40c3ca3e5666e267c0a4d1
Diffstat (limited to 'contrib/catch2/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp')
-rw-r--r--contrib/catch2/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp330
1 files changed, 330 insertions, 0 deletions
diff --git a/contrib/catch2/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp b/contrib/catch2/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp
new file mode 100644
index 0000000..86ba117
--- /dev/null
+++ b/contrib/catch2/tests/SelfTest/IntrospectiveTests/Reporters.tests.cpp
@@ -0,0 +1,330 @@
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+
+#include <catch2/catch_test_macros.hpp>
+
+#include <catch2/catch_test_case_info.hpp>
+#include <catch2/catch_config.hpp>
+#include <catch2/interfaces/catch_interfaces_reporter.hpp>
+#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
+#include <catch2/internal/catch_console_colour.hpp>
+#include <catch2/internal/catch_enforce.hpp>
+#include <catch2/internal/catch_list.hpp>
+#include <catch2/internal/catch_reporter_registry.hpp>
+#include <catch2/internal/catch_istream.hpp>
+#include <catch2/matchers/catch_matchers_string.hpp>
+#include <catch2/reporters/catch_reporter_helpers.hpp>
+#include <catch2/reporters/catch_reporter_event_listener.hpp>
+#include <catch2/reporters/catch_reporter_streaming_base.hpp>
+#include <catch2/reporters/catch_reporter_multi.hpp>
+#include <catch2/internal/catch_move_and_forward.hpp>
+
+#include <sstream>
+
+namespace {
+ class StringIStream : public Catch::IStream {
+ public:
+ std::ostream& stream() override { return sstr; }
+ std::string str() const { return sstr.str(); }
+ private:
+ std::stringstream sstr;
+ };
+
+ //! config must outlive the function
+ Catch::ReporterConfig makeDummyRepConfig( Catch::Config const& config ) {
+ return Catch::ReporterConfig{
+ &config,
+ Catch::Detail::make_unique<StringIStream>(),
+ Catch::ColourMode::None,
+ {} };
+ }
+}
+
+TEST_CASE( "The default listing implementation write to provided stream",
+ "[reporters][reporter-helpers]" ) {
+ using Catch::Matchers::ContainsSubstring;
+ using namespace std::string_literals;
+
+ StringIStream sstream;
+ SECTION( "Listing tags" ) {
+ std::vector<Catch::TagInfo> tags(1);
+ tags[0].add("fakeTag"_catch_sr);
+ Catch::defaultListTags(sstream.stream(), tags, false);
+
+ auto listingString = sstream.str();
+ REQUIRE_THAT(listingString, ContainsSubstring("[fakeTag]"s));
+ }
+ SECTION( "Listing reporters" ) {
+ std::vector<Catch::ReporterDescription> reporters(
+ { { "fake reporter", "fake description" } } );
+ Catch::defaultListReporters(sstream.stream(), reporters, Catch::Verbosity::Normal);
+
+ auto listingString = sstream.str();
+ REQUIRE_THAT( listingString,
+ ContainsSubstring( "fake reporter"s ) &&
+ ContainsSubstring( "fake description"s ) );
+ }
+ SECTION( "Listing tests" ) {
+ Catch::TestCaseInfo fakeInfo{
+ ""s,
+ { "fake test name"_catch_sr, "[fakeTestTag]"_catch_sr },
+ { "fake-file.cpp", 123456789 } };
+ std::vector<Catch::TestCaseHandle> tests({ {&fakeInfo, nullptr} });
+ auto colour = Catch::makeColourImpl( Catch::ColourMode::None, &sstream);
+ Catch::defaultListTests(sstream.stream(), colour.get(), tests, false, Catch::Verbosity::Normal);
+
+ auto listingString = sstream.str();
+ REQUIRE_THAT( listingString,
+ ContainsSubstring( "fake test name"s ) &&
+ ContainsSubstring( "fakeTestTag"s ) );
+ }
+ SECTION( "Listing listeners" ) {
+ std::vector<Catch::ListenerDescription> 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]" ) {
+ using Catch::Matchers::ContainsSubstring;
+ 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);
+ auto sstream = Catch::Detail::make_unique<StringIStream>();
+ auto& sstreamRef = *sstream;
+
+ Catch::ConfigData cfg_data;
+ cfg_data.rngSeed = 1234;
+ Catch::Config config( cfg_data );
+ auto reporter = factory.second->create( Catch::ReporterConfig{
+ &config, CATCH_MOVE( sstream ), Catch::ColourMode::None, {} } );
+
+ DYNAMIC_SECTION( factory.first << " reporter lists tags" ) {
+ std::vector<Catch::TagInfo> tags(1);
+ tags[0].add("fakeTag"_catch_sr);
+ reporter->listTags(tags);
+
+ auto listingString = sstreamRef.str();
+ REQUIRE_THAT(listingString, ContainsSubstring("fakeTag"s));
+ }
+
+ DYNAMIC_SECTION( factory.first << " reporter lists reporters" ) {
+ std::vector<Catch::ReporterDescription> reporters(
+ { { "fake reporter", "fake description" } } );
+ reporter->listReporters(reporters);
+
+ auto listingString = sstreamRef.str();
+ REQUIRE_THAT(listingString, ContainsSubstring("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<Catch::TestCaseHandle> tests({ {&fakeInfo, nullptr} });
+ reporter->listTests(tests);
+
+ auto listingString = sstreamRef.str();
+ REQUIRE_THAT( listingString,
+ ContainsSubstring( "fake test name"s ) &&
+ ContainsSubstring( "fakeTestTag"s ) );
+ }
+ }
+}
+
+
+TEST_CASE("Reproducer for #2309 - a very long description past 80 chars (default console width) with a late colon : blablabla", "[console-reporter]") {
+ SUCCEED();
+}
+
+namespace {
+ // A listener that writes provided string into destination,
+ // to record order of testRunStarting invocation.
+ class MockListener : public Catch::EventListenerBase {
+ std::string m_witness;
+ std::vector<std::string>& m_recorder;
+ public:
+ MockListener( std::string witness,
+ std::vector<std::string>& recorder,
+ Catch::IConfig const* config ):
+ EventListenerBase( config ),
+ m_witness( CATCH_MOVE(witness) ),
+ m_recorder( recorder )
+ {}
+
+ void testRunStarting( Catch::TestRunInfo const& ) override {
+ m_recorder.push_back( m_witness );
+ }
+ };
+ // A reporter that writes provided string into destination,
+ // to record order of testRunStarting invocation.
+ class MockReporter : public Catch::StreamingReporterBase {
+ std::string m_witness;
+ std::vector<std::string>& m_recorder;
+ public:
+ MockReporter( std::string witness,
+ std::vector<std::string>& recorder,
+ Catch::ReporterConfig&& config ):
+ StreamingReporterBase( CATCH_MOVE(config) ),
+ m_witness( CATCH_MOVE(witness) ),
+ m_recorder( recorder )
+ {}
+
+ void testRunStarting( Catch::TestRunInfo const& ) override {
+ m_recorder.push_back( m_witness );
+ }
+ };
+} // namespace
+
+TEST_CASE("Multireporter calls reporters and listeners in correct order",
+ "[reporters][multi-reporter]") {
+ Catch::Config config( Catch::ConfigData{} );
+
+ // We add reporters before listeners, to check that internally they
+ // get sorted properly, and listeners are called first anyway.
+ Catch::MultiReporter multiReporter( &config );
+ std::vector<std::string> records;
+ multiReporter.addReporter( Catch::Detail::make_unique<MockReporter>(
+ "Goodbye", records, makeDummyRepConfig(config) ) );
+ multiReporter.addListener(
+ Catch::Detail::make_unique<MockListener>( "Hello", records, &config ) );
+ multiReporter.addListener(
+ Catch::Detail::make_unique<MockListener>( "world", records, &config ) );
+ multiReporter.addReporter( Catch::Detail::make_unique<MockReporter>(
+ "world", records, makeDummyRepConfig(config) ) );
+ multiReporter.testRunStarting( { "" } );
+
+ std::vector<std::string> expected( { "Hello", "world", "Goodbye", "world" } );
+ REQUIRE( records == expected );
+}
+
+namespace {
+ // A listener that sets it preferences to test that multireporter,
+ // properly sets up its own preferences
+ class PreferenceListener : public Catch::EventListenerBase {
+ public:
+ PreferenceListener( bool redirectStdout,
+ bool reportAllAssertions,
+ Catch::IConfig const* config ):
+ EventListenerBase( config ) {
+ m_preferences.shouldRedirectStdOut = redirectStdout;
+ m_preferences.shouldReportAllAssertions = reportAllAssertions;
+ }
+ };
+ // A reporter that sets it preferences to test that multireporter,
+ // properly sets up its own preferences
+ class PreferenceReporter : public Catch::StreamingReporterBase {
+ public:
+ PreferenceReporter( bool redirectStdout,
+ bool reportAllAssertions,
+ Catch::ReporterConfig&& config ):
+ StreamingReporterBase( CATCH_MOVE(config) ) {
+ m_preferences.shouldRedirectStdOut = redirectStdout;
+ m_preferences.shouldReportAllAssertions = reportAllAssertions;
+ }
+ };
+} // namespace
+
+TEST_CASE("Multireporter updates ReporterPreferences properly",
+ "[reporters][multi-reporter]") {
+
+ Catch::Config config( Catch::ConfigData{} );
+ Catch::MultiReporter multiReporter( &config );
+
+ // Post init defaults
+ REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == false );
+ REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == false );
+
+ SECTION( "Adding listeners" ) {
+ multiReporter.addListener(
+ Catch::Detail::make_unique<PreferenceListener>(
+ true, false, &config ) );
+ REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
+ REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == false );
+
+ multiReporter.addListener(
+ Catch::Detail::make_unique<PreferenceListener>(
+ false, true, &config ) );
+ REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
+ REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true);
+
+ multiReporter.addListener(
+ Catch::Detail::make_unique<PreferenceListener>(
+ false, false, &config ) );
+ REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
+ REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true );
+ }
+ SECTION( "Adding reporters" ) {
+ multiReporter.addReporter(
+ Catch::Detail::make_unique<PreferenceReporter>(
+ true, false, makeDummyRepConfig(config) ) );
+ REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
+ REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == false );
+
+ multiReporter.addReporter(
+ Catch::Detail::make_unique<PreferenceReporter>(
+ false, true, makeDummyRepConfig( config ) ) );
+ REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
+ REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true );
+
+ multiReporter.addReporter(
+ Catch::Detail::make_unique<PreferenceReporter>(
+ false, false, makeDummyRepConfig( config ) ) );
+ REQUIRE( multiReporter.getPreferences().shouldRedirectStdOut == true );
+ REQUIRE( multiReporter.getPreferences().shouldReportAllAssertions == true );
+ }
+}
+
+namespace {
+ class TestReporterFactory : public Catch::IReporterFactory {
+ Catch::IEventListenerPtr create( Catch::ReporterConfig&& ) const override {
+ CATCH_INTERNAL_ERROR(
+ "This factory should never create a reporter" );
+ }
+ std::string getDescription() const override {
+ return "Fake test factory";
+ }
+ };
+}
+
+TEST_CASE("Registering reporter with '::' in name fails",
+ "[reporters][registration]") {
+ Catch::ReporterRegistry registry;
+
+ REQUIRE_THROWS_WITH( registry.registerReporter(
+ "with::doublecolons",
+ Catch::Detail::make_unique<TestReporterFactory>() ),
+ "'::' is not allowed in reporter name: 'with::doublecolons'" );
+}
+
+TEST_CASE("Registering multiple reporters with the same name fails",
+ "[reporters][registration][approvals]") {
+ Catch::ReporterRegistry registry;
+
+ registry.registerReporter(
+ "some-reporter-name",
+ Catch::Detail::make_unique<TestReporterFactory>() );
+
+ REQUIRE_THROWS_WITH(
+ registry.registerReporter(
+ "some-reporter-name",
+ Catch::Detail::make_unique<TestReporterFactory>() ),
+ "reporter using 'some-reporter-name' as name was already registered" );
+}