File indexing completed on 2025-01-30 10:02:52
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
0009 #define CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
0010
0011 #include <catch2/interfaces/catch_interfaces_reporter_factory.hpp>
0012 #include <catch2/internal/catch_compiler_capabilities.hpp>
0013 #include <catch2/internal/catch_unique_name.hpp>
0014 #include <catch2/internal/catch_unique_ptr.hpp>
0015 #include <catch2/internal/catch_move_and_forward.hpp>
0016 #include <catch2/internal/catch_void_type.hpp>
0017
0018 #include <type_traits>
0019
0020 namespace Catch {
0021
0022 namespace Detail {
0023
0024 template <typename T, typename = void>
0025 struct has_description : std::false_type {};
0026
0027 template <typename T>
0028 struct has_description<
0029 T,
0030 void_t<decltype( T::getDescription() )>>
0031 : std::true_type {};
0032
0033
0034
0035 void registerReporterImpl( std::string const& name,
0036 IReporterFactoryPtr reporterPtr );
0037
0038 void registerListenerImpl( Detail::unique_ptr<EventListenerFactory> listenerFactory );
0039 }
0040
0041 class IEventListener;
0042 using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
0043
0044 template <typename T>
0045 class ReporterFactory : public IReporterFactory {
0046
0047 IEventListenerPtr create( ReporterConfig&& config ) const override {
0048 return Detail::make_unique<T>( CATCH_MOVE(config) );
0049 }
0050
0051 std::string getDescription() const override {
0052 return T::getDescription();
0053 }
0054 };
0055
0056
0057 template<typename T>
0058 class ReporterRegistrar {
0059 public:
0060 explicit ReporterRegistrar( std::string const& name ) {
0061 registerReporterImpl( name,
0062 Detail::make_unique<ReporterFactory<T>>() );
0063 }
0064 };
0065
0066 template<typename T>
0067 class ListenerRegistrar {
0068
0069 class TypedListenerFactory : public EventListenerFactory {
0070 StringRef m_listenerName;
0071
0072 std::string getDescriptionImpl( std::true_type ) const {
0073 return T::getDescription();
0074 }
0075
0076 std::string getDescriptionImpl( std::false_type ) const {
0077 return "(No description provided)";
0078 }
0079
0080 public:
0081 TypedListenerFactory( StringRef listenerName ):
0082 m_listenerName( listenerName ) {}
0083
0084 IEventListenerPtr create( IConfig const* config ) const override {
0085 return Detail::make_unique<T>( config );
0086 }
0087
0088 StringRef getName() const override {
0089 return m_listenerName;
0090 }
0091
0092 std::string getDescription() const override {
0093 return getDescriptionImpl( Detail::has_description<T>{} );
0094 }
0095 };
0096
0097 public:
0098 ListenerRegistrar(StringRef listenerName) {
0099 registerListenerImpl( Detail::make_unique<TypedListenerFactory>(listenerName) );
0100 }
0101 };
0102 }
0103
0104 #if !defined(CATCH_CONFIG_DISABLE)
0105
0106 # define CATCH_REGISTER_REPORTER( name, reporterType ) \
0107 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0108 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0109 namespace { \
0110 Catch::ReporterRegistrar<reporterType> INTERNAL_CATCH_UNIQUE_NAME( \
0111 catch_internal_RegistrarFor )( name ); \
0112 } \
0113 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
0114
0115 # define CATCH_REGISTER_LISTENER( listenerType ) \
0116 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \
0117 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \
0118 namespace { \
0119 Catch::ListenerRegistrar<listenerType> INTERNAL_CATCH_UNIQUE_NAME( \
0120 catch_internal_RegistrarFor )( #listenerType##_catch_sr ); \
0121 } \
0122 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
0123
0124 #else
0125
0126 #define CATCH_REGISTER_REPORTER(name, reporterType)
0127 #define CATCH_REGISTER_LISTENER(listenerType)
0128
0129 #endif
0130
0131 #endif