mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-30 19:57:10 +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_random_number_generator.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_spec_parser.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_junit.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_streaming_base.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_junit.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_streaming_base.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_factory.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_move_and_forward.hpp> | ||||
| #include <catch2/internal/catch_void_type.hpp> | ||||
| @@ -21,6 +22,7 @@ | ||||
| namespace Catch { | ||||
|  | ||||
|     namespace Detail { | ||||
|  | ||||
|         template <typename T, typename = void> | ||||
|         struct has_description : std::false_type {}; | ||||
|  | ||||
| @@ -29,7 +31,13 @@ namespace Catch { | ||||
|             T, | ||||
|             void_t<decltype( T::getDescription() )>> | ||||
|             : 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; | ||||
|     using IEventListenerPtr = Detail::unique_ptr<IEventListener>; | ||||
| @@ -51,7 +59,8 @@ namespace Catch { | ||||
|     class ReporterRegistrar { | ||||
|     public: | ||||
|         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) | ||||
|  | ||||
| #define CATCH_REGISTER_REPORTER( name, reporterType ) \ | ||||
|     CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \ | ||||
|     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \ | ||||
|     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \ | ||||
|     CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION | ||||
| #    define CATCH_REGISTER_REPORTER( name, reporterType )                      \ | ||||
|         CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                              \ | ||||
|         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                               \ | ||||
|         namespace {                                                            \ | ||||
|             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 | ||||
|  | ||||
| #define CATCH_REGISTER_REPORTER(name, reporterType) | ||||
|   | ||||
| @@ -421,6 +421,20 @@ set_tests_properties( | ||||
|     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) | ||||
| #target_link_libraries(DebugBreakMacros Catch2) | ||||
| #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
	 Martin Hořeňovský
					Martin Hořeňovský