1 /*
2  *  Created by Phil on 31/12/2010.
3  *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
10 
11 #include "catch_interfaces_registry_hub.h"
12 #include "catch_legacy_reporter_adapter.h"
13 
14 namespace Catch {
15 
16     template<typename T>
17     class LegacyReporterRegistrar {
18 
19         class ReporterFactory : public IReporterFactory {
create(ReporterConfig const & config) const20             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
21                 return new LegacyReporterAdapter( new T( config ) );
22             }
23 
getDescription() const24             virtual std::string getDescription() const {
25                 return T::getDescription();
26             }
27         };
28 
29     public:
30 
LegacyReporterRegistrar(std::string const & name)31         LegacyReporterRegistrar( std::string const& name ) {
32             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
33         }
34     };
35 
36     template<typename T>
37     class ReporterRegistrar {
38 
39         class ReporterFactory : public SharedImpl<IReporterFactory> {
40 
41             // *** Please Note ***:
42             // - If you end up here looking at a compiler error because it's trying to register
43             // your custom reporter class be aware that the native reporter interface has changed
44             // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
45             // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
46             // However please consider updating to the new interface as the old one is now
47             // deprecated and will probably be removed quite soon!
48             // Please contact me via github if you have any questions at all about this.
49             // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
50             // no idea who is actually using custom reporters at all (possibly no-one!).
51             // The new interface is designed to minimise exposure to interface changes in the future.
create(ReporterConfig const & config) const52             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
53                 return new T( config );
54             }
55 
getDescription() const56             virtual std::string getDescription() const {
57                 return T::getDescription();
58             }
59         };
60 
61     public:
62 
ReporterRegistrar(std::string const & name)63         ReporterRegistrar( std::string const& name ) {
64             getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
65         }
66     };
67 
68     template<typename T>
69     class ListenerRegistrar {
70 
71         class ListenerFactory : public SharedImpl<IReporterFactory> {
72 
create(ReporterConfig const & config) const73             virtual IStreamingReporter* create( ReporterConfig const& config ) const {
74                 return new T( config );
75             }
getDescription() const76             virtual std::string getDescription() const {
77                 return std::string();
78             }
79         };
80 
81     public:
82 
ListenerRegistrar()83         ListenerRegistrar() {
84             getMutableRegistryHub().registerListener( new ListenerFactory() );
85         }
86     };
87 }
88 
89 #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
90     namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
91 
92 #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
93     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
94 
95 // Deprecated - use the form without INTERNAL_
96 #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
97     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
98 
99 #define CATCH_REGISTER_LISTENER( listenerType ) \
100     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
101 
102 #endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
103