blob: a93963f061a1b1806f17ec45f74ce8c825634d54 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
// 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
#ifndef CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
#define CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
#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>
#include <type_traits>
namespace Catch {
namespace Detail {
template <typename T, typename = void>
struct has_description : std::false_type {};
template <typename T>
struct has_description<
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 );
//! Actually registers the factory, independent on listener's concrete type
void registerListenerImpl( Detail::unique_ptr<EventListenerFactory> listenerFactory );
} // namespace Detail
class IEventListener;
using IEventListenerPtr = Detail::unique_ptr<IEventListener>;
template <typename T>
class ReporterFactory : public IReporterFactory {
IEventListenerPtr create( ReporterConfig&& config ) const override {
return Detail::make_unique<T>( CATCH_MOVE(config) );
}
std::string getDescription() const override {
return T::getDescription();
}
};
template<typename T>
class ReporterRegistrar {
public:
explicit ReporterRegistrar( std::string const& name ) {
registerReporterImpl( name,
Detail::make_unique<ReporterFactory<T>>() );
}
};
template<typename T>
class ListenerRegistrar {
class TypedListenerFactory : public EventListenerFactory {
StringRef m_listenerName;
std::string getDescriptionImpl( std::true_type ) const {
return T::getDescription();
}
std::string getDescriptionImpl( std::false_type ) const {
return "(No description provided)";
}
public:
TypedListenerFactory( StringRef listenerName ):
m_listenerName( listenerName ) {}
IEventListenerPtr create( IConfig const* config ) const override {
return Detail::make_unique<T>( config );
}
StringRef getName() const override {
return m_listenerName;
}
std::string getDescription() const override {
return getDescriptionImpl( Detail::has_description<T>{} );
}
};
public:
ListenerRegistrar(StringRef listenerName) {
registerListenerImpl( Detail::make_unique<TypedListenerFactory>(listenerName) );
}
};
}
#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> 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_sr ); \
} \
CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION
#else // CATCH_CONFIG_DISABLE
#define CATCH_REGISTER_REPORTER(name, reporterType)
#define CATCH_REGISTER_LISTENER(listenerType)
#endif // CATCH_CONFIG_DISABLE
#endif // CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
|