Streaming reporter interface is now used natively.

Legacy reporters are adapted by their factories.
This commit is contained in:
Phil Nash 2012-11-30 19:15:23 +00:00
parent 7f04b56738
commit 4e12e12c1f
6 changed files with 46 additions and 23 deletions

View File

@ -112,7 +112,7 @@ namespace Catch {
Config& m_configWrapper; Config& m_configWrapper;
const ConfigData& m_config; const ConfigData& m_config;
std::ofstream m_ofs; std::ofstream m_ofs;
Ptr<IReporter> m_reporter; Ptr<IStreamingReporter> m_reporter;
std::set<TestCase> m_testsAlreadyRun; std::set<TestCase> m_testsAlreadyRun;
}; };

View File

@ -249,7 +249,7 @@ namespace Catch
struct IReporterFactory { struct IReporterFactory {
virtual ~IReporterFactory(); virtual ~IReporterFactory();
virtual IReporter* create( ReporterConfig const& config ) const = 0; virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
virtual std::string getDescription() const = 0; virtual std::string getDescription() const = 0;
}; };
@ -257,7 +257,7 @@ namespace Catch
typedef std::map<std::string, IReporterFactory*> FactoryMap; typedef std::map<std::string, IReporterFactory*> FactoryMap;
virtual ~IReporterRegistry(); virtual ~IReporterRegistry();
virtual IReporter* create( std::string const& name, ReporterConfig const& config ) const = 0; virtual IStreamingReporter* create( std::string const& name, ReporterConfig const& config ) const = 0;
virtual const FactoryMap& getFactories() const = 0; virtual const FactoryMap& getFactories() const = 0;
}; };

View File

@ -13,12 +13,12 @@
namespace Catch { namespace Catch {
template<typename T> template<typename T>
class ReporterRegistrar { class LegacyReporterRegistrar {
class ReporterFactory : public IReporterFactory { class ReporterFactory : public IReporterFactory {
virtual IReporter* create( const ReporterConfig& config ) const { virtual IStreamingReporter* create( const ReporterConfig& config ) const {
return new T( config ); return new LegacyReporterAdapter( new T( config ), config );
} }
virtual std::string getDescription() const { virtual std::string getDescription() const {
@ -26,6 +26,27 @@ namespace Catch {
} }
}; };
public:
LegacyReporterRegistrar( const std::string& name ) {
getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
}
};
template<typename T>
class ReporterRegistrar {
class ReporterFactory : public IReporterFactory {
virtual IStreamingReporter* create( const ReporterConfig& config ) const {
return new T( config );
}
virtual std::string getDescription() const {
return T::getDescription();
}
};
public: public:
ReporterRegistrar( const std::string& name ) { ReporterRegistrar( const std::string& name ) {
@ -35,6 +56,8 @@ namespace Catch {
} }
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name );
#define INTERNAL_CATCH_REGISTER_REPORTER2( name, reporterType ) \
Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name );
#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED #endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED

View File

@ -22,7 +22,7 @@ namespace Catch {
deleteAllValues( m_factories ); deleteAllValues( m_factories );
} }
virtual IReporter* create( const std::string& name, const ReporterConfig& config ) const { virtual IStreamingReporter* create( const std::string& name, const ReporterConfig& config ) const {
FactoryMap::const_iterator it = m_factories.find( name ); FactoryMap::const_iterator it = m_factories.find( name );
if( it == m_factories.end() ) if( it == m_factories.end() )
return NULL; return NULL;

View File

@ -56,11 +56,11 @@ namespace Catch {
public: public:
explicit Runner( const Config& config, const Ptr<IReporter>& reporter ) explicit Runner( const Config& config, const Ptr<IStreamingReporter>& reporter )
: m_context( getCurrentMutableContext() ), : m_context( getCurrentMutableContext() ),
m_runningTest( NULL ), m_runningTest( NULL ),
m_config( config ), m_config( config ),
m_reporter( reporter, ReporterConfig( m_config.stream(), m_config.data() ) ), m_reporter( reporter ),
m_prevRunner( &m_context.getRunner() ), m_prevRunner( &m_context.getRunner() ),
m_prevResultCapture( &m_context.getResultCapture() ), m_prevResultCapture( &m_context.getResultCapture() ),
m_prevConfig( m_context.getConfig() ) m_prevConfig( m_context.getConfig() )
@ -68,11 +68,11 @@ namespace Catch {
m_context.setRunner( this ); m_context.setRunner( this );
m_context.setConfig( &m_config ); m_context.setConfig( &m_config );
m_context.setResultCapture( this ); m_context.setResultCapture( this );
m_reporter.testRunStarting( "" ); // !TBD - name m_reporter->testRunStarting( "" ); // !TBD - name
} }
virtual ~Runner() { virtual ~Runner() {
m_reporter.testRunEnded( new TestRunStats( "", m_totals, aborting() ) ); // !TBD - name m_reporter->testRunEnded( new TestRunStats( "", m_totals, aborting() ) ); // !TBD - name
m_context.setRunner( m_prevRunner ); m_context.setRunner( m_prevRunner );
m_context.setConfig( NULL ); m_context.setConfig( NULL );
m_context.setResultCapture( m_prevResultCapture ); m_context.setResultCapture( m_prevResultCapture );
@ -80,10 +80,10 @@ namespace Catch {
} }
void testGroupStarting( std::string const& testSpec ) { void testGroupStarting( std::string const& testSpec ) {
m_reporter.testGroupStarting( testSpec ); m_reporter->testGroupStarting( testSpec );
} }
void testGroupEnded( std::string const& testSpec, Totals const& totals ) { void testGroupEnded( std::string const& testSpec, Totals const& totals ) {
m_reporter.testGroupEnded( new TestGroupStats( testSpec, totals, aborting() ) ); m_reporter->testGroupEnded( new TestGroupStats( testSpec, totals, aborting() ) );
} }
Totals runMatching( const std::string& testSpec ) { Totals runMatching( const std::string& testSpec ) {
@ -111,7 +111,7 @@ namespace Catch {
TestCaseInfo testInfo = testCase.getTestCaseInfo(); TestCaseInfo testInfo = testCase.getTestCaseInfo();
m_reporter.testCaseStarting( testInfo ); m_reporter->testCaseStarting( testInfo );
m_runningTest = new RunningTest( testCase ); m_runningTest = new RunningTest( testCase );
@ -134,7 +134,7 @@ namespace Catch {
m_totals.testCases += deltaTotals.testCases; m_totals.testCases += deltaTotals.testCases;
m_reporter.testCaseEnded( new TestCaseStats( testInfo, m_reporter->testCaseEnded( new TestCaseStats( testInfo,
deltaTotals, deltaTotals,
redirectedCout, redirectedCout,
redirectedCerr, redirectedCerr,
@ -170,13 +170,13 @@ namespace Catch {
std::vector<ScopedInfo*>::const_iterator it = m_scopedInfos.begin(); std::vector<ScopedInfo*>::const_iterator it = m_scopedInfos.begin();
std::vector<ScopedInfo*>::const_iterator itEnd = m_scopedInfos.end(); std::vector<ScopedInfo*>::const_iterator itEnd = m_scopedInfos.end();
for(; it != itEnd; ++it ) for(; it != itEnd; ++it )
m_reporter.assertionEnded( new AssertionStats( (*it)->buildResult( m_lastAssertionInfo ), m_totals ) ); m_reporter->assertionEnded( new AssertionStats( (*it)->buildResult( m_lastAssertionInfo ), m_totals ) );
} }
{ {
std::vector<AssertionResult>::const_iterator it = m_assertionResults.begin(); std::vector<AssertionResult>::const_iterator it = m_assertionResults.begin();
std::vector<AssertionResult>::const_iterator itEnd = m_assertionResults.end(); std::vector<AssertionResult>::const_iterator itEnd = m_assertionResults.end();
for(; it != itEnd; ++it ) for(; it != itEnd; ++it )
m_reporter.assertionEnded( new AssertionStats( *it, m_totals ) ); m_reporter->assertionEnded( new AssertionStats( *it, m_totals ) );
} }
m_assertionResults.clear(); m_assertionResults.clear();
} }
@ -187,7 +187,7 @@ namespace Catch {
m_totals.assertions.info++; m_totals.assertions.info++;
} }
else else
m_reporter.assertionEnded( new AssertionStats( result, m_totals ) ); m_reporter->assertionEnded( new AssertionStats( result, m_totals ) );
// Reset AssertionInfo // Reset AssertionInfo
m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after this line}" , m_lastAssertionInfo.resultDisposition ); m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after this line}" , m_lastAssertionInfo.resultDisposition );
@ -207,7 +207,7 @@ namespace Catch {
m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
m_reporter.sectionStarting( sectionInfo ); m_reporter->sectionStarting( sectionInfo );
assertions = m_totals.assertions; assertions = m_totals.assertions;
@ -227,7 +227,7 @@ namespace Catch {
} }
m_runningTest->endSection( info.name ); m_runningTest->endSection( info.name );
m_reporter.sectionEnded( new SectionStats( info, assertions, missingAssertions ) ); m_reporter->sectionEnded( new SectionStats( info, assertions, missingAssertions ) );
} }
virtual void pushScopedInfo( ScopedInfo* scopedInfo ) { virtual void pushScopedInfo( ScopedInfo* scopedInfo ) {
@ -281,7 +281,7 @@ namespace Catch {
try { try {
m_lastAssertionInfo = AssertionInfo( "TEST_CASE", m_runningTest->getTestCase().getTestCaseInfo().lineInfo, "", ResultDisposition::Normal ); m_lastAssertionInfo = AssertionInfo( "TEST_CASE", m_runningTest->getTestCase().getTestCaseInfo().lineInfo, "", ResultDisposition::Normal );
m_runningTest->reset(); m_runningTest->reset();
if( m_reporter.getPreferences().shouldRedirectStdOut ) { if( m_reporter->getPreferences().shouldRedirectStdOut ) {
StreamRedirect coutRedir( std::cout, redirectedCout ); StreamRedirect coutRedir( std::cout, redirectedCout );
StreamRedirect cerrRedir( std::cerr, redirectedCerr ); StreamRedirect cerrRedir( std::cerr, redirectedCerr );
m_runningTest->getTestCase().invoke(); m_runningTest->getTestCase().invoke();
@ -309,7 +309,7 @@ namespace Catch {
const Config& m_config; const Config& m_config;
Totals m_totals; Totals m_totals;
LegacyReporterAdapter m_reporter; Ptr<IStreamingReporter> m_reporter;
std::vector<ScopedInfo*> m_scopedInfos; std::vector<ScopedInfo*> m_scopedInfos;
std::vector<AssertionResult> m_assertionResults; std::vector<AssertionResult> m_assertionResults;
IRunner* m_prevRunner; IRunner* m_prevRunner;

View File

@ -24,7 +24,7 @@ namespace Catch{
// Scoped because Runner doesn't report EndTesting until its destructor // Scoped because Runner doesn't report EndTesting until its destructor
{ {
Runner runner( config, m_reporter.get() ); Runner runner( config, new LegacyReporterAdapter( m_reporter.get(), ReporterConfig( config.stream(), config.data() ) ) );
totals = runner.runMatching( rawTestSpec ); totals = runner.runMatching( rawTestSpec );
} }
m_output = oss.str(); m_output = oss.str();