diff --git a/catch.hpp b/catch.hpp index debc6589..accc8a64 100644 --- a/catch.hpp +++ b/catch.hpp @@ -26,6 +26,7 @@ #ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED #define TWOBLUECUBES_CATCH_HPP_INCLUDED +#include "internal/catch_hub.hpp" #include "internal/catch_registry.hpp" #include "internal/catch_capture.hpp" #include "internal/catch_section.hpp" diff --git a/catch_reporter_basic.hpp b/catch_reporter_basic.hpp index 37e5a1d8..2f9ecdab 100644 --- a/catch_reporter_basic.hpp +++ b/catch_reporter_basic.hpp @@ -17,11 +17,11 @@ namespace Catch { - class BasicReporter : public ITestReporter + class BasicReporter : public IReporter { public: /////////////////////////////////////////////////////////////////////////// - BasicReporter( const ReporterConfig& config ) + BasicReporter( const IReporterConfig& config ) : m_config( config ) { } @@ -47,7 +47,7 @@ namespace Catch m_config.stream() << succeeded << " test(s) passed but " << failed << " test(s) failed"; } - private: // ITestReporter + private: // IReporter /////////////////////////////////////////////////////////////////////////// virtual void StartTesting() @@ -166,7 +166,7 @@ namespace Catch } private: - const ReporterConfig& m_config; + const IReporterConfig& m_config; bool m_firstSectionInTestCase; }; diff --git a/catch_reporter_junit.hpp b/catch_reporter_junit.hpp index e71a47d2..da8d9640 100644 --- a/catch_reporter_junit.hpp +++ b/catch_reporter_junit.hpp @@ -18,7 +18,7 @@ namespace Catch { - class JunitReporter : public Catch::ITestReporter + class JunitReporter : public Catch::IReporter { struct TestStats { @@ -66,7 +66,7 @@ namespace Catch public: /////////////////////////////////////////////////////////////////////////// - JunitReporter( const ReporterConfig& config = ReporterConfig() ) + JunitReporter( const IReporterConfig& config ) : m_config( config ), m_testSuiteStats( "AllTests" ), m_currentStats( &m_testSuiteStats ) @@ -79,7 +79,7 @@ namespace Catch return "Reports test results in an XML format that looks like Ant's junitreport target"; } - private: // ITestReporter + private: // IReporter /////////////////////////////////////////////////////////////////////////// virtual void StartTesting() @@ -245,7 +245,7 @@ namespace Catch } private: - const ReporterConfig& m_config; + const IReporterConfig& m_config; bool m_currentTestSuccess; Stats m_testSuiteStats; diff --git a/catch_reporter_xml.hpp b/catch_reporter_xml.hpp index 848eb93e..6ab0531c 100644 --- a/catch_reporter_xml.hpp +++ b/catch_reporter_xml.hpp @@ -18,11 +18,11 @@ namespace Catch { - class XmlReporter : public Catch::ITestReporter + class XmlReporter : public Catch::IReporter { public: /////////////////////////////////////////////////////////////////////////// - XmlReporter( const ReporterConfig& config = ReporterConfig() ) + XmlReporter( const IReporterConfig& config ) : m_config( config ) { } @@ -33,7 +33,7 @@ namespace Catch return "Reports test results as an XML document"; } - private: // ITestReporter + private: // IReporter /////////////////////////////////////////////////////////////////////////// virtual void StartTesting() @@ -145,7 +145,7 @@ namespace Catch } private: - const ReporterConfig& m_config; + const IReporterConfig& m_config; bool m_currentTestSuccess; XmlWriter m_xml; }; diff --git a/catch_runner.hpp b/catch_runner.hpp index ea0dbfa0..79905098 100644 --- a/catch_runner.hpp +++ b/catch_runner.hpp @@ -19,6 +19,8 @@ #include "catch_reporter_xml.hpp" #include "catch_reporter_junit.hpp" +#include + namespace Catch { inline int Main( int argc, char * const argv[] ) diff --git a/internal/catch_capture.hpp b/internal/catch_capture.hpp index 4b15cfec..aba1db93 100644 --- a/internal/catch_capture.hpp +++ b/internal/catch_capture.hpp @@ -218,8 +218,7 @@ struct IResultListener virtual void acceptExpression( const MutableResultInfo& resultInfo ) = 0; virtual void acceptMessage( const std::string& msg ) = 0; -}; - +}; class ResultsCapture { @@ -249,7 +248,6 @@ public: } private: - MutableResultInfo currentResult; IResultListener* m_listener; }; diff --git a/internal/catch_hub.hpp b/internal/catch_hub.hpp new file mode 100644 index 00000000..dc708f24 --- /dev/null +++ b/internal/catch_hub.hpp @@ -0,0 +1,49 @@ +/* + * catch_hub.hpp + * Test + * + * Created by Phil on 31/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ +#ifndef TWOBLUECUBES_CATCH_HUB_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_HUB_HPP_INCLUDED + +#include + +namespace Catch +{ + struct IResultListener; + struct IReporterRegistry; + struct ITestCaseRegistry; + + class Hub + { + public: + Hub(); + + static IResultListener* getListener(); + static IReporterRegistry* getReporterRegistry(); + static ITestCaseRegistry* getTestCaseRegistry(); + + private: + std::auto_ptr m_reporterRegistry; + }; +} + + ////// -- new file -- + +#include "catch_reporter_registry.hpp" + +namespace Catch +{ + inline Hub::Hub() + : m_reporterRegistry( new ReporterRegistry ) + { + } +} + +#endif // TWOBLUECUBES_CATCH_HUB_HPP_INCLUDED \ No newline at end of file diff --git a/internal/catch_ireporterregistry.h b/internal/catch_ireporterregistry.h new file mode 100644 index 00000000..eade407a --- /dev/null +++ b/internal/catch_ireporterregistry.h @@ -0,0 +1,129 @@ +/* + * catch_ireporterregistry.h + * Test + * + * Created by Phil on 31/12/2010. + * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#ifndef TWOBLUECUBES_CATCH_IREPORTERREGISTRY_INCLUDED +#define TWOBLUECUBES_CATCH_IREPORTERREGISTRY_INCLUDED + +#include "catch_common.h" + +#include +#include + +namespace Catch +{ + /////////////////////////////////////////////////////////////////////////// + struct IReporterConfig + { + virtual std::ostream& stream + () const = 0; + + virtual bool includeSuccessfulResults + () const = 0; + }; + + class TestCaseInfo; + class ResultInfo; + + /////////////////////////////////////////////////////////////////////////// + struct IReporter : NonCopyable + { + virtual ~IReporter + (){} + + virtual void StartTesting + () = 0; + + virtual void EndTesting + ( std::size_t succeeded, + std::size_t failed + ) = 0; + + virtual void StartGroup + ( const std::string& groupName + ) = 0; + + virtual void EndGroup + ( const std::string& groupName, + std::size_t succeeded, + std::size_t failed + ) = 0; + + virtual void StartSection + ( const std::string& sectionName, + const std::string description + ) = 0; + + virtual void EndSection + ( const std::string& sectionName, + std::size_t succeeded, + std::size_t failed + ) = 0; + + virtual void StartTestCase + ( const TestCaseInfo& testInfo + ) = 0; + + virtual void EndTestCase + ( const TestCaseInfo& testInfo, + const std::string& stdOut, + const std::string& stdErr + ) = 0; + + virtual void Result + ( const ResultInfo& result + ) = 0; + }; + + /////////////////////////////////////////////////////////////////////////// + struct IReporterFactory + { + virtual ~IReporterFactory + (){} + + virtual IReporter* create + ( const IReporterConfig& config + ) const = 0; + + virtual std::string getDescription + () const = 0; + }; + + /////////////////////////////////////////////////////////////////////////// + struct IReporterRegistry + { + virtual ~IReporterRegistry + (){} + + virtual IReporter* create + ( const std::string& name, + const IReporterConfig& config + ) const = 0; + + virtual void registerReporter + ( const std::string& name, + IReporterFactory* factory + ) = 0; + }; + + /////////////////////////////////////////////////////////////////////////// + inline std::string trim( const std::string& str ) + { + std::string::size_type start = str.find_first_not_of( "\n\r\t " ); + std::string::size_type end = str.find_last_not_of( "\n\r\t " ); + + return start < end ? str.substr( start, 1+end-start ) : ""; + } + + +} + +#endif // TWOBLUECUBES_CATCH_IREPORTERREGISTRY_INCLUDED diff --git a/internal/catch_reporter_registry.hpp b/internal/catch_reporter_registry.hpp index 455108fb..07e1cc77 100644 --- a/internal/catch_reporter_registry.hpp +++ b/internal/catch_reporter_registry.hpp @@ -12,120 +12,14 @@ #ifndef TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED -#include "catch_testcaseinfo.hpp" -#include "catch_resultinfo.hpp" -#include "catch_common.h" +#include "catch_ireporterregistry.h" #include -#include -#include namespace Catch { - /////////////////////////////////////////////////////////////////////////// - static std::string trim( const std::string& str ) - { - std::string::size_type start = str.find_first_not_of( "\n\r\t " ); - std::string::size_type end = str.find_last_not_of( "\n\r\t " ); - - return start < end ? str.substr( start, 1+end-start ) : ""; - } - - - class ReporterConfig - { - private: - ReporterConfig( const ReporterConfig& other ); - ReporterConfig& operator = ( const ReporterConfig& other ); - - public: - - struct Include { enum What - { - FailedOnly, - SuccessfulResults - }; }; - - public: - - /////////////////////////////////////////////////////////////////////////// - explicit ReporterConfig( Include::What includeWhat = Include::FailedOnly ) - : m_includeWhat( includeWhat ), - m_os( std::cout.rdbuf() ) - { - } - - /////////////////////////////////////////////////////////////////////////// - bool includeSuccessfulResults() const - { - return m_includeWhat == Include::SuccessfulResults; - } - - /////////////////////////////////////////////////////////////////////////// - void setIncludeWhat(Include::What includeWhat ) - { - m_includeWhat = includeWhat; - } - - /////////////////////////////////////////////////////////////////////////// - std::ostream& stream() const - { - return m_os; - } - - /////////////////////////////////////////////////////////////////////////// - void setStreamBuf( std::streambuf* buf ) - { - m_os.rdbuf( buf ); - } - - private: - Include::What m_includeWhat; - - mutable std::ostream m_os; - }; - - struct ITestReporter : NonCopyable - { - virtual ~ITestReporter(){} - - virtual void StartTesting() = 0; - virtual void EndTesting( std::size_t succeeded, std::size_t failed ) = 0; - - virtual void StartGroup( const std::string& groupName ) = 0; - virtual void EndGroup( const std::string& groupName, std::size_t succeeded, std::size_t failed ) = 0; - - virtual void StartSection( const std::string& sectionName, const std::string description ) = 0; - virtual void EndSection( const std::string& sectionName, std::size_t succeeded, std::size_t failed ) = 0; - - virtual void StartTestCase( const TestCaseInfo& testInfo ) = 0; - virtual void EndTestCase( const TestCaseInfo& testInfo, const std::string& stdOut, const std::string& stdErr ) = 0; - - virtual void Result( const ResultInfo& result ) = 0; - }; - - struct IReporterFactory - { - virtual ~IReporterFactory(){} - - virtual ITestReporter* create( const ReporterConfig& config ) = 0; - virtual std::string getDescription() const = 0; - }; - - template - class ReporterFactory : public IReporterFactory - { - virtual ITestReporter* create( const ReporterConfig& config ) - { - return new T( config ); - } - virtual std::string getDescription() const - { - return T::getDescription(); - } - }; - - class ReporterRegistry + + class ReporterRegistry : public IReporterRegistry { public: @@ -145,7 +39,7 @@ namespace Catch } } - ITestReporter* create( const std::string& name, const ReporterConfig& config ) + virtual IReporter* create( const std::string& name, const IReporterConfig& config ) const { FactoryMap::const_iterator it = m_factories.find( name ); if( it == m_factories.end() ) @@ -153,10 +47,9 @@ namespace Catch return it->second->create( config ); } - template - void registerReporter( const std::string& name ) + void registerReporter( const std::string& name, IReporterFactory* factory ) { - m_factories.insert( std::make_pair( name, new ReporterFactory() ) ); + m_factories.insert( std::make_pair( name, factory ) ); } typedef std::map FactoryMap; @@ -170,12 +63,25 @@ namespace Catch FactoryMap m_factories; }; + template + class ReporterFactory : public IReporterFactory + { + virtual IReporter* create( const IReporterConfig& config ) const + { + return new T( config ); + } + virtual std::string getDescription() const + { + return T::getDescription(); + } + }; + template struct ReporterRegistrar { ReporterRegistrar( const std::string& name ) { - ReporterRegistry::instance().registerReporter( name ); + ReporterRegistry::instance().registerReporter( name, new ReporterFactory() ); } }; } diff --git a/internal/catch_runner_impl.hpp b/internal/catch_runner_impl.hpp index 30378231..e9ec030c 100644 --- a/internal/catch_runner_impl.hpp +++ b/internal/catch_runner_impl.hpp @@ -251,7 +251,7 @@ namespace Catch const RunnerConfig& m_config; std::size_t m_successes; std::size_t m_failures; - ITestReporter* m_reporter; + IReporter* m_reporter; std::vector m_scopedInfos; std::vector m_info; }; diff --git a/internal/catch_runnerconfig.hpp b/internal/catch_runnerconfig.hpp index 4d5b174c..6e11a451 100644 --- a/internal/catch_runnerconfig.hpp +++ b/internal/catch_runnerconfig.hpp @@ -21,6 +21,59 @@ namespace Catch { + class ReporterConfig : public IReporterConfig + { + private: + ReporterConfig( const ReporterConfig& other ); + ReporterConfig& operator = ( const ReporterConfig& other ); + + public: + + struct Include { enum What + { + FailedOnly, + SuccessfulResults + }; }; + + public: + + /////////////////////////////////////////////////////////////////////////// + explicit ReporterConfig( Include::What includeWhat = Include::FailedOnly ) + : m_includeWhat( includeWhat ), + m_os( std::cout.rdbuf() ) + { + } + + /////////////////////////////////////////////////////////////////////////// + virtual bool includeSuccessfulResults() const + { + return m_includeWhat == Include::SuccessfulResults; + } + + /////////////////////////////////////////////////////////////////////////// + void setIncludeWhat(Include::What includeWhat ) + { + m_includeWhat = includeWhat; + } + + /////////////////////////////////////////////////////////////////////////// + virtual std::ostream& stream() const + { + return m_os; + } + + /////////////////////////////////////////////////////////////////////////// + void setStreamBuf( std::streambuf* buf ) + { + m_os.rdbuf( buf ); + } + + private: + Include::What m_includeWhat; + + mutable std::ostream m_os; + }; + class RunnerConfig { public: @@ -80,19 +133,19 @@ namespace Catch m_message = errorMessage + "\n\n" + "Usage: ..."; } - void setReporter( ITestReporter* reporter ) + void setReporter( IReporter* reporter ) { - m_reporter = std::auto_ptr( reporter ); + m_reporter = std::auto_ptr( reporter ); } - ITestReporter* getReporter() + IReporter* getReporter() { if( !m_reporter.get() ) setReporter( ReporterRegistry::instance().create( "basic", m_reporterConfig ) ); return m_reporter.get(); } - ITestReporter* getReporter() const + IReporter* getReporter() const { return const_cast( this )->getReporter(); } @@ -133,7 +186,7 @@ namespace Catch } - std::auto_ptr m_reporter; + std::auto_ptr m_reporter; std::string m_filename; ReporterConfig m_reporterConfig; std::string m_message;