diff --git a/include/catch.hpp b/include/catch.hpp index f0dd7c9e..1064ddd7 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -9,6 +9,12 @@ #ifndef TWOBLUECUBES_CATCH_HPP_INCLUDED #define TWOBLUECUBES_CATCH_HPP_INCLUDED +#pragma clang diagnostic ignored "-Wno-global-constructors" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" + + #include "internal/catch_notimplemented_exception.h" #include "internal/catch_context.h" #include "internal/catch_test_registry.hpp" @@ -29,7 +35,6 @@ #endif #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER ) -#include "catch_runner.hpp" #include "internal/catch_impl.hpp" #endif @@ -127,4 +132,6 @@ using Catch::Detail::Approx; +#pragma clang diagnostic pop + #endif // TWOBLUECUBES_CATCH_HPP_INCLUDED diff --git a/include/catch_runner.hpp b/include/catch_runner.hpp index 4ae06f85..b66fec31 100644 --- a/include/catch_runner.hpp +++ b/include/catch_runner.hpp @@ -8,12 +8,14 @@ #ifndef TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED -#include "internal/catch_commandline.hpp" -#include "internal/catch_list.hpp" #include "reporters/catch_reporter_basic.hpp" #include "reporters/catch_reporter_xml.hpp" #include "reporters/catch_reporter_junit.hpp" +#include "internal/catch_commandline.hpp" +#include "internal/catch_list.hpp" +#include "internal/catch_runner_impl.hpp" + #include #include #include diff --git a/include/catch_with_main.hpp b/include/catch_with_main.hpp index 45356ec9..23855e9b 100644 --- a/include/catch_with_main.hpp +++ b/include/catch_with_main.hpp @@ -1,4 +1,4 @@ -/* + /* * Created by Phil on 01/11/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * diff --git a/include/internal/catch_commandline.hpp b/include/internal/catch_commandline.hpp index d25e33e2..d1b39a82 100644 --- a/include/internal/catch_commandline.hpp +++ b/include/internal/catch_commandline.hpp @@ -9,7 +9,6 @@ #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED #include "catch_config.hpp" -#include "catch_runner_impl.hpp" namespace Catch { @@ -42,7 +41,8 @@ namespace Catch { std::string name() const { return m_name; } std::string operator[]( std::size_t i ) const { return m_args[i]; } std::size_t argsCount() const { return m_args.size(); } - + + CATCH_ATTRIBUTE_NORETURN void raiseError( const std::string& message ) const { std::ostringstream oss; oss << "Error while parsing " << m_name << ". " << message << "."; diff --git a/include/internal/catch_common.h b/include/internal/catch_common.h index 624966d0..ee4a565b 100644 --- a/include/internal/catch_common.h +++ b/include/internal/catch_common.h @@ -16,9 +16,9 @@ #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) #ifdef __GNUC__ -#define ATTRIBUTE_NORETURN __attribute__ ((noreturn)) +#define CATCH_ATTRIBUTE_NORETURN __attribute__ ((noreturn)) #else -#define ATTRIBUTE_NORETURN +#define CATCH_ATTRIBUTE_NORETURN #endif #include @@ -32,7 +32,7 @@ namespace Catch { void operator = ( const NonCopyable& ); protected: NonCopyable() {} - virtual ~NonCopyable() {} + virtual ~NonCopyable(); }; class SafeBool { @@ -110,21 +110,16 @@ namespace Catch { return os; } - ATTRIBUTE_NORETURN - inline void throwLogicError( const std::string& message, const std::string& file, std::size_t line ) { + CATCH_ATTRIBUTE_NORETURN + inline void throwLogicError( const std::string& message, const SourceLineInfo& locationInfo ) { std::ostringstream oss; - oss << "Internal Catch error: '" << message << "' at: " << SourceLineInfo( file, line ); + oss << "Internal Catch error: '" << message << "' at: " << locationInfo; throw std::logic_error( oss.str() ); } } -#define CATCH_INTERNAL_ERROR( msg ) throwLogicError( msg, __FILE__, __LINE__ ); - -//#ifdef __FUNCTION__ -//#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FUNCTION__, __FILE__, __LINE__ ) -//#else -#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, __LINE__ ) -//#endif +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); #endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp index 7f8e2a2d..fa488095 100644 --- a/include/internal/catch_config.hpp +++ b/include/internal/catch_config.hpp @@ -64,8 +64,9 @@ namespace Catch { private: Config( const Config& other ); Config& operator = ( const Config& other ); + virtual void dummy(); public: - + Config() : m_streambuf( NULL ), m_os( std::cout.rdbuf() ) @@ -77,7 +78,7 @@ namespace Catch { m_os( std::cout.rdbuf() ) {} - ~Config() { + virtual ~Config() { m_os.rdbuf( std::cout.rdbuf() ); delete m_streambuf; } diff --git a/include/internal/catch_context.h b/include/internal/catch_context.h index 005b0bfa..c3460e3d 100644 --- a/include/internal/catch_context.h +++ b/include/internal/catch_context.h @@ -23,11 +23,14 @@ namespace Catch { struct IRunner; struct IGeneratorsForTest; - class StreamBufBase : public std::streambuf{}; + class StreamBufBase : public std::streambuf { + public: + virtual ~StreamBufBase(); + }; struct IContext { - virtual ~IContext(){} + virtual ~IContext(); virtual IResultCapture& getResultCapture() = 0; virtual IRunner& getRunner() = 0; @@ -38,6 +41,7 @@ namespace Catch { struct IMutableContext : IContext { + virtual ~IMutableContext(); virtual void setResultCapture( IResultCapture* resultCapture ) = 0; virtual void setRunner( IRunner* runner ) = 0; virtual void setConfig( const IConfig* config ) = 0; diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp index 5320d8d8..6bb11e77 100644 --- a/include/internal/catch_impl.hpp +++ b/include/internal/catch_impl.hpp @@ -8,6 +8,11 @@ // Collect all the implementation files together here // These are the equivalent of what would usually be cpp files + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" + +#include "catch_runner.hpp" #include "catch_registry_hub.hpp" #include "catch_notimplemented_exception.hpp" #include "catch_context_impl.hpp" @@ -15,3 +20,35 @@ #include "catch_generators_impl.hpp" #include "catch_resultinfo.hpp" #include "catch_resultinfo_builder.hpp" + +namespace Catch { + NonCopyable::~NonCopyable() {} + IShared::~IShared() {} + StreamBufBase::~StreamBufBase() {} + IContext::~IContext() {} + IResultCapture::~IResultCapture() {} + ITestCase::~ITestCase() {} + ITestCaseRegistry::~ITestCaseRegistry() {} + IRegistryHub::~IRegistryHub() {} + IMutableRegistryHub::~IMutableRegistryHub() {} + IExceptionTranslator::~IExceptionTranslator() {} + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} + IReporter::~IReporter() {} + IReporterFactory::~IReporterFactory() {} + IReporterRegistry::~IReporterRegistry() {} + BasicReporter::~BasicReporter() {} + IRunner::~IRunner() {} + IMutableContext::~IMutableContext() {} + IConfig::~IConfig() {} + XmlReporter::~XmlReporter() {} + JunitReporter::~JunitReporter() {} + TestRegistry::~TestRegistry() {} + FreeFunctionTestCase::~FreeFunctionTestCase() {} + IGeneratorInfo::~IGeneratorInfo() {} + IGeneratorsForTest::~IGeneratorsForTest() {} + + void Config::dummy() {} + +} + +#pragma clang diagnostic pop diff --git a/include/internal/catch_interfaces_capture.h b/include/internal/catch_interfaces_capture.h index 4cb74a06..c50d914b 100644 --- a/include/internal/catch_interfaces_capture.h +++ b/include/internal/catch_interfaces_capture.h @@ -21,7 +21,7 @@ namespace Catch { struct IResultCapture { - virtual ~IResultCapture(){} + virtual ~IResultCapture(); virtual void testEnded( const ResultInfo& result ) = 0; virtual bool sectionStarted( const std::string& name, diff --git a/include/internal/catch_interfaces_config.h b/include/internal/catch_interfaces_config.h index ec434e5d..01abe56e 100644 --- a/include/internal/catch_interfaces_config.h +++ b/include/internal/catch_interfaces_config.h @@ -12,7 +12,7 @@ namespace Catch { struct IConfig { - virtual ~IConfig(){} + virtual ~IConfig(); virtual bool allowThrows() const = 0; }; diff --git a/include/internal/catch_interfaces_exception.h b/include/internal/catch_interfaces_exception.h index 9054dfe4..76146129 100644 --- a/include/internal/catch_interfaces_exception.h +++ b/include/internal/catch_interfaces_exception.h @@ -16,12 +16,12 @@ namespace Catch { typedef std::string(*exceptionTranslateFunction)(); struct IExceptionTranslator { - virtual ~IExceptionTranslator(){} + virtual ~IExceptionTranslator(); virtual std::string translate() const = 0; }; struct IExceptionTranslatorRegistry { - virtual ~IExceptionTranslatorRegistry(){} + virtual ~IExceptionTranslatorRegistry(); virtual std::string translateActiveException() const = 0; }; diff --git a/include/internal/catch_interfaces_generators.h b/include/internal/catch_interfaces_generators.h index ef651edc..8907adb6 100644 --- a/include/internal/catch_interfaces_generators.h +++ b/include/internal/catch_interfaces_generators.h @@ -13,13 +13,13 @@ namespace Catch { struct IGeneratorInfo { - virtual ~IGeneratorInfo(){} + virtual ~IGeneratorInfo(); virtual bool moveNext() = 0; virtual std::size_t getCurrentIndex() const = 0; }; struct IGeneratorsForTest { - virtual ~IGeneratorsForTest() {} + virtual ~IGeneratorsForTest(); virtual IGeneratorInfo& getGeneratorInfo( const std::string& fileInfo, std::size_t size ) = 0; virtual bool moveNext() = 0; diff --git a/include/internal/catch_interfaces_registry_hub.h b/include/internal/catch_interfaces_registry_hub.h index e935340f..0da503bd 100644 --- a/include/internal/catch_interfaces_registry_hub.h +++ b/include/internal/catch_interfaces_registry_hub.h @@ -24,7 +24,7 @@ namespace Catch { struct IExceptionTranslator; struct IRegistryHub { - virtual ~IRegistryHub(){} + virtual ~IRegistryHub(); virtual const IReporterRegistry& getReporterRegistry() const = 0; virtual const ITestCaseRegistry& getTestCaseRegistry() const = 0; @@ -32,7 +32,7 @@ namespace Catch { }; struct IMutableRegistryHub { - virtual ~IMutableRegistryHub(){} + virtual ~IMutableRegistryHub(); virtual void registerReporter( const std::string& name, IReporterFactory* factory ) = 0; virtual void registerTest( const TestCaseInfo& testInfo ) = 0; virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h index dddba174..f6b90872 100644 --- a/include/internal/catch_interfaces_reporter.h +++ b/include/internal/catch_interfaces_reporter.h @@ -37,7 +37,7 @@ namespace Catch class ResultInfo; struct IReporter : IShared { - virtual ~IReporter() {} + virtual ~IReporter(); virtual bool shouldRedirectStdout() const = 0; virtual void StartTesting() = 0; virtual void EndTesting( const Totals& totals ) = 0; @@ -52,7 +52,7 @@ namespace Catch }; struct IReporterFactory { - virtual ~IReporterFactory() {} + virtual ~IReporterFactory(); virtual IReporter* create( const ReporterConfig& config ) const = 0; virtual std::string getDescription() const = 0; }; @@ -60,7 +60,7 @@ namespace Catch struct IReporterRegistry { typedef std::map FactoryMap; - virtual ~IReporterRegistry() {} + virtual ~IReporterRegistry(); virtual IReporter* create( const std::string& name, const ReporterConfig& config ) const = 0; virtual const FactoryMap& getFactories() const = 0; }; diff --git a/include/internal/catch_interfaces_runner.h b/include/internal/catch_interfaces_runner.h index ee7b3486..b932e65f 100644 --- a/include/internal/catch_interfaces_runner.h +++ b/include/internal/catch_interfaces_runner.h @@ -16,7 +16,7 @@ namespace Catch { class TestCaseInfo; struct IRunner { - virtual ~IRunner() {} + virtual ~IRunner(); virtual void runAll( bool runHiddenTests = false ) = 0; virtual std::size_t runMatching( const std::string& rawTestSpec ) = 0; virtual Totals getTotals() const = 0; diff --git a/include/internal/catch_interfaces_testcase.h b/include/internal/catch_interfaces_testcase.h index f4ba5621..f3ccb58d 100644 --- a/include/internal/catch_interfaces_testcase.h +++ b/include/internal/catch_interfaces_testcase.h @@ -12,7 +12,7 @@ namespace Catch { struct ITestCase { - virtual ~ITestCase(){} + virtual ~ITestCase(); virtual void invoke () const = 0; virtual ITestCase* clone() const = 0; virtual bool operator == ( const ITestCase& other ) const = 0; @@ -22,7 +22,7 @@ namespace Catch { class TestCaseInfo; struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(){} + virtual ~ITestCaseRegistry(); virtual const std::vector& getAllTests() const = 0; virtual std::vector getMatchingTestCases( const std::string& rawTestSpec ) const = 0; }; diff --git a/include/internal/catch_ptr.hpp b/include/internal/catch_ptr.hpp index 73e53ac9..3976b7e9 100644 --- a/include/internal/catch_ptr.hpp +++ b/include/internal/catch_ptr.hpp @@ -74,7 +74,7 @@ namespace Catch { }; struct IShared : NonCopyable { - virtual ~IShared(){} + virtual ~IShared(); virtual void addRef() = 0; virtual void release() = 0; }; diff --git a/include/internal/catch_reporter_registry.hpp b/include/internal/catch_reporter_registry.hpp index 485cb3bf..21a48962 100644 --- a/include/internal/catch_reporter_registry.hpp +++ b/include/internal/catch_reporter_registry.hpp @@ -18,7 +18,7 @@ namespace Catch { public: - ~ReporterRegistry() { + virtual ~ReporterRegistry() { deleteAllValues( m_factories ); } diff --git a/include/internal/catch_resultinfo.h b/include/internal/catch_resultinfo.h index 3ca6276e..fb49649d 100644 --- a/include/internal/catch_resultinfo.h +++ b/include/internal/catch_resultinfo.h @@ -22,7 +22,7 @@ namespace Catch { const SourceLineInfo& lineInfo, const char* macroName, const char* message ); - virtual ~ResultInfo(); + ~ResultInfo(); bool ok() const; ResultWas::OfType getResultType() const; diff --git a/include/internal/catch_runner_impl.hpp b/include/internal/catch_runner_impl.hpp index 6e4b0c0a..15b60743 100644 --- a/include/internal/catch_runner_impl.hpp +++ b/include/internal/catch_runner_impl.hpp @@ -70,7 +70,7 @@ namespace Catch { m_reporter->StartTesting(); } - ~Runner() { + virtual ~Runner() { m_reporter->EndTesting( m_totals ); m_context.setRunner( m_prevRunner ); m_context.setConfig( NULL ); diff --git a/include/internal/catch_test_case_registry_impl.hpp b/include/internal/catch_test_case_registry_impl.hpp index 46d2805e..5e23fed9 100644 --- a/include/internal/catch_test_case_registry_impl.hpp +++ b/include/internal/catch_test_case_registry_impl.hpp @@ -19,6 +19,7 @@ namespace Catch { class TestRegistry : public ITestCaseRegistry { public: TestRegistry() : m_unnamedCount( 0 ) {} + virtual ~TestRegistry(); virtual void registerTest( const TestCaseInfo& testInfo ) { if( testInfo.getName() == "" ) { @@ -71,6 +72,7 @@ namespace Catch { public: FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} + virtual ~FreeFunctionTestCase(); virtual void invoke() const { m_fun(); diff --git a/include/internal/catch_test_registry.hpp b/include/internal/catch_test_registry.hpp index f25dedd1..5a0ef0d9 100644 --- a/include/internal/catch_test_registry.hpp +++ b/include/internal/catch_test_registry.hpp @@ -81,7 +81,7 @@ private: /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE_NORETURN( Name, Desc ) \ - static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )() ATTRIBUTE_NORETURN; \ + static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )() CATCH_ATTRIBUTE_NORETURN; \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ ), Name, Desc, CATCH_INTERNAL_LINEINFO ); }\ static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )() diff --git a/include/reporters/catch_reporter_basic.hpp b/include/reporters/catch_reporter_basic.hpp index 87769ee3..0e1edc1e 100644 --- a/include/reporters/catch_reporter_basic.hpp +++ b/include/reporters/catch_reporter_basic.hpp @@ -35,7 +35,7 @@ namespace Catch { class BasicReporter : public SharedImpl { struct SpanInfo { - + SpanInfo() : emitted( false ) {} @@ -60,6 +60,8 @@ namespace Catch { m_firstSectionInTestCase( true ), m_aborted( false ) {} + + virtual ~BasicReporter(); static std::string getDescription() { return "Reports test results as lines of text"; @@ -222,7 +224,6 @@ namespace Catch { case ResultWas::FailureBit: case ResultWas::ExpressionFailed: case ResultWas::Exception: - default: if( !resultInfo.hasExpression() ) { if( resultInfo.ok() ) { TextColour colour( TextColour::Success ); diff --git a/include/reporters/catch_reporter_junit.hpp b/include/reporters/catch_reporter_junit.hpp index 12757620..d1633dcb 100644 --- a/include/reporters/catch_reporter_junit.hpp +++ b/include/reporters/catch_reporter_junit.hpp @@ -61,7 +61,8 @@ namespace Catch { : m_config( config ), m_testSuiteStats( "AllTests" ), m_currentStats( &m_testSuiteStats ) - {} + {} + virtual ~JunitReporter(); static std::string getDescription() { return "Reports test results in an XML format that looks like Ant's junitreport target"; @@ -131,8 +132,6 @@ namespace Catch { case ResultWas::FailureBit: case ResultWas::Exception: case ResultWas::DidntThrowException: - default: - stats.m_element = "unknown"; break; } testCaseStats.m_testStats.push_back( stats ); diff --git a/include/reporters/catch_reporter_xml.hpp b/include/reporters/catch_reporter_xml.hpp index ed627e36..9e6a345e 100644 --- a/include/reporters/catch_reporter_xml.hpp +++ b/include/reporters/catch_reporter_xml.hpp @@ -21,6 +21,7 @@ namespace Catch { static std::string getDescription() { return "Reports test results as an XML document"; } + virtual ~XmlReporter(); private: // IReporter @@ -116,7 +117,6 @@ namespace Catch { case ResultWas::ExpressionFailed: case ResultWas::Exception: case ResultWas::DidntThrowException: - default: break; } if( resultInfo.hasExpression() ) diff --git a/projects/SelfTest/ApproxTests.cpp b/projects/SelfTest/ApproxTests.cpp index f9addb4e..5101c865 100644 --- a/projects/SelfTest/ApproxTests.cpp +++ b/projects/SelfTest/ApproxTests.cpp @@ -1,13 +1,9 @@ /* - * ApproxTests.cpp - * Catch - Test - * * Created by Phil on 28/04/2011. * Copyright 2011 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) - * */ #include "catch.hpp" diff --git a/projects/SelfTest/ClassTests.cpp b/projects/SelfTest/ClassTests.cpp index 31713ea2..76c06dd7 100644 --- a/projects/SelfTest/ClassTests.cpp +++ b/projects/SelfTest/ClassTests.cpp @@ -1,13 +1,9 @@ /* - * ClassTests.cpp - * Catch - Test - * * Created by Phil on 09/11/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) - * */ #include "catch.hpp" diff --git a/projects/SelfTest/ConditionTests.cpp b/projects/SelfTest/ConditionTests.cpp index db70611b..cd874c39 100644 --- a/projects/SelfTest/ConditionTests.cpp +++ b/projects/SelfTest/ConditionTests.cpp @@ -1,14 +1,11 @@ /* - * ConditionTests.cpp - * Catch - Test - * * Created by Phil on 08/11/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) - * */ +#pragma clang diagnostic ignored "-Wpadded" #include "catch.hpp" diff --git a/projects/SelfTest/ExceptionTests.cpp b/projects/SelfTest/ExceptionTests.cpp index 8d8eb552..a6c2a60f 100644 --- a/projects/SelfTest/ExceptionTests.cpp +++ b/projects/SelfTest/ExceptionTests.cpp @@ -1,15 +1,13 @@ /* - * ExceptionTests.cpp - * Catch - Test - * * Created by Phil on 09/11/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) - * */ +#pragma clang diagnostic ignored "-Wpadded" + #include "catch.hpp" #include @@ -19,7 +17,7 @@ namespace { - ATTRIBUTE_NORETURN + CATCH_ATTRIBUTE_NORETURN int thisThrows(); int thisThrows() @@ -41,6 +39,7 @@ TEST_CASE( "./succeeding/exceptions/explicit", "When checked exceptions are thro REQUIRE_THROWS( thisThrows() ); } +CATCH_ATTRIBUTE_NORETURN TEST_CASE( "./failing/exceptions/explicit", "When checked exceptions are thrown they can be expected or unexpected" ) { CHECK_THROWS_AS( thisThrows(), std::string ); diff --git a/projects/SelfTest/GeneratorTests.cpp b/projects/SelfTest/GeneratorTests.cpp index fe843bd3..700b180b 100644 --- a/projects/SelfTest/GeneratorTests.cpp +++ b/projects/SelfTest/GeneratorTests.cpp @@ -1,13 +1,9 @@ /* - * GeneratorTests.cpp - * Catch - Test - * * Created by Phil on 28/01/2011. * Copyright 2011 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) - * */ // This define means we have to prefix all the CATCH macros with CATCH_ diff --git a/projects/SelfTest/MessageTests.cpp b/projects/SelfTest/MessageTests.cpp index d7c148f6..36a5071a 100644 --- a/projects/SelfTest/MessageTests.cpp +++ b/projects/SelfTest/MessageTests.cpp @@ -1,13 +1,9 @@ /* - * MessageTests.cpp - * Catch - Test - * * Created by Phil on 09/11/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) - * */ #include "catch.hpp" diff --git a/projects/SelfTest/MiscTests.cpp b/projects/SelfTest/MiscTests.cpp index cacc3f31..f9a9bad7 100644 --- a/projects/SelfTest/MiscTests.cpp +++ b/projects/SelfTest/MiscTests.cpp @@ -1,14 +1,11 @@ /* - * MiscTests.cpp - * Catch - Test - * * Created by Phil on 29/11/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) - * */ +#pragma clang diagnostic ignored "-Wpadded" #include "catch.hpp" #include "catch_self_test.hpp" diff --git a/projects/SelfTest/TestMain.cpp b/projects/SelfTest/TestMain.cpp index 15616ee3..324fc28c 100644 --- a/projects/SelfTest/TestMain.cpp +++ b/projects/SelfTest/TestMain.cpp @@ -5,6 +5,8 @@ * 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) */ +#pragma clang diagnostic ignored "-Wpadded" + #include "catch_self_test.hpp" TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results" ) { @@ -54,6 +56,8 @@ TEST_CASE( "meta/Misc/Sections", "looped tests" ) { CHECK( runner.getTotals().assertions.failed == 1 ); } +#pragma clang diagnostic ignored "-Wweak-vtables" + #include "../../include/internal/catch_commandline.hpp" #include "../../include/reporters/catch_reporter_basic.hpp" #include "../../include/reporters/catch_reporter_xml.hpp" diff --git a/projects/SelfTest/TrickyTests.cpp b/projects/SelfTest/TrickyTests.cpp index ee7d236e..f1b0342a 100644 --- a/projects/SelfTest/TrickyTests.cpp +++ b/projects/SelfTest/TrickyTests.cpp @@ -1,15 +1,13 @@ /* - * TrickyTests.cpp - * Catch - Test - * * Created by Phil on 09/11/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) - * */ +#pragma clang diagnostic ignored "-Wpadded" + #include "catch.hpp" namespace Catch diff --git a/projects/SelfTest/catch_self_test.cpp b/projects/SelfTest/catch_self_test.cpp index 96ffdbd4..d0065a78 100644 --- a/projects/SelfTest/catch_self_test.cpp +++ b/projects/SelfTest/catch_self_test.cpp @@ -1,15 +1,13 @@ /* - * catch_self_test.cpp - * Catch - * * Created by Phil on 14/02/2012. * Copyright 2012 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) - * */ +#pragma clang diagnostic ignored "-Wpadded" + #define CATCH_CONFIG_MAIN #include "catch_self_test.hpp" @@ -69,9 +67,6 @@ namespace Catch{ case ResultWas::Exception: m_log << "Exception"; break; - default: - m_log << "{unrecognised ResultType enum value}"; - break; } if( resultInfo.hasExpression() ) diff --git a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj index ac89c59a..437b1375 100644 --- a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj +++ b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj @@ -465,14 +465,28 @@ 4A6D0C2B149B3D3B00DB3EAA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; + WARNING_CFLAGS = ( + "-Weverything", + "-Wno-disabled-macro-expansion", + "-Wno-global-constructors", + ); }; name = Debug; }; 4A6D0C2C149B3D3B00DB3EAA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; + WARNING_CFLAGS = ( + "-Weverything", + "-Wno-disabled-macro-expansion", + "-Wno-global-constructors", + ); }; name = Release; }; diff --git a/single_include/catch.hpp b/single_include/catch.hpp index c8a405a6..e19cf6b4 100644 --- a/single_include/catch.hpp +++ b/single_include/catch.hpp @@ -1,5 +1,5 @@ /* - * Generated: 2012-08-09 07:45:58.677223 + * Generated: 2012-08-12 09:51:33.273449 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. @@ -12,6 +12,9 @@ #define TWOBLUECUBES_CATCH_HPP_INCLUDED +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" + // #included from: internal/catch_notimplemented_exception.h #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED @@ -26,9 +29,9 @@ #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) #ifdef __GNUC__ -#define ATTRIBUTE_NORETURN __attribute__ ((noreturn)) +#define CATCH_ATTRIBUTE_NORETURN __attribute__ ((noreturn)) #else -#define ATTRIBUTE_NORETURN +#define CATCH_ATTRIBUTE_NORETURN #endif #include @@ -42,7 +45,7 @@ namespace Catch { void operator = ( const NonCopyable& ); protected: NonCopyable() {} - virtual ~NonCopyable() {} + virtual ~NonCopyable(); }; class SafeBool { @@ -120,21 +123,16 @@ namespace Catch { return os; } - ATTRIBUTE_NORETURN - inline void throwLogicError( const std::string& message, const std::string& file, std::size_t line ) { + CATCH_ATTRIBUTE_NORETURN + inline void throwLogicError( const std::string& message, const SourceLineInfo& locationInfo ) { std::ostringstream oss; - oss << "Internal Catch error: '" << message << "' at: " << SourceLineInfo( file, line ); + oss << "Internal Catch error: '" << message << "' at: " << locationInfo; throw std::logic_error( oss.str() ); } } -#define CATCH_INTERNAL_ERROR( msg ) throwLogicError( msg, __FILE__, __LINE__ ); - -//#ifdef __FUNCTION__ -//#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FUNCTION__, __FILE__, __LINE__ ) -//#else -#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, __LINE__ ) -//#endif +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); #include @@ -283,7 +281,7 @@ namespace Catch { }; struct IShared : NonCopyable { - virtual ~IShared(){} + virtual ~IShared(); virtual void addRef() = 0; virtual void release() = 0; }; @@ -331,7 +329,7 @@ namespace Catch class ResultInfo; struct IReporter : IShared { - virtual ~IReporter() {} + virtual ~IReporter(); virtual bool shouldRedirectStdout() const = 0; virtual void StartTesting() = 0; virtual void EndTesting( const Totals& totals ) = 0; @@ -346,7 +344,7 @@ namespace Catch }; struct IReporterFactory { - virtual ~IReporterFactory() {} + virtual ~IReporterFactory(); virtual IReporter* create( const ReporterConfig& config ) const = 0; virtual std::string getDescription() const = 0; }; @@ -354,7 +352,7 @@ namespace Catch struct IReporterRegistry { typedef std::map FactoryMap; - virtual ~IReporterRegistry() {} + virtual ~IReporterRegistry(); virtual IReporter* create( const std::string& name, const ReporterConfig& config ) const = 0; virtual const FactoryMap& getFactories() const = 0; }; @@ -374,7 +372,7 @@ namespace Catch { struct IConfig { - virtual ~IConfig(){} + virtual ~IConfig(); virtual bool allowThrows() const = 0; }; @@ -388,13 +386,13 @@ namespace Catch { namespace Catch { struct IGeneratorInfo { - virtual ~IGeneratorInfo(){} + virtual ~IGeneratorInfo(); virtual bool moveNext() = 0; virtual std::size_t getCurrentIndex() const = 0; }; struct IGeneratorsForTest { - virtual ~IGeneratorsForTest() {} + virtual ~IGeneratorsForTest(); virtual IGeneratorInfo& getGeneratorInfo( const std::string& fileInfo, std::size_t size ) = 0; virtual bool moveNext() = 0; @@ -415,11 +413,14 @@ namespace Catch { struct IRunner; struct IGeneratorsForTest; - class StreamBufBase : public std::streambuf{}; + class StreamBufBase : public std::streambuf { + public: + virtual ~StreamBufBase(); + }; struct IContext { - virtual ~IContext(){} + virtual ~IContext(); virtual IResultCapture& getResultCapture() = 0; virtual IRunner& getRunner() = 0; @@ -430,6 +431,7 @@ namespace Catch { struct IMutableContext : IContext { + virtual ~IMutableContext(); virtual void setResultCapture( IResultCapture* resultCapture ) = 0; virtual void setRunner( IRunner* runner ) = 0; virtual void setConfig( const IConfig* config ) = 0; @@ -452,7 +454,7 @@ namespace Catch { namespace Catch { struct ITestCase { - virtual ~ITestCase(){} + virtual ~ITestCase(); virtual void invoke () const = 0; virtual ITestCase* clone() const = 0; virtual bool operator == ( const ITestCase& other ) const = 0; @@ -462,7 +464,7 @@ namespace Catch { class TestCaseInfo; struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(){} + virtual ~ITestCaseRegistry(); virtual const std::vector& getAllTests() const = 0; virtual std::vector getMatchingTestCases( const std::string& rawTestSpec ) const = 0; }; @@ -538,7 +540,7 @@ private: /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE_NORETURN( Name, Desc ) \ - static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )() ATTRIBUTE_NORETURN; \ + static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )() CATCH_ATTRIBUTE_NORETURN; \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ ), Name, Desc, CATCH_INTERNAL_LINEINFO ); }\ static void INTERNAL_CATCH_UNIQUE_NAME( TestCaseFunction_catch_internal_ )() @@ -797,7 +799,7 @@ namespace Catch { const SourceLineInfo& lineInfo, const char* macroName, const char* message ); - virtual ~ResultInfo(); + ~ResultInfo(); bool ok() const; ResultWas::OfType getResultType() const; @@ -1210,7 +1212,7 @@ namespace Catch { struct IResultCapture { - virtual ~IResultCapture(){} + virtual ~IResultCapture(); virtual void testEnded( const ResultInfo& result ) = 0; virtual bool sectionStarted( const std::string& name, @@ -1693,7 +1695,7 @@ namespace Catch { struct IExceptionTranslator; struct IRegistryHub { - virtual ~IRegistryHub(){} + virtual ~IRegistryHub(); virtual const IReporterRegistry& getReporterRegistry() const = 0; virtual const ITestCaseRegistry& getTestCaseRegistry() const = 0; @@ -1701,7 +1703,7 @@ namespace Catch { }; struct IMutableRegistryHub { - virtual ~IMutableRegistryHub(){} + virtual ~IMutableRegistryHub(); virtual void registerReporter( const std::string& name, IReporterFactory* factory ) = 0; virtual void registerTest( const TestCaseInfo& testInfo ) = 0; virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; @@ -1718,12 +1720,12 @@ namespace Catch { typedef std::string(*exceptionTranslateFunction)(); struct IExceptionTranslator { - virtual ~IExceptionTranslator(){} + virtual ~IExceptionTranslator(); virtual std::string translate() const = 0; }; struct IExceptionTranslatorRegistry { - virtual ~IExceptionTranslatorRegistry(){} + virtual ~IExceptionTranslatorRegistry(); virtual std::string translateActiveException() const = 0; }; @@ -2061,7 +2063,7 @@ namespace Catch { class TestCaseInfo; struct IRunner { - virtual ~IRunner() {} + virtual ~IRunner(); virtual void runAll( bool runHiddenTests = false ) = 0; virtual std::size_t runMatching( const std::string& rawTestSpec ) = 0; virtual Totals getTotals() const = 0; @@ -2278,845 +2280,17 @@ return @ desc; \ #endif #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER ) +// #included from: internal/catch_impl.hpp + +// Collect all the implementation files together here +// These are the equivalent of what would usually be cpp files + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" + // #included from: catch_runner.hpp #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED -// #included from: internal/catch_commandline.hpp -#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED - -// #included from: catch_config.hpp -#define TWOBLUECUBES_CATCH_RUNNERCONFIG_HPP_INCLUDED - -#include -#include -#include -#include - -namespace Catch { - - struct Include { enum WhichResults { - FailedOnly, - SuccessfulResults - }; }; - - struct List{ enum What { - None = 0, - - Reports = 1, - Tests = 2, - All = 3, - - WhatMask = 0xf, - - AsText = 0x10, - AsXml = 0x11, - - AsMask = 0xf0 - }; }; - - struct ConfigData { - ConfigData() - : listSpec( List::None ), - shouldDebugBreak( false ), - includeWhichResults( Include::FailedOnly ), - cutoff( -1 ), - allowThrows( true ) - {} - - std::string reporter; - std::string outputFilename; - List::What listSpec; - std::vector testSpecs; - bool shouldDebugBreak; - std::string stream; - Include::WhichResults includeWhichResults; - std::string name; - int cutoff; - bool allowThrows; - }; - - class Config : public IConfig { - private: - Config( const Config& other ); - Config& operator = ( const Config& other ); - public: - - Config() - : m_streambuf( NULL ), - m_os( std::cout.rdbuf() ) - {} - - Config( const ConfigData& data ) - : m_data( data ), - m_streambuf( NULL ), - m_os( std::cout.rdbuf() ) - {} - - ~Config() { - m_os.rdbuf( std::cout.rdbuf() ); - delete m_streambuf; - } - - void setFilename( const std::string& filename ) { - m_data.outputFilename = filename; - } - - bool testsSpecified() const { - return !m_data.testSpecs.empty(); - } - - const std::vector& getTestSpecs() const { - return m_data.testSpecs; - } - - List::What getListSpec( void ) const { - return m_data.listSpec; - } - - const std::string& getFilename() const { - return m_data.outputFilename ; - } - - List::What listWhat() const { - return static_cast( m_data.listSpec & List::WhatMask ); - } - - List::What listAs() const { - return static_cast( m_data.listSpec & List::AsMask ); - } - - std::string getName() const { - return m_data.name; - } - - bool shouldDebugBreak() const { - return m_data.shouldDebugBreak; - } - - virtual std::ostream& stream() const { - return m_os; - } - - void setStreamBuf( std::streambuf* buf ) { - m_os.rdbuf( buf ? buf : std::cout.rdbuf() ); - } - - void useStream( const std::string& streamName ) { - std::streambuf* newBuf = createStreamBuf( streamName ); - setStreamBuf( newBuf ); - delete m_streambuf; - m_streambuf = newBuf; - } - - virtual bool includeSuccessfulResults() const { - return m_data.includeWhichResults == Include::SuccessfulResults; - } - - int getCutoff() const { - return m_data.cutoff; - } - - virtual bool allowThrows() const { - return m_data.allowThrows; - } - - ConfigData& data() { - return m_data; - } - - private: - ConfigData m_data; - - // !TBD Move these out of here - std::streambuf* m_streambuf; - mutable std::ostream m_os; - }; - -} // end namespace Catch - -// #included from: catch_runner_impl.hpp -#define TWOBLUECUBES_INTERNAL_CATCH_RUNNER_HPP_INCLUDED - -// #included from: catch_running_test.hpp -#define TWOBLUECUBES_INTERNAL_CATCH_RUNNING_TEST_HPP_INCLUDED - -// #included from: catch_section_info.hpp -#define TWOBLUECUBES_INTERNAL_CATCH_SECTION_INFO_HPP_INCLUDED - -#include -#include - -namespace Catch { - - class SectionInfo { - public: - - enum Status { - Root, - Unknown, - Branch, - TestedBranch, - TestedLeaf - }; - - SectionInfo( SectionInfo* parent ) - : m_status( Unknown ), - m_parent( parent ) - {} - - SectionInfo() - : m_status( Root ), - m_parent( NULL ) - {} - - ~SectionInfo() { - deleteAllValues( m_subSections ); - } - - bool shouldRun() const { - return m_status < TestedBranch; - } - - bool ran() { - if( m_status < Branch ) { - m_status = TestedLeaf; - return true; - } - return false; - } - - void ranToCompletion() { - if( m_status == Branch && !hasUntestedSections() ) - m_status = TestedBranch; - } - - SectionInfo* findSubSection( const std::string& name ) { - std::map::const_iterator it = m_subSections.find( name ); - return it != m_subSections.end() - ? it->second - : NULL; - } - - SectionInfo* addSubSection( const std::string& name ) { - SectionInfo* subSection = new SectionInfo( this ); - m_subSections.insert( std::make_pair( name, subSection ) ); - m_status = Branch; - return subSection; - } - - SectionInfo* getParent() { - return m_parent; - } - - bool hasUntestedSections() const { - if( m_status == Unknown ) - return true; - - std::map::const_iterator it = m_subSections.begin(); - std::map::const_iterator itEnd = m_subSections.end(); - for(; it != itEnd; ++it ) { - if( it->second->hasUntestedSections() ) - return true; - } - return false; - } - - private: - Status m_status; - std::map m_subSections; - SectionInfo* m_parent; - }; -} - -namespace Catch { - - class RunningTest { - - enum RunStatus { - NothingRun, - EncounteredASection, - RanAtLeastOneSection, - RanToCompletionWithSections, - RanToCompletionWithNoSections - }; - - public: - explicit RunningTest( const TestCaseInfo* info = NULL ) - : m_info( info ), - m_runStatus( RanAtLeastOneSection ), - m_currentSection( &m_rootSection ), - m_changed( false ) - {} - - bool wasSectionSeen() const { - return m_runStatus == RanAtLeastOneSection || - m_runStatus == RanToCompletionWithSections; - } - - void reset() { - m_runStatus = NothingRun; - m_changed = false; - m_lastSectionToRun = NULL; - } - - void ranToCompletion() { - if( m_runStatus == RanAtLeastOneSection || - m_runStatus == EncounteredASection ) { - m_runStatus = RanToCompletionWithSections; - if( m_lastSectionToRun ) { - m_lastSectionToRun->ranToCompletion(); - m_changed = true; - } - } - else { - m_runStatus = RanToCompletionWithNoSections; - } - } - - bool addSection( const std::string& name ) { - if( m_runStatus == NothingRun ) - m_runStatus = EncounteredASection; - - SectionInfo* thisSection = m_currentSection->findSubSection( name ); - if( !thisSection ) { - thisSection = m_currentSection->addSubSection( name ); - m_changed = true; - } - - if( !wasSectionSeen() && thisSection->shouldRun() ) { - m_currentSection = thisSection; - m_lastSectionToRun = NULL; - return true; - } - return false; - } - - void endSection( const std::string& ) { - if( m_currentSection->ran() ) { - m_runStatus = RanAtLeastOneSection; - m_changed = true; - } - else if( m_runStatus == EncounteredASection ) { - m_runStatus = RanAtLeastOneSection; - m_lastSectionToRun = m_currentSection; - } - m_currentSection = m_currentSection->getParent(); - } - - const TestCaseInfo& getTestCaseInfo() const { - return *m_info; - } - - bool hasUntestedSections() const { - return m_runStatus == RanAtLeastOneSection || - ( m_rootSection.hasUntestedSections() && m_changed ); - } - - private: - const TestCaseInfo* m_info; - RunStatus m_runStatus; - SectionInfo m_rootSection; - SectionInfo* m_currentSection; - SectionInfo* m_lastSectionToRun; - bool m_changed; - }; -} - -#include -#include - -namespace Catch { - - class StreamRedirect { - - public: - StreamRedirect( std::ostream& stream, std::string& targetString ) - : m_stream( stream ), - m_prevBuf( stream.rdbuf() ), - m_targetString( targetString ) - { - stream.rdbuf( m_oss.rdbuf() ); - } - - ~StreamRedirect() { - m_targetString += m_oss.str(); - m_stream.rdbuf( m_prevBuf ); - } - - private: - std::ostream& m_stream; - std::streambuf* m_prevBuf; - std::ostringstream m_oss; - std::string& m_targetString; - }; - - /////////////////////////////////////////////////////////////////////////// - - class Runner : public IResultCapture, public IRunner { - - Runner( const Runner& ); - void operator =( const Runner& ); - - public: - - explicit Runner( Config& config, const Ptr& reporter ) - : m_context( getCurrentMutableContext() ), - m_runningTest( NULL ), - m_config( config ), - m_reporter( reporter ), - m_prevRunner( &m_context.getRunner() ), - m_prevResultCapture( &m_context.getResultCapture() ), - m_prevConfig( m_context.getConfig() ) - { - m_context.setRunner( this ); - m_context.setConfig( &m_config ); - m_context.setResultCapture( this ); - m_reporter->StartTesting(); - } - - ~Runner() { - m_reporter->EndTesting( m_totals ); - m_context.setRunner( m_prevRunner ); - m_context.setConfig( NULL ); - m_context.setResultCapture( m_prevResultCapture ); - m_context.setConfig( m_prevConfig ); - } - - virtual void runAll( bool runHiddenTests = false ) { - m_reporter->StartGroup( "" ); - const std::vector& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); - for( std::size_t i=0; i < allTests.size(); ++i ) { - if( runHiddenTests || !allTests[i].isHidden() ) { - if( aborting() ) { - m_reporter->Aborted(); - break; - } - runTest( allTests[i] ); - } - } - m_reporter->EndGroup( "", getTotals() ); - } - - virtual std::size_t runMatching( const std::string& rawTestSpec ) { - - Totals prevTotals = getTotals(); - m_reporter->StartGroup( rawTestSpec ); - - TestSpec testSpec( rawTestSpec ); - - const std::vector& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); - std::size_t testsRun = 0; - for( std::size_t i=0; i < allTests.size(); ++i ) { - if( testSpec.matches( allTests[i].getName() ) ) { - if( aborting() ) { - m_reporter->Aborted(); - break; - } - runTest( allTests[i] ); - testsRun++; - } - } - m_reporter->EndGroup( rawTestSpec, getTotals() - prevTotals ); - return testsRun; - } - - void runTest( const TestCaseInfo& testInfo ) { - Totals prevTotals = m_totals; - - std::string redirectedCout; - std::string redirectedCerr; - - m_reporter->StartTestCase( testInfo ); - - m_runningTest = new RunningTest( &testInfo ); - - do { - do { -// m_reporter->StartGroup( "test case run" ); - m_currentResult.setLineInfo( m_runningTest->getTestCaseInfo().getLineInfo() ); - runCurrentTest( redirectedCout, redirectedCerr ); -// m_reporter->EndGroup( "test case run", m_totals.delta( prevTotals ) ); - } - while( m_runningTest->hasUntestedSections() && !aborting() ); - } - while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); - - delete m_runningTest; - m_runningTest = NULL; - - Totals deltaTotals = m_totals.delta( prevTotals ); - m_totals.testCases += deltaTotals.testCases; - m_reporter->EndTestCase( testInfo, deltaTotals, redirectedCout, redirectedCerr ); - } - - virtual Totals getTotals() const { - return m_totals; - } - - const Config& config() const { - return m_config; - } - - private: // IResultCapture - - virtual ResultAction::Value acceptResult( bool result ) { - return acceptResult( result ? ResultWas::Ok : ResultWas::ExpressionFailed ); - } - - virtual ResultAction::Value acceptResult( ResultWas::OfType result ) { - m_currentResult.setResultType( result ); - return actOnCurrentResult(); - } - - virtual ResultAction::Value acceptExpression( const ResultInfoBuilder& resultInfo ) { - m_currentResult = resultInfo; - return actOnCurrentResult(); - } - - virtual void acceptMessage( const std::string& msg ) { - m_currentResult.setMessage( msg ); - } - - virtual void testEnded( const ResultInfo& result ) { - if( result.getResultType() == ResultWas::Ok ) { - m_totals.assertions.passed++; - } - else if( !result.ok() ) { - m_totals.assertions.failed++; - - std::vector::const_iterator it = m_info.begin(); - std::vector::const_iterator itEnd = m_info.end(); - for(; it != itEnd; ++it ) - m_reporter->Result( *it ); - m_info.clear(); - } - - if( result.getResultType() == ResultWas::Info ) - m_info.push_back( result ); - else - m_reporter->Result( result ); - } - - virtual bool sectionStarted ( - const std::string& name, - const std::string& description, - const SourceLineInfo& lineInfo, - Counts& assertions - ) - { - std::ostringstream oss; - oss << name << "@" << lineInfo; - - if( !m_runningTest->addSection( oss.str() ) ) - return false; - - m_currentResult.setLineInfo( lineInfo ); - m_reporter->StartSection( name, description ); - assertions = m_totals.assertions; - - return true; - } - - virtual void sectionEnded( const std::string& name, const Counts& prevAssertions ) { - m_runningTest->endSection( name ); - m_reporter->EndSection( name, m_totals.assertions - prevAssertions ); - } - - virtual void pushScopedInfo( ScopedInfo* scopedInfo ) { - m_scopedInfos.push_back( scopedInfo ); - } - - virtual void popScopedInfo( ScopedInfo* scopedInfo ) { - if( m_scopedInfos.back() == scopedInfo ) - m_scopedInfos.pop_back(); - } - - virtual bool shouldDebugBreak() const { - return m_config.shouldDebugBreak(); - } - - virtual std::string getCurrentTestName() const { - return m_runningTest - ? m_runningTest->getTestCaseInfo().getName() - : ""; - } - - virtual const ResultInfo* getLastResult() const { - return &m_lastResult; - } - - private: - - bool aborting() const { - return m_totals.assertions.failed == static_cast( m_config.getCutoff() ); - } - - ResultAction::Value actOnCurrentResult() { - testEnded( m_currentResult ); - m_lastResult = m_currentResult; - - m_currentResult = ResultInfoBuilder(); - - ResultAction::Value action = ResultAction::None; - - if( !m_lastResult.ok() ) { - action = ResultAction::Failed; - if( shouldDebugBreak() ) - action = (ResultAction::Value)( action | ResultAction::Debug ); - if( aborting() ) - action = (ResultAction::Value)( action | ResultAction::Abort ); - } - return action; - } - - void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { - try { - m_runningTest->reset(); - if( m_reporter->shouldRedirectStdout() ) { - StreamRedirect coutRedir( std::cout, redirectedCout ); - StreamRedirect cerrRedir( std::cerr, redirectedCerr ); - m_runningTest->getTestCaseInfo().invoke(); - } - else { - m_runningTest->getTestCaseInfo().invoke(); - } - m_runningTest->ranToCompletion(); - } - catch( TestFailureException& ) { - // This just means the test was aborted due to failure - } - catch(...) { - acceptMessage( getRegistryHub().getExceptionTranslatorRegistry().translateActiveException() ); - acceptResult( ResultWas::ThrewException ); - } - m_info.clear(); - } - - private: - IMutableContext& m_context; - RunningTest* m_runningTest; - ResultInfoBuilder m_currentResult; - ResultInfo m_lastResult; - - const Config& m_config; - Totals m_totals; - Ptr m_reporter; - std::vector m_scopedInfos; - std::vector m_info; - IRunner* m_prevRunner; - IResultCapture* m_prevResultCapture; - const IConfig* m_prevConfig; - }; - -} // end namespace Catch - -namespace Catch { - - class Command { - public: - Command(){} - - explicit Command( const std::string& name ) : m_name( name ) {} - - Command& operator += ( const std::string& arg ) { - m_args.push_back( arg ); - return *this; - } - Command& operator += ( const Command& other ) { - std::copy( other.m_args.begin(), other.m_args.end(), std::back_inserter( m_args ) ); - if( m_name.empty() ) - m_name = other.m_name; - return *this; - } - Command operator + ( const Command& other ) { - Command newCommand( *this ); - newCommand += other; - return newCommand; - } - - operator SafeBool::type() const { - return SafeBool::makeSafe( !m_name.empty() ); - } - - std::string name() const { return m_name; } - std::string operator[]( std::size_t i ) const { return m_args[i]; } - std::size_t argsCount() const { return m_args.size(); } - - void raiseError( const std::string& message ) const { - std::ostringstream oss; - oss << "Error while parsing " << m_name << ". " << message << "."; - if( m_args.size() > 0 ) - oss << " Arguments where:"; - for( std::size_t i = 0; i < m_args.size(); ++i ) - oss << " " << m_args[i]; - throw std::domain_error( oss.str() ); - } - - private: - - std::string m_name; - std::vector m_args; - }; - - class CommandParser { - public: - CommandParser( int argc, char const * const * argv ) : m_argc( static_cast( argc ) ), m_argv( argv ) {} - - Command find( const std::string& arg1, const std::string& arg2, const std::string& arg3 ) const { - return find( arg1 ) + find( arg2 ) + find( arg3 ); - } - - Command find( const std::string& shortArg, const std::string& longArg ) const { - return find( shortArg ) + find( longArg ); - } - Command find( const std::string& arg ) const { - for( std::size_t i = 0; i < m_argc; ++i ) - if( m_argv[i] == arg ) - return getArgs( i ); - return Command(); - } - - private: - Command getArgs( std::size_t from ) const { - Command command( m_argv[from] ); - for( std::size_t i = from+1; i < m_argc && m_argv[i][0] != '-'; ++i ) - command += m_argv[i]; - return command; - } - - std::size_t m_argc; - char const * const * m_argv; - }; - - inline void parseIntoConfig( const CommandParser& parser, ConfigData& config ) { - - if( Command cmd = parser.find( "-l", "--list" ) ) { - if( cmd.argsCount() > 2 ) - cmd.raiseError( "Expected upto 2 arguments" ); - - List::What listSpec = List::All; - if( cmd.argsCount() >= 1 ) { - if( cmd[0] == "tests" ) - config.listSpec = List::Tests; - else if( cmd[0] == "reporters" ) - config.listSpec = List::Reports; - else - cmd.raiseError( "Expected [tests] or [reporters]" ); - } - if( cmd.argsCount() >= 2 ) { - if( cmd[1] == "xml" ) - config.listSpec = static_cast( listSpec | List::AsXml ); - else if( cmd[1] == "text" ) - config.listSpec = static_cast( listSpec | List::AsText ); - else - cmd.raiseError( "Expected [xml] or [text]" ); - } - } - - if( Command cmd = parser.find( "-t", "--test" ) ) { - if( cmd.argsCount() == 0 ) - cmd.raiseError( "Expected at least one argument" ); - for( std::size_t i = 0; i < cmd.argsCount(); ++i ) - config.testSpecs.push_back( cmd[i] ); - } - - if( Command cmd = parser.find( "-r", "--reporter" ) ) { - if( cmd.argsCount() != 1 ) - cmd.raiseError( "Expected one argument" ); - config.reporter = cmd[0]; - } - - if( Command cmd = parser.find( "-o", "--out" ) ) { - if( cmd.argsCount() == 0 ) - cmd.raiseError( "Expected filename" ); - if( cmd[0][0] == '%' ) - config.stream = cmd[0].substr( 1 ); - else - config.outputFilename = cmd[0]; - } - - if( Command cmd = parser.find( "-s", "--success" ) ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); - config.includeWhichResults = Include::SuccessfulResults; - } - - if( Command cmd = parser.find( "-b", "--break" ) ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); - config.shouldDebugBreak = true; - } - - if( Command cmd = parser.find( "-n", "--name" ) ) { - if( cmd.argsCount() != 1 ) - cmd.raiseError( "Expected a name" ); - config.name = cmd[0]; - } - - if( Command cmd = parser.find( "-a", "--abort" ) ) { - if( cmd.argsCount() > 1 ) - cmd.raiseError( "Only accepts 0-1 arguments" ); - int threshold = 1; - if( cmd.argsCount() == 1 ) { - std::stringstream ss; - ss << cmd[0]; - ss >> threshold; - if( ss.fail() || threshold <= 0 ) - cmd.raiseError( "threshold must be a number greater than zero" ); - } - config.cutoff = threshold; - } - - if( Command cmd = parser.find( "-nt", "--nothrow" ) ) { - if( cmd.argsCount() != 0 ) - cmd.raiseError( "Does not accept arguments" ); - config.allowThrows = false; - } - - } - -} // end namespace Catch - -// #included from: internal/catch_list.hpp -#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED - -#include - -namespace Catch { - inline int List( Config& config ) { - - if( config.listWhat() & List::Reports ) { - std::cout << "Available reports:\n"; - IReporterRegistry::FactoryMap::const_iterator it = getRegistryHub().getReporterRegistry().getFactories().begin(); - IReporterRegistry::FactoryMap::const_iterator itEnd = getRegistryHub().getReporterRegistry().getFactories().end(); - for(; it != itEnd; ++it ) { - // !TBD: consider listAs() - std::cout << "\t" << it->first << "\n\t\t'" << it->second->getDescription() << "'\n"; - } - std::cout << std::endl; - } - - if( config.listWhat() & List::Tests ) { - std::cout << "Available tests:\n"; - std::vector::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin(); - std::vector::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end(); - for(; it != itEnd; ++it ) { - // !TBD: consider listAs() - std::cout << "\t" << it->getName() << "\n\t\t '" << it->getDescription() << "'\n"; - } - std::cout << std::endl; - } - - if( ( config.listWhat() & List::All ) == 0 ) { - std::cerr << "Unknown list type" << std::endl; - return (std::numeric_limits::max)(); - } - - return 0; - } - -} // end namespace Catch - // #included from: reporters/catch_reporter_basic.hpp #define TWOBLUECUBES_CATCH_REPORTER_BASIC_HPP_INCLUDED @@ -3232,6 +2406,8 @@ namespace Catch { m_aborted( false ) {} + virtual ~BasicReporter(); + static std::string getDescription() { return "Reports test results as lines of text"; } @@ -3393,7 +2569,6 @@ namespace Catch { case ResultWas::FailureBit: case ResultWas::ExpressionFailed: case ResultWas::Exception: - default: if( !resultInfo.hasExpression() ) { if( resultInfo.ok() ) { TextColour colour( TextColour::Success ); @@ -3714,6 +2889,7 @@ namespace Catch { static std::string getDescription() { return "Reports test results as an XML document"; } + virtual ~XmlReporter(); private: // IReporter @@ -3809,7 +2985,6 @@ namespace Catch { case ResultWas::ExpressionFailed: case ResultWas::Exception: case ResultWas::DidntThrowException: - default: break; } if( resultInfo.hasExpression() ) @@ -3885,6 +3060,7 @@ namespace Catch { m_testSuiteStats( "AllTests" ), m_currentStats( &m_testSuiteStats ) {} + virtual ~JunitReporter(); static std::string getDescription() { return "Reports test results in an XML format that looks like Ant's junitreport target"; @@ -3954,8 +3130,6 @@ namespace Catch { case ResultWas::FailureBit: case ResultWas::Exception: case ResultWas::DidntThrowException: - default: - stats.m_element = "unknown"; break; } testCaseStats.m_testStats.push_back( stats ); @@ -4046,6 +3220,844 @@ namespace Catch { } // end namespace Catch +// #included from: internal/catch_commandline.hpp +#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED + +// #included from: catch_config.hpp +#define TWOBLUECUBES_CATCH_RUNNERCONFIG_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + + struct Include { enum WhichResults { + FailedOnly, + SuccessfulResults + }; }; + + struct List{ enum What { + None = 0, + + Reports = 1, + Tests = 2, + All = 3, + + WhatMask = 0xf, + + AsText = 0x10, + AsXml = 0x11, + + AsMask = 0xf0 + }; }; + + struct ConfigData { + ConfigData() + : listSpec( List::None ), + shouldDebugBreak( false ), + includeWhichResults( Include::FailedOnly ), + cutoff( -1 ), + allowThrows( true ) + {} + + std::string reporter; + std::string outputFilename; + List::What listSpec; + std::vector testSpecs; + bool shouldDebugBreak; + std::string stream; + Include::WhichResults includeWhichResults; + std::string name; + int cutoff; + bool allowThrows; + }; + + class Config : public IConfig { + private: + Config( const Config& other ); + Config& operator = ( const Config& other ); + virtual void dummy(); + public: + + Config() + : m_streambuf( NULL ), + m_os( std::cout.rdbuf() ) + {} + + Config( const ConfigData& data ) + : m_data( data ), + m_streambuf( NULL ), + m_os( std::cout.rdbuf() ) + {} + + virtual ~Config() { + m_os.rdbuf( std::cout.rdbuf() ); + delete m_streambuf; + } + + void setFilename( const std::string& filename ) { + m_data.outputFilename = filename; + } + + bool testsSpecified() const { + return !m_data.testSpecs.empty(); + } + + const std::vector& getTestSpecs() const { + return m_data.testSpecs; + } + + List::What getListSpec( void ) const { + return m_data.listSpec; + } + + const std::string& getFilename() const { + return m_data.outputFilename ; + } + + List::What listWhat() const { + return static_cast( m_data.listSpec & List::WhatMask ); + } + + List::What listAs() const { + return static_cast( m_data.listSpec & List::AsMask ); + } + + std::string getName() const { + return m_data.name; + } + + bool shouldDebugBreak() const { + return m_data.shouldDebugBreak; + } + + virtual std::ostream& stream() const { + return m_os; + } + + void setStreamBuf( std::streambuf* buf ) { + m_os.rdbuf( buf ? buf : std::cout.rdbuf() ); + } + + void useStream( const std::string& streamName ) { + std::streambuf* newBuf = createStreamBuf( streamName ); + setStreamBuf( newBuf ); + delete m_streambuf; + m_streambuf = newBuf; + } + + virtual bool includeSuccessfulResults() const { + return m_data.includeWhichResults == Include::SuccessfulResults; + } + + int getCutoff() const { + return m_data.cutoff; + } + + virtual bool allowThrows() const { + return m_data.allowThrows; + } + + ConfigData& data() { + return m_data; + } + + private: + ConfigData m_data; + + // !TBD Move these out of here + std::streambuf* m_streambuf; + mutable std::ostream m_os; + }; + +} // end namespace Catch + +namespace Catch { + + class Command { + public: + Command(){} + + explicit Command( const std::string& name ) : m_name( name ) {} + + Command& operator += ( const std::string& arg ) { + m_args.push_back( arg ); + return *this; + } + Command& operator += ( const Command& other ) { + std::copy( other.m_args.begin(), other.m_args.end(), std::back_inserter( m_args ) ); + if( m_name.empty() ) + m_name = other.m_name; + return *this; + } + Command operator + ( const Command& other ) { + Command newCommand( *this ); + newCommand += other; + return newCommand; + } + + operator SafeBool::type() const { + return SafeBool::makeSafe( !m_name.empty() ); + } + + std::string name() const { return m_name; } + std::string operator[]( std::size_t i ) const { return m_args[i]; } + std::size_t argsCount() const { return m_args.size(); } + + CATCH_ATTRIBUTE_NORETURN + void raiseError( const std::string& message ) const { + std::ostringstream oss; + oss << "Error while parsing " << m_name << ". " << message << "."; + if( m_args.size() > 0 ) + oss << " Arguments where:"; + for( std::size_t i = 0; i < m_args.size(); ++i ) + oss << " " << m_args[i]; + throw std::domain_error( oss.str() ); + } + + private: + + std::string m_name; + std::vector m_args; + }; + + class CommandParser { + public: + CommandParser( int argc, char const * const * argv ) : m_argc( static_cast( argc ) ), m_argv( argv ) {} + + Command find( const std::string& arg1, const std::string& arg2, const std::string& arg3 ) const { + return find( arg1 ) + find( arg2 ) + find( arg3 ); + } + + Command find( const std::string& shortArg, const std::string& longArg ) const { + return find( shortArg ) + find( longArg ); + } + Command find( const std::string& arg ) const { + for( std::size_t i = 0; i < m_argc; ++i ) + if( m_argv[i] == arg ) + return getArgs( i ); + return Command(); + } + + private: + Command getArgs( std::size_t from ) const { + Command command( m_argv[from] ); + for( std::size_t i = from+1; i < m_argc && m_argv[i][0] != '-'; ++i ) + command += m_argv[i]; + return command; + } + + std::size_t m_argc; + char const * const * m_argv; + }; + + inline void parseIntoConfig( const CommandParser& parser, ConfigData& config ) { + + if( Command cmd = parser.find( "-l", "--list" ) ) { + if( cmd.argsCount() > 2 ) + cmd.raiseError( "Expected upto 2 arguments" ); + + List::What listSpec = List::All; + if( cmd.argsCount() >= 1 ) { + if( cmd[0] == "tests" ) + config.listSpec = List::Tests; + else if( cmd[0] == "reporters" ) + config.listSpec = List::Reports; + else + cmd.raiseError( "Expected [tests] or [reporters]" ); + } + if( cmd.argsCount() >= 2 ) { + if( cmd[1] == "xml" ) + config.listSpec = static_cast( listSpec | List::AsXml ); + else if( cmd[1] == "text" ) + config.listSpec = static_cast( listSpec | List::AsText ); + else + cmd.raiseError( "Expected [xml] or [text]" ); + } + } + + if( Command cmd = parser.find( "-t", "--test" ) ) { + if( cmd.argsCount() == 0 ) + cmd.raiseError( "Expected at least one argument" ); + for( std::size_t i = 0; i < cmd.argsCount(); ++i ) + config.testSpecs.push_back( cmd[i] ); + } + + if( Command cmd = parser.find( "-r", "--reporter" ) ) { + if( cmd.argsCount() != 1 ) + cmd.raiseError( "Expected one argument" ); + config.reporter = cmd[0]; + } + + if( Command cmd = parser.find( "-o", "--out" ) ) { + if( cmd.argsCount() == 0 ) + cmd.raiseError( "Expected filename" ); + if( cmd[0][0] == '%' ) + config.stream = cmd[0].substr( 1 ); + else + config.outputFilename = cmd[0]; + } + + if( Command cmd = parser.find( "-s", "--success" ) ) { + if( cmd.argsCount() != 0 ) + cmd.raiseError( "Does not accept arguments" ); + config.includeWhichResults = Include::SuccessfulResults; + } + + if( Command cmd = parser.find( "-b", "--break" ) ) { + if( cmd.argsCount() != 0 ) + cmd.raiseError( "Does not accept arguments" ); + config.shouldDebugBreak = true; + } + + if( Command cmd = parser.find( "-n", "--name" ) ) { + if( cmd.argsCount() != 1 ) + cmd.raiseError( "Expected a name" ); + config.name = cmd[0]; + } + + if( Command cmd = parser.find( "-a", "--abort" ) ) { + if( cmd.argsCount() > 1 ) + cmd.raiseError( "Only accepts 0-1 arguments" ); + int threshold = 1; + if( cmd.argsCount() == 1 ) { + std::stringstream ss; + ss << cmd[0]; + ss >> threshold; + if( ss.fail() || threshold <= 0 ) + cmd.raiseError( "threshold must be a number greater than zero" ); + } + config.cutoff = threshold; + } + + if( Command cmd = parser.find( "-nt", "--nothrow" ) ) { + if( cmd.argsCount() != 0 ) + cmd.raiseError( "Does not accept arguments" ); + config.allowThrows = false; + } + + } + +} // end namespace Catch + +// #included from: internal/catch_list.hpp +#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED + +#include + +namespace Catch { + inline int List( Config& config ) { + + if( config.listWhat() & List::Reports ) { + std::cout << "Available reports:\n"; + IReporterRegistry::FactoryMap::const_iterator it = getRegistryHub().getReporterRegistry().getFactories().begin(); + IReporterRegistry::FactoryMap::const_iterator itEnd = getRegistryHub().getReporterRegistry().getFactories().end(); + for(; it != itEnd; ++it ) { + // !TBD: consider listAs() + std::cout << "\t" << it->first << "\n\t\t'" << it->second->getDescription() << "'\n"; + } + std::cout << std::endl; + } + + if( config.listWhat() & List::Tests ) { + std::cout << "Available tests:\n"; + std::vector::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin(); + std::vector::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end(); + for(; it != itEnd; ++it ) { + // !TBD: consider listAs() + std::cout << "\t" << it->getName() << "\n\t\t '" << it->getDescription() << "'\n"; + } + std::cout << std::endl; + } + + if( ( config.listWhat() & List::All ) == 0 ) { + std::cerr << "Unknown list type" << std::endl; + return (std::numeric_limits::max)(); + } + + return 0; + } + +} // end namespace Catch + +// #included from: internal/catch_runner_impl.hpp +#define TWOBLUECUBES_INTERNAL_CATCH_RUNNER_HPP_INCLUDED + +// #included from: catch_running_test.hpp +#define TWOBLUECUBES_INTERNAL_CATCH_RUNNING_TEST_HPP_INCLUDED + +// #included from: catch_section_info.hpp +#define TWOBLUECUBES_INTERNAL_CATCH_SECTION_INFO_HPP_INCLUDED + +#include +#include + +namespace Catch { + + class SectionInfo { + public: + + enum Status { + Root, + Unknown, + Branch, + TestedBranch, + TestedLeaf + }; + + SectionInfo( SectionInfo* parent ) + : m_status( Unknown ), + m_parent( parent ) + {} + + SectionInfo() + : m_status( Root ), + m_parent( NULL ) + {} + + ~SectionInfo() { + deleteAllValues( m_subSections ); + } + + bool shouldRun() const { + return m_status < TestedBranch; + } + + bool ran() { + if( m_status < Branch ) { + m_status = TestedLeaf; + return true; + } + return false; + } + + void ranToCompletion() { + if( m_status == Branch && !hasUntestedSections() ) + m_status = TestedBranch; + } + + SectionInfo* findSubSection( const std::string& name ) { + std::map::const_iterator it = m_subSections.find( name ); + return it != m_subSections.end() + ? it->second + : NULL; + } + + SectionInfo* addSubSection( const std::string& name ) { + SectionInfo* subSection = new SectionInfo( this ); + m_subSections.insert( std::make_pair( name, subSection ) ); + m_status = Branch; + return subSection; + } + + SectionInfo* getParent() { + return m_parent; + } + + bool hasUntestedSections() const { + if( m_status == Unknown ) + return true; + + std::map::const_iterator it = m_subSections.begin(); + std::map::const_iterator itEnd = m_subSections.end(); + for(; it != itEnd; ++it ) { + if( it->second->hasUntestedSections() ) + return true; + } + return false; + } + + private: + Status m_status; + std::map m_subSections; + SectionInfo* m_parent; + }; +} + +namespace Catch { + + class RunningTest { + + enum RunStatus { + NothingRun, + EncounteredASection, + RanAtLeastOneSection, + RanToCompletionWithSections, + RanToCompletionWithNoSections + }; + + public: + explicit RunningTest( const TestCaseInfo* info = NULL ) + : m_info( info ), + m_runStatus( RanAtLeastOneSection ), + m_currentSection( &m_rootSection ), + m_changed( false ) + {} + + bool wasSectionSeen() const { + return m_runStatus == RanAtLeastOneSection || + m_runStatus == RanToCompletionWithSections; + } + + void reset() { + m_runStatus = NothingRun; + m_changed = false; + m_lastSectionToRun = NULL; + } + + void ranToCompletion() { + if( m_runStatus == RanAtLeastOneSection || + m_runStatus == EncounteredASection ) { + m_runStatus = RanToCompletionWithSections; + if( m_lastSectionToRun ) { + m_lastSectionToRun->ranToCompletion(); + m_changed = true; + } + } + else { + m_runStatus = RanToCompletionWithNoSections; + } + } + + bool addSection( const std::string& name ) { + if( m_runStatus == NothingRun ) + m_runStatus = EncounteredASection; + + SectionInfo* thisSection = m_currentSection->findSubSection( name ); + if( !thisSection ) { + thisSection = m_currentSection->addSubSection( name ); + m_changed = true; + } + + if( !wasSectionSeen() && thisSection->shouldRun() ) { + m_currentSection = thisSection; + m_lastSectionToRun = NULL; + return true; + } + return false; + } + + void endSection( const std::string& ) { + if( m_currentSection->ran() ) { + m_runStatus = RanAtLeastOneSection; + m_changed = true; + } + else if( m_runStatus == EncounteredASection ) { + m_runStatus = RanAtLeastOneSection; + m_lastSectionToRun = m_currentSection; + } + m_currentSection = m_currentSection->getParent(); + } + + const TestCaseInfo& getTestCaseInfo() const { + return *m_info; + } + + bool hasUntestedSections() const { + return m_runStatus == RanAtLeastOneSection || + ( m_rootSection.hasUntestedSections() && m_changed ); + } + + private: + const TestCaseInfo* m_info; + RunStatus m_runStatus; + SectionInfo m_rootSection; + SectionInfo* m_currentSection; + SectionInfo* m_lastSectionToRun; + bool m_changed; + }; +} + +#include +#include + +namespace Catch { + + class StreamRedirect { + + public: + StreamRedirect( std::ostream& stream, std::string& targetString ) + : m_stream( stream ), + m_prevBuf( stream.rdbuf() ), + m_targetString( targetString ) + { + stream.rdbuf( m_oss.rdbuf() ); + } + + ~StreamRedirect() { + m_targetString += m_oss.str(); + m_stream.rdbuf( m_prevBuf ); + } + + private: + std::ostream& m_stream; + std::streambuf* m_prevBuf; + std::ostringstream m_oss; + std::string& m_targetString; + }; + + /////////////////////////////////////////////////////////////////////////// + + class Runner : public IResultCapture, public IRunner { + + Runner( const Runner& ); + void operator =( const Runner& ); + + public: + + explicit Runner( Config& config, const Ptr& reporter ) + : m_context( getCurrentMutableContext() ), + m_runningTest( NULL ), + m_config( config ), + m_reporter( reporter ), + m_prevRunner( &m_context.getRunner() ), + m_prevResultCapture( &m_context.getResultCapture() ), + m_prevConfig( m_context.getConfig() ) + { + m_context.setRunner( this ); + m_context.setConfig( &m_config ); + m_context.setResultCapture( this ); + m_reporter->StartTesting(); + } + + virtual ~Runner() { + m_reporter->EndTesting( m_totals ); + m_context.setRunner( m_prevRunner ); + m_context.setConfig( NULL ); + m_context.setResultCapture( m_prevResultCapture ); + m_context.setConfig( m_prevConfig ); + } + + virtual void runAll( bool runHiddenTests = false ) { + m_reporter->StartGroup( "" ); + const std::vector& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); + for( std::size_t i=0; i < allTests.size(); ++i ) { + if( runHiddenTests || !allTests[i].isHidden() ) { + if( aborting() ) { + m_reporter->Aborted(); + break; + } + runTest( allTests[i] ); + } + } + m_reporter->EndGroup( "", getTotals() ); + } + + virtual std::size_t runMatching( const std::string& rawTestSpec ) { + + Totals prevTotals = getTotals(); + m_reporter->StartGroup( rawTestSpec ); + + TestSpec testSpec( rawTestSpec ); + + const std::vector& allTests = getRegistryHub().getTestCaseRegistry().getAllTests(); + std::size_t testsRun = 0; + for( std::size_t i=0; i < allTests.size(); ++i ) { + if( testSpec.matches( allTests[i].getName() ) ) { + if( aborting() ) { + m_reporter->Aborted(); + break; + } + runTest( allTests[i] ); + testsRun++; + } + } + m_reporter->EndGroup( rawTestSpec, getTotals() - prevTotals ); + return testsRun; + } + + void runTest( const TestCaseInfo& testInfo ) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + m_reporter->StartTestCase( testInfo ); + + m_runningTest = new RunningTest( &testInfo ); + + do { + do { +// m_reporter->StartGroup( "test case run" ); + m_currentResult.setLineInfo( m_runningTest->getTestCaseInfo().getLineInfo() ); + runCurrentTest( redirectedCout, redirectedCerr ); +// m_reporter->EndGroup( "test case run", m_totals.delta( prevTotals ) ); + } + while( m_runningTest->hasUntestedSections() && !aborting() ); + } + while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); + + delete m_runningTest; + m_runningTest = NULL; + + Totals deltaTotals = m_totals.delta( prevTotals ); + m_totals.testCases += deltaTotals.testCases; + m_reporter->EndTestCase( testInfo, deltaTotals, redirectedCout, redirectedCerr ); + } + + virtual Totals getTotals() const { + return m_totals; + } + + const Config& config() const { + return m_config; + } + + private: // IResultCapture + + virtual ResultAction::Value acceptResult( bool result ) { + return acceptResult( result ? ResultWas::Ok : ResultWas::ExpressionFailed ); + } + + virtual ResultAction::Value acceptResult( ResultWas::OfType result ) { + m_currentResult.setResultType( result ); + return actOnCurrentResult(); + } + + virtual ResultAction::Value acceptExpression( const ResultInfoBuilder& resultInfo ) { + m_currentResult = resultInfo; + return actOnCurrentResult(); + } + + virtual void acceptMessage( const std::string& msg ) { + m_currentResult.setMessage( msg ); + } + + virtual void testEnded( const ResultInfo& result ) { + if( result.getResultType() == ResultWas::Ok ) { + m_totals.assertions.passed++; + } + else if( !result.ok() ) { + m_totals.assertions.failed++; + + std::vector::const_iterator it = m_info.begin(); + std::vector::const_iterator itEnd = m_info.end(); + for(; it != itEnd; ++it ) + m_reporter->Result( *it ); + m_info.clear(); + } + + if( result.getResultType() == ResultWas::Info ) + m_info.push_back( result ); + else + m_reporter->Result( result ); + } + + virtual bool sectionStarted ( + const std::string& name, + const std::string& description, + const SourceLineInfo& lineInfo, + Counts& assertions + ) + { + std::ostringstream oss; + oss << name << "@" << lineInfo; + + if( !m_runningTest->addSection( oss.str() ) ) + return false; + + m_currentResult.setLineInfo( lineInfo ); + m_reporter->StartSection( name, description ); + assertions = m_totals.assertions; + + return true; + } + + virtual void sectionEnded( const std::string& name, const Counts& prevAssertions ) { + m_runningTest->endSection( name ); + m_reporter->EndSection( name, m_totals.assertions - prevAssertions ); + } + + virtual void pushScopedInfo( ScopedInfo* scopedInfo ) { + m_scopedInfos.push_back( scopedInfo ); + } + + virtual void popScopedInfo( ScopedInfo* scopedInfo ) { + if( m_scopedInfos.back() == scopedInfo ) + m_scopedInfos.pop_back(); + } + + virtual bool shouldDebugBreak() const { + return m_config.shouldDebugBreak(); + } + + virtual std::string getCurrentTestName() const { + return m_runningTest + ? m_runningTest->getTestCaseInfo().getName() + : ""; + } + + virtual const ResultInfo* getLastResult() const { + return &m_lastResult; + } + + private: + + bool aborting() const { + return m_totals.assertions.failed == static_cast( m_config.getCutoff() ); + } + + ResultAction::Value actOnCurrentResult() { + testEnded( m_currentResult ); + m_lastResult = m_currentResult; + + m_currentResult = ResultInfoBuilder(); + + ResultAction::Value action = ResultAction::None; + + if( !m_lastResult.ok() ) { + action = ResultAction::Failed; + if( shouldDebugBreak() ) + action = (ResultAction::Value)( action | ResultAction::Debug ); + if( aborting() ) + action = (ResultAction::Value)( action | ResultAction::Abort ); + } + return action; + } + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { + try { + m_runningTest->reset(); + if( m_reporter->shouldRedirectStdout() ) { + StreamRedirect coutRedir( std::cout, redirectedCout ); + StreamRedirect cerrRedir( std::cerr, redirectedCerr ); + m_runningTest->getTestCaseInfo().invoke(); + } + else { + m_runningTest->getTestCaseInfo().invoke(); + } + m_runningTest->ranToCompletion(); + } + catch( TestFailureException& ) { + // This just means the test was aborted due to failure + } + catch(...) { + acceptMessage( getRegistryHub().getExceptionTranslatorRegistry().translateActiveException() ); + acceptResult( ResultWas::ThrewException ); + } + m_info.clear(); + } + + private: + IMutableContext& m_context; + RunningTest* m_runningTest; + ResultInfoBuilder m_currentResult; + ResultInfo m_lastResult; + + const Config& m_config; + Totals m_totals; + Ptr m_reporter; + std::vector m_scopedInfos; + std::vector m_info; + IRunner* m_prevRunner; + IResultCapture* m_prevResultCapture; + const IConfig* m_prevConfig; + }; + +} // end namespace Catch + #include #include #include @@ -4180,10 +4192,6 @@ namespace Catch { } // end namespace Catch -// #included from: internal/catch_impl.hpp - -// Collect all the implementation files together here -// These are the equivalent of what would usually be cpp files // #included from: catch_registry_hub.hpp // #included from: catch_test_case_registry_impl.hpp @@ -4198,6 +4206,7 @@ namespace Catch { class TestRegistry : public ITestCaseRegistry { public: TestRegistry() : m_unnamedCount( 0 ) {} + virtual ~TestRegistry(); virtual void registerTest( const TestCaseInfo& testInfo ) { if( testInfo.getName() == "" ) { @@ -4250,6 +4259,7 @@ namespace Catch { public: FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} + virtual ~FreeFunctionTestCase(); virtual void invoke() const { m_fun(); @@ -4304,7 +4314,7 @@ namespace Catch { public: - ~ReporterRegistry() { + virtual ~ReporterRegistry() { deleteAllValues( m_factories ); } @@ -4946,6 +4956,37 @@ namespace Catch { } // end namespace Catch +namespace Catch { + NonCopyable::~NonCopyable() {} + IShared::~IShared() {} + StreamBufBase::~StreamBufBase() {} + IContext::~IContext() {} + IResultCapture::~IResultCapture() {} + ITestCase::~ITestCase() {} + ITestCaseRegistry::~ITestCaseRegistry() {} + IRegistryHub::~IRegistryHub() {} + IMutableRegistryHub::~IMutableRegistryHub() {} + IExceptionTranslator::~IExceptionTranslator() {} + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} + IReporter::~IReporter() {} + IReporterFactory::~IReporterFactory() {} + IReporterRegistry::~IReporterRegistry() {} + BasicReporter::~BasicReporter() {} + IRunner::~IRunner() {} + IMutableContext::~IMutableContext() {} + IConfig::~IConfig() {} + XmlReporter::~XmlReporter() {} + JunitReporter::~JunitReporter() {} + TestRegistry::~TestRegistry() {} + FreeFunctionTestCase::~FreeFunctionTestCase() {} + IGeneratorInfo::~IGeneratorInfo() {} + IGeneratorsForTest::~IGeneratorsForTest() {} + + void Config::dummy() {} + +} + +#pragma clang diagnostic pop #endif #ifdef CATCH_CONFIG_MAIN @@ -5071,5 +5112,7 @@ int main (int argc, char * const argv[]) { using Catch::Detail::Approx; +#pragma clang diagnostic pop + #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED