mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Properly handle startup reporter registration errors
This commit is contained in:
		@@ -120,7 +120,6 @@ set(INTERNAL_HEADERS
 | 
				
			|||||||
    ${SOURCES_DIR}/internal/catch_preprocessor_remove_parens.hpp
 | 
					    ${SOURCES_DIR}/internal/catch_preprocessor_remove_parens.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/internal/catch_random_number_generator.hpp
 | 
					    ${SOURCES_DIR}/internal/catch_random_number_generator.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/internal/catch_random_seed_generation.hpp
 | 
					    ${SOURCES_DIR}/internal/catch_random_seed_generation.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_registrars.hpp
 | 
					 | 
				
			||||||
    ${SOURCES_DIR}/internal/catch_reporter_registry.hpp
 | 
					    ${SOURCES_DIR}/internal/catch_reporter_registry.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/internal/catch_reporter_spec_parser.hpp
 | 
					    ${SOURCES_DIR}/internal/catch_reporter_spec_parser.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/internal/catch_result_type.hpp
 | 
					    ${SOURCES_DIR}/internal/catch_result_type.hpp
 | 
				
			||||||
@@ -237,6 +236,7 @@ set(REPORTER_HEADERS
 | 
				
			|||||||
    ${SOURCES_DIR}/reporters/catch_reporter_helpers.hpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_helpers.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_junit.hpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_junit.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_multi.hpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_multi.hpp
 | 
				
			||||||
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_registrars.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_sonarqube.hpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_sonarqube.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_streaming_base.hpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_streaming_base.hpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_tap.hpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_tap.hpp
 | 
				
			||||||
@@ -252,6 +252,7 @@ set(REPORTER_SOURCES
 | 
				
			|||||||
    ${SOURCES_DIR}/reporters/catch_reporter_cumulative_base.cpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_cumulative_base.cpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_junit.cpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_junit.cpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_multi.cpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_multi.cpp
 | 
				
			||||||
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_registrars.cpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_sonarqube.cpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_sonarqube.cpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_streaming_base.cpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_streaming_base.cpp
 | 
				
			||||||
    ${SOURCES_DIR}/reporters/catch_reporter_tap.cpp
 | 
					    ${SOURCES_DIR}/reporters/catch_reporter_tap.cpp
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								src/catch2/reporters/catch_reporter_registrars.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/catch2/reporters/catch_reporter_registrars.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					//              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 <catch2/reporters/catch_reporter_registrars.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <catch2/internal/catch_compiler_capabilities.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Catch {
 | 
				
			||||||
 | 
					    namespace Detail {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void registerReporterImpl( std::string const& name,
 | 
				
			||||||
 | 
					                                   IReporterFactoryPtr reporterPtr ) {
 | 
				
			||||||
 | 
					            CATCH_TRY {
 | 
				
			||||||
 | 
					                getMutableRegistryHub().registerReporter(
 | 
				
			||||||
 | 
					                    name, CATCH_MOVE( reporterPtr ) );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            CATCH_CATCH_ALL {
 | 
				
			||||||
 | 
					                // Do not throw when constructing global objects, instead
 | 
				
			||||||
 | 
					                // register the exception to be processed later
 | 
				
			||||||
 | 
					                getMutableRegistryHub().registerStartupException();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } // namespace Detail
 | 
				
			||||||
 | 
					} // namespace Catch
 | 
				
			||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
#include <catch2/interfaces/catch_interfaces_reporter.hpp>
 | 
					#include <catch2/interfaces/catch_interfaces_reporter.hpp>
 | 
				
			||||||
#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
 | 
					#include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
 | 
				
			||||||
#include <catch2/internal/catch_compiler_capabilities.hpp>
 | 
					#include <catch2/internal/catch_compiler_capabilities.hpp>
 | 
				
			||||||
 | 
					#include <catch2/internal/catch_unique_name.hpp>
 | 
				
			||||||
#include <catch2/internal/catch_unique_ptr.hpp>
 | 
					#include <catch2/internal/catch_unique_ptr.hpp>
 | 
				
			||||||
#include <catch2/internal/catch_move_and_forward.hpp>
 | 
					#include <catch2/internal/catch_move_and_forward.hpp>
 | 
				
			||||||
#include <catch2/internal/catch_void_type.hpp>
 | 
					#include <catch2/internal/catch_void_type.hpp>
 | 
				
			||||||
@@ -21,6 +22,7 @@
 | 
				
			|||||||
namespace Catch {
 | 
					namespace Catch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    namespace Detail {
 | 
					    namespace Detail {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        template <typename T, typename = void>
 | 
					        template <typename T, typename = void>
 | 
				
			||||||
        struct has_description : std::false_type {};
 | 
					        struct has_description : std::false_type {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,7 +31,13 @@ namespace Catch {
 | 
				
			|||||||
            T,
 | 
					            T,
 | 
				
			||||||
            void_t<decltype( T::getDescription() )>>
 | 
					            void_t<decltype( T::getDescription() )>>
 | 
				
			||||||
            : std::true_type {};
 | 
					            : std::true_type {};
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
 | 
					        //! Indirection for reporter registration, so that the error handling is
 | 
				
			||||||
 | 
					        //! independent on the reporter's concrete type
 | 
				
			||||||
 | 
					        void registerReporterImpl( std::string const& name,
 | 
				
			||||||
 | 
					                                   IReporterFactoryPtr reporterPtr );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } // namespace Detail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class IEventListener;
 | 
					    class IEventListener;
 | 
				
			||||||
    using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
 | 
					    using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
 | 
				
			||||||
@@ -51,7 +59,8 @@ namespace Catch {
 | 
				
			|||||||
    class ReporterRegistrar {
 | 
					    class ReporterRegistrar {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        explicit ReporterRegistrar( std::string const& name ) {
 | 
					        explicit ReporterRegistrar( std::string const& name ) {
 | 
				
			||||||
            getMutableRegistryHub().registerReporter( name, Detail::make_unique<ReporterFactory<T>>() );
 | 
					            registerReporterImpl( name,
 | 
				
			||||||
 | 
					                                  Detail::make_unique<ReporterFactory<T>>() );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -95,17 +104,24 @@ namespace Catch {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if !defined(CATCH_CONFIG_DISABLE)
 | 
					#if !defined(CATCH_CONFIG_DISABLE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CATCH_REGISTER_REPORTER( name, reporterType ) \
 | 
					#    define CATCH_REGISTER_REPORTER( name, reporterType )                      \
 | 
				
			||||||
    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \
 | 
					        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                              \
 | 
				
			||||||
    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \
 | 
					        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                               \
 | 
				
			||||||
    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \
 | 
					        namespace {                                                            \
 | 
				
			||||||
    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 | 
					            Catch::ReporterRegistrar<reporterType> INTERNAL_CATCH_UNIQUE_NAME( \
 | 
				
			||||||
 | 
					                catch_internal_RegistrarFor )( name );                         \
 | 
				
			||||||
 | 
					        }                                                                      \
 | 
				
			||||||
 | 
					        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#    define CATCH_REGISTER_LISTENER( listenerType )                            \
 | 
				
			||||||
 | 
					        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                              \
 | 
				
			||||||
 | 
					        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                               \
 | 
				
			||||||
 | 
					        namespace {                                                            \
 | 
				
			||||||
 | 
					            Catch::ListenerRegistrar<listenerType> INTERNAL_CATCH_UNIQUE_NAME( \
 | 
				
			||||||
 | 
					                catch_internal_RegistrarFor )( #listenerType );                \
 | 
				
			||||||
 | 
					        }                                                                      \
 | 
				
			||||||
 | 
					        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CATCH_REGISTER_LISTENER( listenerType ) \
 | 
					 | 
				
			||||||
    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \
 | 
					 | 
				
			||||||
    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \
 | 
					 | 
				
			||||||
    namespace { Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType(#listenerType); } \
 | 
					 | 
				
			||||||
    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
 | 
					 | 
				
			||||||
#else // CATCH_CONFIG_DISABLE
 | 
					#else // CATCH_CONFIG_DISABLE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CATCH_REGISTER_REPORTER(name, reporterType)
 | 
					#define CATCH_REGISTER_REPORTER(name, reporterType)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -421,6 +421,20 @@ set_tests_properties(
 | 
				
			|||||||
    FAIL_REGULAR_EXPRESSION "error: .* already defined\\."
 | 
					    FAIL_REGULAR_EXPRESSION "error: .* already defined\\."
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable(DuplicatedReporters ${TESTS_DIR}/X35-DuplicatedReporterNames.cpp)
 | 
				
			||||||
 | 
					target_link_libraries(DuplicatedReporters PRIVATE Catch2::Catch2WithMain)
 | 
				
			||||||
 | 
					add_test(
 | 
				
			||||||
 | 
					  NAME Reporters::RegistrationErrorsAreCaught
 | 
				
			||||||
 | 
					  COMMAND $<TARGET_FILE:DuplicatedReporters>
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					set_tests_properties(
 | 
				
			||||||
 | 
					    Reporters::RegistrationErrorsAreCaught
 | 
				
			||||||
 | 
					  PROPERTIES
 | 
				
			||||||
 | 
					    PASS_REGULAR_EXPRESSION "Errors occurred during startup!"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#add_executable(DebugBreakMacros ${TESTS_DIR}/X12-CustomDebugBreakMacro.cpp)
 | 
					#add_executable(DebugBreakMacros ${TESTS_DIR}/X12-CustomDebugBreakMacro.cpp)
 | 
				
			||||||
#target_link_libraries(DebugBreakMacros Catch2)
 | 
					#target_link_libraries(DebugBreakMacros Catch2)
 | 
				
			||||||
#add_test(NAME DebugBreakMacros COMMAND DebugBreakMacros --break)
 | 
					#add_test(NAME DebugBreakMacros COMMAND DebugBreakMacros --break)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								tests/ExtraTests/X35-DuplicatedReporterNames.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tests/ExtraTests/X35-DuplicatedReporterNames.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					//              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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**\file
 | 
				
			||||||
 | 
					 * Checks that reporter registration errors are caught and handled as
 | 
				
			||||||
 | 
					 * startup errors, by causing a registration error by registering multiple
 | 
				
			||||||
 | 
					 * reporters with the same name.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <catch2/catch_test_macros.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <catch2/reporters/catch_reporter_registrars.hpp>
 | 
				
			||||||
 | 
					#include <catch2/reporters/catch_reporter_streaming_base.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					    //! Trivial custom reporter for registration
 | 
				
			||||||
 | 
					    class TestReporter : public Catch::StreamingReporterBase {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        using StreamingReporterBase::StreamingReporterBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static std::string getDescription() { return "X35 test reporter"; }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CATCH_REGISTER_REPORTER( "test-reporter", TestReporter )
 | 
				
			||||||
 | 
					CATCH_REGISTER_REPORTER( "test-reporter", TestReporter )
 | 
				
			||||||
		Reference in New Issue
	
	Block a user