mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 12:17:11 +01:00 
			
		
		
		
	Merge branch 'catch2'
This commit is contained in:
		| @@ -19,8 +19,14 @@ | ||||
|  | ||||
| #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) | ||||
| #  define CATCH_IMPL | ||||
| #  define CATCH_CONFIG_EXTERNAL_INTERFACES | ||||
| #  if defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #    undef CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #include "internal/catch_platform.h" | ||||
|  | ||||
| #ifdef CATCH_IMPL | ||||
| #  ifndef CLARA_CONFIG_MAIN | ||||
| #    define CLARA_CONFIG_MAIN_NOT_DEFINED | ||||
| @@ -28,18 +34,19 @@ | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #include "internal/catch_notimplemented_exception.h" | ||||
| #include "internal/catch_context.h" | ||||
| #include "internal/catch_test_registry.hpp" | ||||
| #include "internal/catch_tag_alias_autoregistrar.h" | ||||
| #include "internal/catch_test_registry.h" | ||||
| #include "internal/catch_capture.hpp" | ||||
| #include "internal/catch_section.h" | ||||
| #include "internal/catch_generators.hpp" | ||||
| #include "internal/catch_benchmark.h" | ||||
| #include "internal/catch_interfaces_exception.h" | ||||
| #include "internal/catch_approx.hpp" | ||||
| #include "internal/catch_matchers_string.h" | ||||
| #include "internal/catch_matchers_vector.h" | ||||
| #include "internal/catch_approx.h" | ||||
| #include "internal/catch_compiler_capabilities.h" | ||||
| #include "internal/catch_interfaces_tag_alias_registry.h" | ||||
| #include "internal/catch_string_manip.h" | ||||
|  | ||||
| #ifndef CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #include "internal/catch_capture_matchers.h" | ||||
| #endif | ||||
|  | ||||
| // These files are included here so the single_include script doesn't put them | ||||
| // in the conditionally compiled sections | ||||
| @@ -50,30 +57,11 @@ | ||||
| #include "internal/catch_objc.hpp" | ||||
| #endif | ||||
|  | ||||
| #ifdef CATCH_IMPL | ||||
|  | ||||
| // !TBD: Move the leak detector code into a separate header | ||||
| #ifdef CATCH_CONFIG_WINDOWS_CRTDBG | ||||
| #include <crtdbg.h> | ||||
| class LeakDetector { | ||||
| public: | ||||
|     LeakDetector() { | ||||
|         int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); | ||||
|         flag |= _CRTDBG_LEAK_CHECK_DF; | ||||
|         flag |= _CRTDBG_ALLOC_MEM_DF; | ||||
|         _CrtSetDbgFlag(flag); | ||||
|         _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); | ||||
|         _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); | ||||
|         // Change this to leaking allocation's number to break there | ||||
|         _CrtSetBreakAlloc(-1); | ||||
|     } | ||||
| }; | ||||
| #else | ||||
| class LeakDetector {}; | ||||
| #ifdef CATCH_CONFIG_EXTERNAL_INTERFACES | ||||
| #include "internal/catch_external_interfaces.h" | ||||
| #endif | ||||
|  | ||||
| LeakDetector leakDetector; | ||||
|  | ||||
| #ifdef CATCH_IMPL | ||||
| #include "internal/catch_impl.hpp" | ||||
| #endif | ||||
|  | ||||
| @@ -86,134 +74,105 @@ LeakDetector leakDetector; | ||||
| #  undef CLARA_CONFIG_MAIN | ||||
| #endif | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE) | ||||
| ////// | ||||
|  | ||||
| // If this config identifier is defined then all CATCH macros are prefixed with CATCH_ | ||||
| #ifdef CATCH_CONFIG_PREFIX_ALL | ||||
|  | ||||
| #if defined(CATCH_CONFIG_FAST_COMPILE) | ||||
| #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) | ||||
| #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) | ||||
| #else | ||||
| #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) | ||||
| #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr  ) | ||||
| #endif | ||||
| #define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) | ||||
| #define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) | ||||
|  | ||||
| #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) | ||||
| #define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ ) | ||||
| #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) | ||||
| #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) | ||||
| #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) | ||||
| #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) | ||||
| #endif// CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) | ||||
|  | ||||
| #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) | ||||
| #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) | ||||
| #define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) | ||||
| #define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) | ||||
|  | ||||
| #define CATCH_CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) | ||||
| #define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ ) | ||||
| #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) | ||||
| #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) | ||||
|  | ||||
| #if defined(CATCH_CONFIG_FAST_COMPILE) | ||||
| #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) | ||||
| #else | ||||
| #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) | ||||
| #endif | ||||
|  | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
|  | ||||
| #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) | ||||
| #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) | ||||
| #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) | ||||
| #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) | ||||
| #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) | ||||
| #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) ) | ||||
|  | ||||
| #ifdef CATCH_CONFIG_VARIADIC_MACROS | ||||
|     #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) | ||||
|     #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) | ||||
|     #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) | ||||
|     #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) | ||||
|     #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) | ||||
|     #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) | ||||
|     #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
|     #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #else | ||||
|     #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) | ||||
|     #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) | ||||
|     #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) | ||||
|     #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) | ||||
|     #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) | ||||
|     #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) | ||||
|     #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) | ||||
|     #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) | ||||
| #endif | ||||
| #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) | ||||
| #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) | ||||
| #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) | ||||
| #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) | ||||
| #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) | ||||
| #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) | ||||
| #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) | ||||
| #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
|  | ||||
| #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) | ||||
| #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) | ||||
|  | ||||
| #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) | ||||
| #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() | ||||
|  | ||||
| // "BDD-style" convenience wrappers | ||||
| #ifdef CATCH_CONFIG_VARIADIC_MACROS | ||||
| #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) | ||||
| #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) | ||||
| #else | ||||
| #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) | ||||
| #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) | ||||
| #endif | ||||
| #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc, "" ) | ||||
| #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc, "" ) | ||||
| #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" ) | ||||
| #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc, "" ) | ||||
| #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc, "" ) | ||||
| #define CATCH_GIVEN( desc )    CATCH_SECTION( std::string( "Given: ") + desc ) | ||||
| #define CATCH_WHEN( desc )     CATCH_SECTION( std::string( " When: ") + desc ) | ||||
| #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc ) | ||||
| #define CATCH_THEN( desc )     CATCH_SECTION( std::string( " Then: ") + desc ) | ||||
| #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( "  And: ") + desc ) | ||||
|  | ||||
| // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required | ||||
| #else | ||||
|  | ||||
| #if defined(CATCH_CONFIG_FAST_COMPILE) | ||||
| #define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr ) | ||||
| #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) | ||||
| #define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__  ) | ||||
| #define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) | ||||
|  | ||||
| #else | ||||
| #define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr  ) | ||||
| #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) | ||||
| #endif | ||||
|  | ||||
| #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) | ||||
| #define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) | ||||
| #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) | ||||
| #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) | ||||
| #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) | ||||
| #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) | ||||
|  | ||||
| #define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) | ||||
| #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) | ||||
| #define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) | ||||
| #define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) | ||||
|  | ||||
| #define CHECK_THROWS( expr )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) | ||||
| #define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) | ||||
| #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) | ||||
| #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
|  | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) | ||||
|  | ||||
| #if defined(CATCH_CONFIG_FAST_COMPILE) | ||||
| #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) | ||||
| #else | ||||
| #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) | ||||
| #endif | ||||
|  | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
|  | ||||
| #define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) | ||||
| #define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) | ||||
| #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) | ||||
| #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) | ||||
| #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) | ||||
| #define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) ) | ||||
|  | ||||
| #ifdef CATCH_CONFIG_VARIADIC_MACROS | ||||
| #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) | ||||
| #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) | ||||
| #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) | ||||
| @@ -222,43 +181,152 @@ LeakDetector leakDetector; | ||||
| #define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) | ||||
| #define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) | ||||
| #else | ||||
| #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) | ||||
|     #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) | ||||
|     #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) | ||||
|     #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) | ||||
|     #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) | ||||
|     #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) | ||||
|     #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) | ||||
|     #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) | ||||
| #endif | ||||
| #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) | ||||
|  | ||||
| #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) | ||||
| #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) | ||||
|  | ||||
| #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) | ||||
| #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) | ||||
|  | ||||
| // "BDD-style" convenience wrappers | ||||
| #ifdef CATCH_CONFIG_VARIADIC_MACROS | ||||
| #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) | ||||
| #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) | ||||
| #else | ||||
| #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) | ||||
| #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) | ||||
| #endif | ||||
| #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc, "" ) | ||||
| #define WHEN( desc )     SECTION( std::string("    When: ") + desc, "" ) | ||||
| #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) | ||||
| #define THEN( desc )     SECTION( std::string("    Then: ") + desc, "" ) | ||||
| #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc, "" ) | ||||
|  | ||||
| #define GIVEN( desc )    SECTION( std::string("   Given: ") + desc ) | ||||
| #define WHEN( desc )     SECTION( std::string("    When: ") + desc ) | ||||
| #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc ) | ||||
| #define THEN( desc )     SECTION( std::string("    Then: ") + desc ) | ||||
| #define AND_THEN( desc ) SECTION( std::string("     And: ") + desc ) | ||||
|  | ||||
| using Catch::Detail::Approx; | ||||
|  | ||||
| #else | ||||
| ////// | ||||
| // If this config identifier is defined then all CATCH macros are prefixed with CATCH_ | ||||
| #ifdef CATCH_CONFIG_PREFIX_ALL | ||||
|  | ||||
| #define CATCH_REQUIRE( ... )        (void)(0) | ||||
| #define CATCH_REQUIRE_FALSE( ... )  (void)(0) | ||||
|  | ||||
| #define CATCH_REQUIRE_THROWS( ... ) (void)(0) | ||||
| #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) | ||||
| #define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) | ||||
| #endif// CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define CATCH_REQUIRE_NOTHROW( ... ) (void)(0) | ||||
|  | ||||
| #define CATCH_CHECK( ... )         (void)(0) | ||||
| #define CATCH_CHECK_FALSE( ... )   (void)(0) | ||||
| #define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__) | ||||
| #define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__)) | ||||
| #define CATCH_CHECK_NOFAIL( ... )  (void)(0) | ||||
|  | ||||
| #define CATCH_CHECK_THROWS( ... )  (void)(0) | ||||
| #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0) | ||||
| #define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define CATCH_CHECK_NOTHROW( ... ) (void)(0) | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CATCH_CHECK_THAT( arg, matcher )   (void)(0) | ||||
|  | ||||
| #define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
|  | ||||
| #define CATCH_INFO( msg )    (void)(0) | ||||
| #define CATCH_WARN( msg )    (void)(0) | ||||
| #define CATCH_CAPTURE( msg ) (void)(0) | ||||
|  | ||||
| #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
| #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
| #define CATCH_METHOD_AS_TEST_CASE( method, ... ) | ||||
| #define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) | ||||
| #define CATCH_SECTION( ... ) | ||||
| #define CATCH_FAIL( ... ) (void)(0) | ||||
| #define CATCH_FAIL_CHECK( ... ) (void)(0) | ||||
| #define CATCH_SUCCEED( ... ) (void)(0) | ||||
|  | ||||
| #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
|  | ||||
| // "BDD-style" convenience wrappers | ||||
| #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
| #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) | ||||
| #define CATCH_GIVEN( desc ) | ||||
| #define CATCH_WHEN( desc ) | ||||
| #define CATCH_AND_WHEN( desc ) | ||||
| #define CATCH_THEN( desc ) | ||||
| #define CATCH_AND_THEN( desc ) | ||||
|  | ||||
| // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required | ||||
| #else | ||||
|  | ||||
| #define REQUIRE( ... )       (void)(0) | ||||
| #define REQUIRE_FALSE( ... ) (void)(0) | ||||
|  | ||||
| #define REQUIRE_THROWS( ... ) (void)(0) | ||||
| #define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) | ||||
| #define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define REQUIRE_NOTHROW( ... ) (void)(0) | ||||
|  | ||||
| #define CHECK( ... ) (void)(0) | ||||
| #define CHECK_FALSE( ... ) (void)(0) | ||||
| #define CHECKED_IF( ... ) if (__VA_ARGS__) | ||||
| #define CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) | ||||
| #define CHECK_NOFAIL( ... ) (void)(0) | ||||
|  | ||||
| #define CHECK_THROWS( ... )  (void)(0) | ||||
| #define CHECK_THROWS_AS( expr, exceptionType ) (void)(0) | ||||
| #define CHECK_THROWS_WITH( expr, matcher ) (void)(0) | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
| #define CHECK_NOTHROW( ... ) (void)(0) | ||||
|  | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
| #define CHECK_THAT( arg, matcher ) (void)(0) | ||||
|  | ||||
| #define REQUIRE_THAT( arg, matcher ) (void)(0) | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
|  | ||||
| #define INFO( msg ) (void)(0) | ||||
| #define WARN( msg ) (void)(0) | ||||
| #define CAPTURE( msg ) (void)(0) | ||||
|  | ||||
| #define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
| #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
| #define METHOD_AS_TEST_CASE( method, ... ) | ||||
| #define REGISTER_TEST_CASE( Function, ... ) (void)(0) | ||||
| #define SECTION( ... ) | ||||
| #define FAIL( ... ) (void)(0) | ||||
| #define FAIL_CHECK( ... ) (void)(0) | ||||
| #define SUCCEED( ... ) (void)(0) | ||||
| #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) | ||||
|  | ||||
| // "BDD-style" convenience wrappers | ||||
| #define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) | ||||
| #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) | ||||
|  | ||||
| #define GIVEN( desc ) | ||||
| #define WHEN( desc ) | ||||
| #define AND_WHEN( desc ) | ||||
| #define THEN( desc ) | ||||
| #define AND_THEN( desc ) | ||||
|  | ||||
| using Catch::Detail::Approx; | ||||
|  | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #include "internal/catch_reenable_warnings.h" | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_HPP_INCLUDED | ||||
|   | ||||
							
								
								
									
										1054
									
								
								include/external/clara.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1054
									
								
								include/external/clara.h
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1232
									
								
								include/external/clara.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1232
									
								
								include/external/clara.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										168
									
								
								include/external/tbc_text_format.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										168
									
								
								include/external/tbc_text_format.h
									
									
									
									
										vendored
									
									
								
							| @@ -1,168 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 18/4/2013. | ||||
|  *  Copyright 2013 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) | ||||
|  */ | ||||
| // Only use header guard if we are not using an outer namespace | ||||
| #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE | ||||
| # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED | ||||
| #  ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED | ||||
| #   define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED | ||||
| #  endif | ||||
| # else | ||||
| #  define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED | ||||
| # endif | ||||
| #endif | ||||
| #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <sstream> | ||||
|  | ||||
| // Use optional outer namespace | ||||
| #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE | ||||
| namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { | ||||
| #endif | ||||
|  | ||||
| namespace Tbc { | ||||
|  | ||||
| #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH | ||||
|     const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; | ||||
| #else | ||||
|     const unsigned int consoleWidth = 80; | ||||
| #endif | ||||
|  | ||||
|     struct TextAttributes { | ||||
|         TextAttributes() | ||||
|         :   initialIndent( std::string::npos ), | ||||
|             indent( 0 ), | ||||
|             width( consoleWidth-1 ) | ||||
|         {} | ||||
|  | ||||
|         TextAttributes& setInitialIndent( std::size_t _value )  { initialIndent = _value; return *this; } | ||||
|         TextAttributes& setIndent( std::size_t _value )         { indent = _value; return *this; } | ||||
|         TextAttributes& setWidth( std::size_t _value )          { width = _value; return *this; } | ||||
|  | ||||
|         std::size_t initialIndent;  // indent of first line, or npos | ||||
|         std::size_t indent;         // indent of subsequent lines, or all if initialIndent is npos | ||||
|         std::size_t width;          // maximum width of text, including indent. Longer text will wrap | ||||
|     }; | ||||
|  | ||||
|     class Text { | ||||
|     public: | ||||
|         Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) | ||||
|         : attr( _attr ) | ||||
|         { | ||||
|             const std::string wrappableBeforeChars = "[({<\t"; | ||||
|             const std::string wrappableAfterChars = "])}>-,./|\\"; | ||||
|             const std::string wrappableInsteadOfChars = " \n\r"; | ||||
|             std::string indent = _attr.initialIndent != std::string::npos | ||||
|                 ? std::string( _attr.initialIndent, ' ' ) | ||||
|                 : std::string( _attr.indent, ' ' ); | ||||
|  | ||||
|             typedef std::string::const_iterator iterator; | ||||
|             iterator it = _str.begin(); | ||||
|             const iterator strEnd = _str.end(); | ||||
|  | ||||
|             while( it != strEnd ) { | ||||
|  | ||||
|                 if( lines.size() >= 1000 ) { | ||||
|                     lines.push_back( "... message truncated due to excessive size" ); | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 std::string suffix; | ||||
|                 std::size_t width = (std::min)( static_cast<size_t>( strEnd-it ), _attr.width-static_cast<size_t>( indent.size() ) ); | ||||
|                 iterator itEnd = it+width; | ||||
|                 iterator itNext = _str.end(); | ||||
|  | ||||
|                 iterator itNewLine = std::find( it, itEnd, '\n' ); | ||||
|                 if( itNewLine != itEnd ) | ||||
|                     itEnd = itNewLine; | ||||
|  | ||||
|                 if( itEnd != strEnd  ) { | ||||
|                     bool foundWrapPoint = false; | ||||
|                     iterator findIt = itEnd; | ||||
|                     do { | ||||
|                         if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) { | ||||
|                             itEnd = findIt+1; | ||||
|                             itNext = findIt+1; | ||||
|                             foundWrapPoint = true; | ||||
|                         } | ||||
|                         else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) { | ||||
|                             itEnd = findIt; | ||||
|                             itNext = findIt; | ||||
|                             foundWrapPoint = true; | ||||
|                         } | ||||
|                         else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) { | ||||
|                             itNext = findIt+1; | ||||
|                             itEnd = findIt; | ||||
|                             foundWrapPoint = true; | ||||
|                         } | ||||
|                         if( findIt == it ) | ||||
|                             break; | ||||
|                         else | ||||
|                             --findIt; | ||||
|                     } | ||||
|                     while( !foundWrapPoint ); | ||||
|  | ||||
|                     if( !foundWrapPoint ) { | ||||
|                         // No good wrap char, so we'll break mid word and add a hyphen | ||||
|                         --itEnd; | ||||
|                         itNext = itEnd; | ||||
|                         suffix = "-"; | ||||
|                     } | ||||
|                     else { | ||||
|                         while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos ) | ||||
|                             --itEnd; | ||||
|                     } | ||||
|                 } | ||||
|                 lines.push_back( indent + std::string( it, itEnd ) + suffix ); | ||||
|  | ||||
|                 if( indent.size() != _attr.indent ) | ||||
|                     indent = std::string( _attr.indent, ' ' ); | ||||
|                 it = itNext; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|         typedef std::vector<std::string>::const_iterator const_iterator; | ||||
|  | ||||
|         const_iterator begin() const { return lines.begin(); } | ||||
|         const_iterator end() const { return lines.end(); } | ||||
|         std::string const& last() const { return lines.back(); } | ||||
|         std::size_t size() const { return lines.size(); } | ||||
|         std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } | ||||
|         std::string toString() const { | ||||
|             std::ostringstream oss; | ||||
|             oss << *this; | ||||
|             return oss.str(); | ||||
|         } | ||||
|  | ||||
|         inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { | ||||
|             for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); | ||||
|                 it != itEnd; ++it ) { | ||||
|                 if( it != _text.begin() ) | ||||
|                     _stream << "\n"; | ||||
|                 _stream << *it; | ||||
|             } | ||||
|             return _stream; | ||||
|         } | ||||
|  | ||||
|  | ||||
|     private: | ||||
|         std::string str; | ||||
|         TextAttributes attr; | ||||
|         std::vector<std::string> lines; | ||||
|     }; | ||||
|  | ||||
| } // end namespace Tbc | ||||
|  | ||||
| #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE | ||||
| } // end outer namespace | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED | ||||
							
								
								
									
										56
									
								
								include/internal/catch_approx.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								include/internal/catch_approx.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| /* | ||||
|  *  Created by Martin on 19/07/2017. | ||||
|  *  Copyright 2017 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_approx.h" | ||||
|  | ||||
| #include <cmath> | ||||
| #include <limits> | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| // Performs equivalent check of std::fabs(lhs - rhs) <= margin | ||||
| // But without the subtraction to allow for INFINITY in comparison | ||||
| bool marginComparison(double lhs, double rhs, double margin) { | ||||
|     return (lhs + margin >= rhs) && (rhs + margin >= lhs); | ||||
| } | ||||
|  | ||||
| } | ||||
|  | ||||
| namespace Catch { | ||||
| namespace Detail { | ||||
|  | ||||
|     Approx::Approx ( double value ) | ||||
|     :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ), | ||||
|         m_margin( 0.0 ), | ||||
|         m_scale( 0.0 ), | ||||
|         m_value( value ) | ||||
|     {} | ||||
|  | ||||
|     Approx Approx::custom() { | ||||
|         return Approx( 0 ); | ||||
|     } | ||||
|  | ||||
|     std::string Approx::toString() const { | ||||
|         std::ostringstream oss; | ||||
|         oss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )"; | ||||
|         return oss.str(); | ||||
|     } | ||||
|  | ||||
|     bool Approx::equalityComparisonImpl(const double other) const { | ||||
|         // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value | ||||
|         // Thanks to Richard Harris for his help refining the scaled margin value | ||||
|         return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value))); | ||||
|     } | ||||
|  | ||||
| } // end namespace Detail | ||||
|  | ||||
| std::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) { | ||||
|     return value.toString(); | ||||
| } | ||||
|  | ||||
| } // end namespace Catch | ||||
							
								
								
									
										126
									
								
								include/internal/catch_approx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								include/internal/catch_approx.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| /* | ||||
|  *  Created by Phil on 28/04/2011. | ||||
|  *  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_APPROX_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_enforce.h" | ||||
| #include "catch_tostring.h" | ||||
|  | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace Catch { | ||||
| namespace Detail { | ||||
|  | ||||
|     class Approx { | ||||
|     private: | ||||
|         bool equalityComparisonImpl(double other) const; | ||||
|  | ||||
|     public: | ||||
|         explicit Approx ( double value ); | ||||
|  | ||||
|         static Approx custom(); | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         Approx operator()( T const& value ) { | ||||
|             Approx approx( static_cast<double>(value) ); | ||||
|             approx.epsilon( m_epsilon ); | ||||
|             approx.margin( m_margin ); | ||||
|             approx.scale( m_scale ); | ||||
|             return approx; | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         explicit Approx( T const& value ): Approx(static_cast<double>(value)) | ||||
|         {} | ||||
|  | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator == ( const T& lhs, Approx const& rhs ) { | ||||
|             auto lhs_v = static_cast<double>(lhs); | ||||
|             return rhs.equalityComparisonImpl(lhs_v); | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator == ( Approx const& lhs, const T& rhs ) { | ||||
|             return operator==( rhs, lhs ); | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator != ( T const& lhs, Approx const& rhs ) { | ||||
|             return !operator==( lhs, rhs ); | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator != ( Approx const& lhs, T const& rhs ) { | ||||
|             return !operator==( rhs, lhs ); | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator <= ( T const& lhs, Approx const& rhs ) { | ||||
|             return static_cast<double>(lhs) < rhs.m_value || lhs == rhs; | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator <= ( Approx const& lhs, T const& rhs ) { | ||||
|             return lhs.m_value < static_cast<double>(rhs) || lhs == rhs; | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator >= ( T const& lhs, Approx const& rhs ) { | ||||
|             return static_cast<double>(lhs) > rhs.m_value || lhs == rhs; | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         friend bool operator >= ( Approx const& lhs, T const& rhs ) { | ||||
|             return lhs.m_value > static_cast<double>(rhs) || lhs == rhs; | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         Approx& epsilon( T const& newEpsilon ) { | ||||
|             double epsilonAsDouble = static_cast<double>(newEpsilon); | ||||
|             CATCH_ENFORCE(epsilonAsDouble >= 0 && epsilonAsDouble <= 1.0, | ||||
|                           "Invalid Approx::epsilon: " << epsilonAsDouble | ||||
|                           << ", Approx::epsilon has to be between 0 and 1"); | ||||
|             m_epsilon = epsilonAsDouble; | ||||
|             return *this; | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         Approx& margin( T const& newMargin ) { | ||||
|             double marginAsDouble = static_cast<double>(newMargin); | ||||
|             CATCH_ENFORCE(marginAsDouble >= 0, | ||||
|                           "Invalid Approx::margin: " << marginAsDouble | ||||
|                           << ", Approx::Margin has to be non-negative."); | ||||
|             m_margin = marginAsDouble; | ||||
|             return *this; | ||||
|         } | ||||
|  | ||||
|         template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type> | ||||
|         Approx& scale( T const& newScale ) { | ||||
|             m_scale = static_cast<double>(newScale); | ||||
|             return *this; | ||||
|         } | ||||
|  | ||||
|         std::string toString() const; | ||||
|  | ||||
|     private: | ||||
|         double m_epsilon; | ||||
|         double m_margin; | ||||
|         double m_scale; | ||||
|         double m_value; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| template<> | ||||
| struct StringMaker<Catch::Detail::Approx> { | ||||
|     static std::string convert(Catch::Detail::Approx const& value); | ||||
| }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED | ||||
							
								
								
									
										147
									
								
								include/internal/catch_assertionhandler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								include/internal/catch_assertionhandler.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | ||||
| /* | ||||
|  *  Created by Phil on 8/8/2017. | ||||
|  *  Copyright 2017 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_assertionhandler.h" | ||||
| #include "catch_assertionresult.h" | ||||
| #include "catch_interfaces_capture.h" | ||||
| #include "catch_interfaces_runner.h" | ||||
| #include "catch_interfaces_config.h" | ||||
| #include "catch_context.h" | ||||
| #include "catch_debugger.h" | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
| #include "catch_capture_matchers.h" | ||||
|  | ||||
| #include <cassert> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { | ||||
|         expr.streamReconstructedExpression( os ); | ||||
|         return os; | ||||
|     } | ||||
|  | ||||
|     LazyExpression::LazyExpression( bool isNegated ) | ||||
|     :   m_isNegated( isNegated ) | ||||
|     {} | ||||
|  | ||||
|     LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {} | ||||
|  | ||||
|     LazyExpression::operator bool() const { | ||||
|         return m_transientExpression != nullptr; | ||||
|     } | ||||
|  | ||||
|     auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& { | ||||
|         if( lazyExpr.m_isNegated ) | ||||
|             os << "!"; | ||||
|  | ||||
|         if( lazyExpr ) { | ||||
|             if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() ) | ||||
|                 os << "(" << *lazyExpr.m_transientExpression << ")"; | ||||
|             else | ||||
|                 os << *lazyExpr.m_transientExpression; | ||||
|         } | ||||
|         else { | ||||
|             os << "{** error - unchecked empty expression requested **}"; | ||||
|         } | ||||
|         return os; | ||||
|     } | ||||
|  | ||||
|     AssertionHandler::AssertionHandler | ||||
|         (   StringRef macroName, | ||||
|             SourceLineInfo const& lineInfo, | ||||
|             StringRef capturedExpression, | ||||
|             ResultDisposition::Flags resultDisposition ) | ||||
|     :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition } | ||||
|     { | ||||
|         getCurrentContext().getResultCapture()->assertionStarting( m_assertionInfo ); | ||||
|     } | ||||
|     AssertionHandler::~AssertionHandler() { | ||||
|         if ( m_inExceptionGuard ) { | ||||
|             handle( ResultWas::ThrewException, "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE" ); | ||||
|             getCurrentContext().getResultCapture()->exceptionEarlyReported(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void AssertionHandler::handle( ITransientExpression const& expr ) { | ||||
|  | ||||
|         bool negated = isFalseTest( m_assertionInfo.resultDisposition ); | ||||
|         bool result = expr.getResult() != negated; | ||||
|  | ||||
|         handle( result ? ResultWas::Ok : ResultWas::ExpressionFailed, &expr, negated ); | ||||
|     } | ||||
|     void AssertionHandler::handle( ResultWas::OfType resultType ) { | ||||
|         handle( resultType, nullptr, false ); | ||||
|     } | ||||
|     void AssertionHandler::handle( ResultWas::OfType resultType, StringRef const& message ) { | ||||
|         AssertionResultData data( resultType, LazyExpression( false ) ); | ||||
|         data.message = message; | ||||
|         handle( data, nullptr ); | ||||
|     } | ||||
|     void AssertionHandler::handle( ResultWas::OfType resultType, ITransientExpression const* expr, bool negated ) { | ||||
|         AssertionResultData data( resultType, LazyExpression( negated ) ); | ||||
|         handle( data, expr ); | ||||
|     } | ||||
|     void AssertionHandler::handle( AssertionResultData const& resultData, ITransientExpression const* expr ) { | ||||
|  | ||||
|         getResultCapture().assertionRun(); | ||||
|  | ||||
|         AssertionResult assertionResult{ m_assertionInfo, resultData }; | ||||
|         assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; | ||||
|  | ||||
|         getResultCapture().assertionEnded( assertionResult ); | ||||
|  | ||||
|         if( !assertionResult.isOk() ) { | ||||
|             m_shouldDebugBreak = getCurrentContext().getConfig()->shouldDebugBreak(); | ||||
|             m_shouldThrow = | ||||
|                     getCurrentContext().getRunner()->aborting() || | ||||
|                     (m_assertionInfo.resultDisposition & ResultDisposition::Normal); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     auto AssertionHandler::allowThrows() const -> bool { | ||||
|         return getCurrentContext().getConfig()->allowThrows(); | ||||
|     } | ||||
|  | ||||
|     auto AssertionHandler::shouldDebugBreak() const -> bool { | ||||
|         return m_shouldDebugBreak; | ||||
|     } | ||||
|     void AssertionHandler::reactWithDebugBreak() const { | ||||
|         if (m_shouldDebugBreak) { | ||||
|             /////////////////////////////////////////////////////////////////// | ||||
|             // To inspect the state during test, you need to go one level up the callstack | ||||
|             // To go back to the test and change execution, jump over the reactWithoutDebugBreak() call | ||||
|             /////////////////////////////////////////////////////////////////// | ||||
|             CATCH_BREAK_INTO_DEBUGGER(); | ||||
|         } | ||||
|         reactWithoutDebugBreak(); | ||||
|     } | ||||
|     void AssertionHandler::reactWithoutDebugBreak() const { | ||||
|         if( m_shouldThrow ) | ||||
|             throw Catch::TestFailureException(); | ||||
|     } | ||||
|  | ||||
|     void AssertionHandler::useActiveException() { | ||||
|         handle( ResultWas::ThrewException, Catch::translateActiveException() ); | ||||
|     } | ||||
|  | ||||
|     void AssertionHandler::setExceptionGuard() { | ||||
|         assert( m_inExceptionGuard == false ); | ||||
|         m_inExceptionGuard = true; | ||||
|     } | ||||
|     void AssertionHandler::unsetExceptionGuard() { | ||||
|         assert( m_inExceptionGuard == true ); | ||||
|         m_inExceptionGuard = false; | ||||
|     } | ||||
|  | ||||
|     // This is the overload that takes a string and infers the Equals matcher from it | ||||
|     // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp | ||||
|     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString  ) { | ||||
|         handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString ); | ||||
|     } | ||||
|  | ||||
| } // namespace Catch | ||||
							
								
								
									
										73
									
								
								include/internal/catch_assertionhandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								include/internal/catch_assertionhandler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /* | ||||
|  *  Created by Phil on 8/8/2017. | ||||
|  *  Copyright 2017 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_ASSERTIONHANDLER_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_ASSERTIONHANDLER_H_INCLUDED | ||||
|  | ||||
| #include "catch_decomposer.h" | ||||
| #include "catch_assertioninfo.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct TestFailureException{}; | ||||
|     struct AssertionResultData; | ||||
|  | ||||
|     class LazyExpression { | ||||
|         friend class AssertionHandler; | ||||
|         friend struct AssertionStats; | ||||
|  | ||||
|         ITransientExpression const* m_transientExpression = nullptr; | ||||
|         bool m_isNegated; | ||||
|     public: | ||||
|         LazyExpression( bool isNegated ); | ||||
|         LazyExpression( LazyExpression const& other ); | ||||
|         LazyExpression& operator = ( LazyExpression const& ) = delete; | ||||
|  | ||||
|         explicit operator bool() const; | ||||
|  | ||||
|         friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&; | ||||
|     }; | ||||
|  | ||||
|     class AssertionHandler { | ||||
|         AssertionInfo m_assertionInfo; | ||||
|         bool m_shouldDebugBreak = false; | ||||
|         bool m_shouldThrow = false; | ||||
|         bool m_inExceptionGuard = false; | ||||
|  | ||||
|     public: | ||||
|         AssertionHandler | ||||
|             (   StringRef macroName, | ||||
|                 SourceLineInfo const& lineInfo, | ||||
|                 StringRef capturedExpression, | ||||
|                 ResultDisposition::Flags resultDisposition ); | ||||
|         ~AssertionHandler(); | ||||
|  | ||||
|         void handle( ITransientExpression const& expr ); | ||||
|  | ||||
|         template<typename T> | ||||
|         void handle( ExprLhs<T> const& expr ) { | ||||
|             handle( expr.makeUnaryExpr() ); | ||||
|         } | ||||
|         void handle( ResultWas::OfType resultType ); | ||||
|         void handle( ResultWas::OfType resultType, StringRef const& message ); | ||||
|         void handle( ResultWas::OfType resultType, ITransientExpression const* expr, bool negated ); | ||||
|         void handle( AssertionResultData const& resultData, ITransientExpression const* expr ); | ||||
|  | ||||
|         auto shouldDebugBreak() const -> bool; | ||||
|         auto allowThrows() const -> bool; | ||||
|         void reactWithDebugBreak() const; | ||||
|         void reactWithoutDebugBreak() const; | ||||
|         void useActiveException(); | ||||
|         void setExceptionGuard(); | ||||
|         void unsetExceptionGuard(); | ||||
|     }; | ||||
|  | ||||
|     void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ); | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_ASSERTIONHANDLER_H_INCLUDED | ||||
							
								
								
									
										31
									
								
								include/internal/catch_assertioninfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								include/internal/catch_assertioninfo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| /* | ||||
|  *  Created by Phil on 8/8/2017. | ||||
|  *  Copyright 2017 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_ASSERTIONINFO_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_ASSERTIONINFO_H_INCLUDED | ||||
|  | ||||
| #include "catch_result_type.h" | ||||
| #include "catch_common.h" | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct AssertionInfo | ||||
|     { | ||||
|         StringRef macroName; | ||||
|         SourceLineInfo lineInfo; | ||||
|         StringRef capturedExpression; | ||||
|         ResultDisposition::Flags resultDisposition; | ||||
|  | ||||
|         // We want to delete this constructor but a compiler bug in 4.8 means | ||||
|         // the struct is then treated as non-aggregate | ||||
|         //AssertionInfo() = delete; | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_ASSERTIONINFO_H_INCLUDED | ||||
							
								
								
									
										99
									
								
								include/internal/catch_assertionresult.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								include/internal/catch_assertionresult.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| /* | ||||
|  *  Created by Phil on 8/8/12 | ||||
|  *  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) | ||||
|  */ | ||||
|  | ||||
| #include "catch_assertionresult.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression): | ||||
|         lazyExpression(_lazyExpression), | ||||
|         resultType(_resultType) {} | ||||
|  | ||||
|     std::string AssertionResultData::reconstructExpression() const { | ||||
|  | ||||
|         if( reconstructedExpression.empty() ) { | ||||
|             if( lazyExpression ) { | ||||
|                 // !TBD Use stringstream for now, but rework above to pass stream in | ||||
|                 std::ostringstream oss; | ||||
|                 oss << lazyExpression; | ||||
|                 reconstructedExpression = oss.str(); | ||||
|             } | ||||
|         } | ||||
|         return reconstructedExpression; | ||||
|     } | ||||
|  | ||||
|     AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) | ||||
|     :   m_info( info ), | ||||
|         m_resultData( data ) | ||||
|     {} | ||||
|  | ||||
|     // Result was a success | ||||
|     bool AssertionResult::succeeded() const { | ||||
|         return Catch::isOk( m_resultData.resultType ); | ||||
|     } | ||||
|  | ||||
|     // Result was a success, or failure is suppressed | ||||
|     bool AssertionResult::isOk() const { | ||||
|         return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); | ||||
|     } | ||||
|  | ||||
|     ResultWas::OfType AssertionResult::getResultType() const { | ||||
|         return m_resultData.resultType; | ||||
|     } | ||||
|  | ||||
|     bool AssertionResult::hasExpression() const { | ||||
|         return m_info.capturedExpression[0] != 0; | ||||
|     } | ||||
|  | ||||
|     bool AssertionResult::hasMessage() const { | ||||
|         return !m_resultData.message.empty(); | ||||
|     } | ||||
|  | ||||
|     std::string AssertionResult::getExpression() const { | ||||
|         if( isFalseTest( m_info.resultDisposition ) ) | ||||
|             return "!(" + std::string(m_info.capturedExpression) + ")"; | ||||
|         else | ||||
|             return m_info.capturedExpression; | ||||
|     } | ||||
|  | ||||
|     std::string AssertionResult::getExpressionInMacro() const { | ||||
|         std::string expr; | ||||
|         if( m_info.macroName[0] == 0 ) | ||||
|             expr = m_info.capturedExpression; | ||||
|         else { | ||||
|             expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 ); | ||||
|             expr += m_info.macroName; | ||||
|             expr += "( "; | ||||
|             expr += m_info.capturedExpression; | ||||
|             expr += " )"; | ||||
|         } | ||||
|         return expr; | ||||
|     } | ||||
|  | ||||
|     bool AssertionResult::hasExpandedExpression() const { | ||||
|         return hasExpression() && getExpandedExpression() != getExpression(); | ||||
|     } | ||||
|  | ||||
|     std::string AssertionResult::getExpandedExpression() const { | ||||
|         std::string expr = m_resultData.reconstructExpression(); | ||||
|         return expr.empty() | ||||
|                 ? getExpression() | ||||
|                 : expr; | ||||
|     } | ||||
|  | ||||
|     std::string AssertionResult::getMessage() const { | ||||
|         return m_resultData.message; | ||||
|     } | ||||
|     SourceLineInfo AssertionResult::getSourceInfo() const { | ||||
|         return m_info.lineInfo; | ||||
|     } | ||||
|  | ||||
|     std::string AssertionResult::getTestMacroName() const { | ||||
|         return m_info.macroName; | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
| @@ -9,100 +9,32 @@ | ||||
| #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED | ||||
|  | ||||
| #include <string> | ||||
| #include "catch_assertioninfo.h" | ||||
| #include "catch_result_type.h" | ||||
| #include "catch_common.h" | ||||
| #include "catch_stringref.h" | ||||
| #include "catch_assertionhandler.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; | ||||
|  | ||||
|     struct DecomposedExpression | ||||
|     { | ||||
|         virtual ~DecomposedExpression() {} | ||||
|         virtual bool isBinaryExpression() const { | ||||
|             return false; | ||||
|         } | ||||
|         virtual void reconstructExpression( std::string& dest ) const = 0; | ||||
|  | ||||
|         // Only simple binary comparisons can be decomposed. | ||||
|         // If more complex check is required then wrap sub-expressions in parentheses. | ||||
|         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); | ||||
|         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); | ||||
|         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); | ||||
|         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); | ||||
|         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); | ||||
|         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); | ||||
|         template<typename T> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); | ||||
|  | ||||
|     private: | ||||
|         DecomposedExpression& operator = (DecomposedExpression const&); | ||||
|     }; | ||||
|  | ||||
|     struct AssertionInfo | ||||
|     { | ||||
|         AssertionInfo(); | ||||
|         AssertionInfo(  char const * _macroName, | ||||
|                         SourceLineInfo const& _lineInfo, | ||||
|                         char const * _capturedExpression, | ||||
|                         ResultDisposition::Flags _resultDisposition, | ||||
|                         char const * _secondArg = ""); | ||||
|  | ||||
|         char const * macroName; | ||||
|         SourceLineInfo lineInfo; | ||||
|         char const * capturedExpression; | ||||
|         ResultDisposition::Flags resultDisposition; | ||||
|         char const * secondArg; | ||||
|     }; | ||||
|  | ||||
|     struct AssertionResultData | ||||
|     { | ||||
|         AssertionResultData() : decomposedExpression( CATCH_NULL ) | ||||
|                               , resultType( ResultWas::Unknown ) | ||||
|                               , negated( false ) | ||||
|                               , parenthesized( false ) {} | ||||
|         AssertionResultData() = delete; | ||||
|  | ||||
|         void negate( bool parenthesize ) { | ||||
|             negated = !negated; | ||||
|             parenthesized = parenthesize; | ||||
|             if( resultType == ResultWas::Ok ) | ||||
|                 resultType = ResultWas::ExpressionFailed; | ||||
|             else if( resultType == ResultWas::ExpressionFailed ) | ||||
|                 resultType = ResultWas::Ok; | ||||
|         } | ||||
|         AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression ); | ||||
|  | ||||
|         std::string const& reconstructExpression() const { | ||||
|             if( decomposedExpression != CATCH_NULL ) { | ||||
|                 decomposedExpression->reconstructExpression( reconstructedExpression ); | ||||
|                 if( parenthesized ) { | ||||
|                     reconstructedExpression.insert( 0, 1, '(' ); | ||||
|                     reconstructedExpression.append( 1, ')' ); | ||||
|                 } | ||||
|                 if( negated ) { | ||||
|                     reconstructedExpression.insert( 0, 1, '!' ); | ||||
|                 } | ||||
|                 decomposedExpression = CATCH_NULL; | ||||
|             } | ||||
|             return reconstructedExpression; | ||||
|         } | ||||
|  | ||||
|         mutable DecomposedExpression const* decomposedExpression; | ||||
|         mutable std::string reconstructedExpression; | ||||
|         std::string message; | ||||
|         mutable std::string reconstructedExpression; | ||||
|         LazyExpression lazyExpression; | ||||
|         ResultWas::OfType resultType; | ||||
|         bool negated; | ||||
|         bool parenthesized; | ||||
|  | ||||
|         std::string reconstructExpression() const; | ||||
|     }; | ||||
|  | ||||
|     class AssertionResult { | ||||
|     public: | ||||
|         AssertionResult(); | ||||
|         AssertionResult() = delete; | ||||
|         AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); | ||||
|         ~AssertionResult(); | ||||
| #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|          AssertionResult( AssertionResult const& )              = default; | ||||
|          AssertionResult( AssertionResult && )                  = default; | ||||
|          AssertionResult& operator = ( AssertionResult const& ) = default; | ||||
|          AssertionResult& operator = ( AssertionResult && )     = default; | ||||
| #  endif | ||||
|  | ||||
|         bool isOk() const; | ||||
|         bool succeeded() const; | ||||
| @@ -116,10 +48,8 @@ namespace Catch { | ||||
|         std::string getMessage() const; | ||||
|         SourceLineInfo getSourceInfo() const; | ||||
|         std::string getTestMacroName() const; | ||||
|         void discardDecomposedExpression() const; | ||||
|         void expandDecomposedExpression() const; | ||||
|  | ||||
|     protected: | ||||
|     //protected: | ||||
|         AssertionInfo m_info; | ||||
|         AssertionResultData m_resultData; | ||||
|     }; | ||||
|   | ||||
							
								
								
									
										36
									
								
								include/internal/catch_benchmark.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								include/internal/catch_benchmark.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| /* | ||||
|  *  Created by Phil on 04/07/2017. | ||||
|  *  Copyright 2017 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_benchmark.h" | ||||
| #include "catch_capture.hpp" | ||||
| #include "catch_interfaces_reporter.h" | ||||
| #include "catch_context.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     auto BenchmarkLooper::getResolution() -> uint64_t { | ||||
|         return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple(); | ||||
|     } | ||||
|  | ||||
|     void BenchmarkLooper::reportStart() { | ||||
|         getResultCapture().benchmarkStarting( { m_name } ); | ||||
|     } | ||||
|     auto BenchmarkLooper::needsMoreIterations() -> bool { | ||||
|         auto elapsed = m_timer.getElapsedNanoseconds(); | ||||
|  | ||||
|         // Exponentially increasing iterations until we're confident in our timer resolution | ||||
|         if( elapsed < m_resolution ) { | ||||
|             m_iterationsToRun *= 10; | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } ); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
							
								
								
									
										57
									
								
								include/internal/catch_benchmark.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								include/internal/catch_benchmark.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| /* | ||||
|  *  Created by Phil on 04/07/2017. | ||||
|  *  Copyright 2017 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_BENCHMARK_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED | ||||
|  | ||||
| #include "catch_stringref.h" | ||||
| #include "catch_timer.h" | ||||
|  | ||||
| #include <cstdint> | ||||
| #include <string> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class BenchmarkLooper { | ||||
|  | ||||
|         std::string m_name; | ||||
|         std::size_t m_count = 0; | ||||
|         std::size_t m_iterationsToRun = 1; | ||||
|         uint64_t m_resolution; | ||||
|         Timer m_timer; | ||||
|  | ||||
|         static auto getResolution() -> uint64_t; | ||||
|     public: | ||||
|         // Keep most of this inline as it's on the code path that is being timed | ||||
|         BenchmarkLooper( StringRef name ) | ||||
|         :   m_name( name ), | ||||
|             m_resolution( getResolution() ) | ||||
|         { | ||||
|             reportStart(); | ||||
|             m_timer.start(); | ||||
|         } | ||||
|  | ||||
|         explicit operator bool() { | ||||
|             if( m_count < m_iterationsToRun ) | ||||
|                 return true; | ||||
|             return needsMoreIterations(); | ||||
|         } | ||||
|  | ||||
|         void increment() { | ||||
|             ++m_count; | ||||
|         } | ||||
|  | ||||
|         void reportStart(); | ||||
|         auto needsMoreIterations() -> bool; | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #define BENCHMARK( name ) \ | ||||
|     for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() ) | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_BENCHMARK_H_INCLUDED | ||||
| @@ -8,20 +8,17 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_result_builder.h" | ||||
| #include "catch_assertionhandler.h" | ||||
| #include "catch_message.h" | ||||
| #include "catch_interfaces_capture.h" | ||||
| #include "catch_debugger.h" | ||||
| #include "catch_common.h" | ||||
| #include "catch_tostring.h" | ||||
| #include "catch_interfaces_runner.h" | ||||
| #include "catch_compiler_capabilities.h" | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE) | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) | ||||
| # define CATCH_INTERNAL_STRINGIFY(expr) #expr | ||||
|   #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__ | ||||
| #else | ||||
| # define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" | ||||
|   #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" | ||||
| #endif | ||||
|  | ||||
| #if defined(CATCH_CONFIG_FAST_COMPILE) | ||||
| @@ -29,158 +26,138 @@ | ||||
| // We can speedup compilation significantly by breaking into debugger lower in | ||||
| // the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER | ||||
| // macro in each assertion | ||||
| #define INTERNAL_CATCH_REACT( resultBuilder ) \ | ||||
|     resultBuilder.react(); | ||||
| #define INTERNAL_CATCH_REACT( handler ) \ | ||||
|     handler.reactWithDebugBreak(); | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| // Another way to speed-up compilation is to omit local try-catch for REQUIRE* | ||||
| // macros. | ||||
| // This can potentially cause false negative, if the test code catches | ||||
| // the exception before it propagates back up to the runner. | ||||
| #define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \ | ||||
|     do { \ | ||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ | ||||
|         __catchResult.setExceptionGuard(); \ | ||||
|         CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ | ||||
|         ( __catchResult <= expr ).endExpression(); \ | ||||
|         CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ | ||||
|         __catchResult.unsetExceptionGuard(); \ | ||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|     } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look | ||||
| // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. | ||||
| #define INTERNAL_CATCH_TRY( capturer ) capturer.setExceptionGuard(); | ||||
| #define INTERNAL_CATCH_CATCH( capturer ) capturer.unsetExceptionGuard(); | ||||
|  | ||||
| #define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \ | ||||
|     do { \ | ||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ | ||||
|         __catchResult.setExceptionGuard(); \ | ||||
|         __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ | ||||
|         __catchResult.unsetExceptionGuard(); \ | ||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
| #else // CATCH_CONFIG_FAST_COMPILE | ||||
|  | ||||
| #else | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| // In the event of a failure works out if the debugger needs to be invoked | ||||
| // and/or an exception thrown and takes appropriate action. | ||||
| // This needs to be done as a macro so the debugger will stop in the user | ||||
| // source code rather than in Catch library code | ||||
| #define INTERNAL_CATCH_REACT( resultBuilder ) \ | ||||
|     if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ | ||||
|     resultBuilder.react(); | ||||
| #define INTERNAL_CATCH_REACT( handler ) \ | ||||
|     if( handler.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ | ||||
|     handler.reactWithoutDebugBreak(); | ||||
|  | ||||
| #define INTERNAL_CATCH_TRY( capturer ) try | ||||
| #define INTERNAL_CATCH_CATCH( capturer ) catch(...) { capturer.useActiveException(); } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \ | ||||
| #define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ | ||||
|     do { \ | ||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ | ||||
|         try { \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ | ||||
|         INTERNAL_CATCH_TRY( catchAssertionHandler ) { \ | ||||
|             CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ | ||||
|             ( __catchResult <= expr ).endExpression(); \ | ||||
|             catchAssertionHandler.handle( Catch::Decomposer() <= __VA_ARGS__ ); \ | ||||
|             CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ | ||||
|         } \ | ||||
|         catch( ... ) { \ | ||||
|             __catchResult.useActiveException( resultDisposition ); \ | ||||
|         } \ | ||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|     } while( Catch::isTrue( false && static_cast<bool>( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look | ||||
|         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::isTrue( false && static_cast<bool>( !!(__VA_ARGS__) ) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look | ||||
|     // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \ | ||||
|     INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ | ||||
| #define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ | ||||
|     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ | ||||
|     if( Catch::getResultCapture().lastAssertionPassed() ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \ | ||||
|     INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ | ||||
| #define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \ | ||||
|     INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ | ||||
|     if( !Catch::getResultCapture().lastAssertionPassed() ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \ | ||||
| #define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \ | ||||
|     do { \ | ||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ | ||||
|         try { \ | ||||
|             static_cast<void>(expr); \ | ||||
|             __catchResult.captureResult( Catch::ResultWas::Ok ); \ | ||||
|             static_cast<void>(__VA_ARGS__); \ | ||||
|             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \ | ||||
|         } \ | ||||
|         catch( ... ) { \ | ||||
|             __catchResult.useActiveException( resultDisposition ); \ | ||||
|             catchAssertionHandler.useActiveException(); \ | ||||
|         } \ | ||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \ | ||||
| #define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \ | ||||
|     do { \ | ||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \ | ||||
|         if( __catchResult.allowThrows() ) \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ | ||||
|         if( catchAssertionHandler.allowThrows() ) \ | ||||
|             try { \ | ||||
|                 static_cast<void>(expr); \ | ||||
|                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ | ||||
|                 static_cast<void>(__VA_ARGS__); \ | ||||
|                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \ | ||||
|             } \ | ||||
|             catch( ... ) { \ | ||||
|                 __catchResult.captureExpectedException( matcher ); \ | ||||
|                 catchAssertionHandler.handle( Catch::ResultWas::Ok ); \ | ||||
|             } \ | ||||
|         else \ | ||||
|             __catchResult.captureResult( Catch::ResultWas::Ok ); \ | ||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ | ||||
|     do { \ | ||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ | ||||
|         if( __catchResult.allowThrows() ) \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ | ||||
|         if( catchAssertionHandler.allowThrows() ) \ | ||||
|             try { \ | ||||
|                 static_cast<void>(expr); \ | ||||
|                 __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ | ||||
|                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \ | ||||
|             } \ | ||||
|             catch( exceptionType ) { \ | ||||
|                 __catchResult.captureResult( Catch::ResultWas::Ok ); \ | ||||
|             catch( exceptionType const& ) { \ | ||||
|                 catchAssertionHandler.handle( Catch::ResultWas::Ok ); \ | ||||
|             } \ | ||||
|             catch( ... ) { \ | ||||
|                 __catchResult.useActiveException( resultDisposition ); \ | ||||
|                 catchAssertionHandler.useActiveException(); \ | ||||
|             } \ | ||||
|         else \ | ||||
|             __catchResult.captureResult( Catch::ResultWas::Ok ); \ | ||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
|  | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #ifdef CATCH_CONFIG_VARIADIC_MACROS | ||||
|     #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ | ||||
|         do { \ | ||||
|             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ | ||||
|             __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ | ||||
|             __catchResult.captureResult( messageType ); \ | ||||
|             INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|         } while( Catch::alwaysFalse() ) | ||||
| #else | ||||
|     #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \ | ||||
|         do { \ | ||||
|             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ | ||||
|             __catchResult << log + ::Catch::StreamEndStop(); \ | ||||
|             __catchResult.captureResult( messageType ); \ | ||||
|             INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|         } while( Catch::alwaysFalse() ) | ||||
| #endif | ||||
| #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ | ||||
|     do { \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ | ||||
|         catchAssertionHandler.handle( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_INFO( macroName, log ) \ | ||||
|     Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ | ||||
| // Although this is matcher-based, it can be used with just a string | ||||
| #define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ | ||||
|     do { \ | ||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ | ||||
|         try { \ | ||||
|             __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ | ||||
|         } catch( ... ) { \ | ||||
|             __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ | ||||
|         } \ | ||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ | ||||
|         if( catchAssertionHandler.allowThrows() ) \ | ||||
|             try { \ | ||||
|                 static_cast<void>(__VA_ARGS__); \ | ||||
|                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \ | ||||
|             } \ | ||||
|             catch( ... ) { \ | ||||
|                 handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \ | ||||
|             } \ | ||||
|         else \ | ||||
|             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
|  | ||||
| #endif // CATCH_CONFIG_DISABLE | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED | ||||
|   | ||||
							
								
								
									
										24
									
								
								include/internal/catch_capture_matchers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/internal/catch_capture_matchers.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| /* | ||||
|  *  Created by Phil on 9/8/2017. | ||||
|  *  Copyright 2017 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_capture_matchers.h" | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     using StringMatcher = Matchers::Impl::MatcherBase<std::string>; | ||||
|  | ||||
|     // This is the general overload that takes a any string matcher | ||||
|     // There is another overload, in catch_assertinhandler.h/.cpp, that only takes a string and infers | ||||
|     // the Equals matcher (so the header does not mention matchers) | ||||
|     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  ) { | ||||
|         std::string exceptionMessage = Catch::translateActiveException(); | ||||
|         MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString ); | ||||
|         handler.handle( expr ); | ||||
|     } | ||||
|  | ||||
| } // namespace Catch | ||||
							
								
								
									
										88
									
								
								include/internal/catch_capture_matchers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								include/internal/catch_capture_matchers.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| /* | ||||
|  *  Created by Phil on 9/8/2017 | ||||
|  *  Copyright 2017 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_CAPTURE_MATCHERS_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_capture.hpp" | ||||
| #include "catch_matchers.h" | ||||
| #include "catch_matchers_string.h" | ||||
| #include "catch_matchers_vector.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     template<typename ArgT, typename MatcherT> | ||||
|     class MatchExpr : public ITransientExpression { | ||||
|         ArgT const& m_arg; | ||||
|         MatcherT m_matcher; | ||||
|         StringRef m_matcherString; | ||||
|         bool m_result; | ||||
|     public: | ||||
|         MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) | ||||
|         :   m_arg( arg ), | ||||
|             m_matcher( matcher ), | ||||
|             m_matcherString( matcherString ), | ||||
|             m_result( matcher.match( arg ) ) | ||||
|         {} | ||||
|  | ||||
|         auto isBinaryExpression() const -> bool  override { return true; } | ||||
|         auto getResult() const -> bool override { return m_result; } | ||||
|  | ||||
|         void streamReconstructedExpression( std::ostream &os ) const override { | ||||
|             auto matcherAsString = m_matcher.toString(); | ||||
|             os << Catch::Detail::stringify( m_arg ) << ' '; | ||||
|             if( matcherAsString == Detail::unprintableString ) | ||||
|                 os << m_matcherString; | ||||
|             else | ||||
|                 os << matcherAsString; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     using StringMatcher = Matchers::Impl::MatcherBase<std::string>; | ||||
|  | ||||
|     void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString  ); | ||||
|  | ||||
|     template<typename ArgT, typename MatcherT> | ||||
|     auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString  ) -> MatchExpr<ArgT, MatcherT> { | ||||
|         return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString ); | ||||
|     } | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ | ||||
|     do { \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ | ||||
|         INTERNAL_CATCH_TRY( catchAssertionHandler ) { \ | ||||
|             catchAssertionHandler.handle( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \ | ||||
|         } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
|  | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ | ||||
|     do { \ | ||||
|         Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ | ||||
|         if( catchAssertionHandler.allowThrows() ) \ | ||||
|             try { \ | ||||
|                 static_cast<void>(__VA_ARGS__ ); \ | ||||
|                 catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \ | ||||
|             } \ | ||||
|             catch( exceptionType const& ex ) { \ | ||||
|                 catchAssertionHandler.handle( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \ | ||||
|             } \ | ||||
|             catch( ... ) { \ | ||||
|                 catchAssertionHandler.useActiveException(); \ | ||||
|             } \ | ||||
|         else \ | ||||
|             catchAssertionHandler.handle( Catch::ResultWas::Ok ); \ | ||||
|         INTERNAL_CATCH_REACT( catchAssertionHandler ) \ | ||||
|     } while( Catch::alwaysFalse() ) | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_CAPTURE_MATCHERS_HPP_INCLUDED | ||||
| @@ -11,21 +11,27 @@ | ||||
|  | ||||
| // Use Catch's value for console width (store Clara's off to the side, if present) | ||||
| #ifdef CLARA_CONFIG_CONSOLE_WIDTH | ||||
| #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH | ||||
| #undef CLARA_CONFIG_CONSOLE_WIDTH | ||||
| #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH | ||||
| #undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH | ||||
| #endif | ||||
| #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH | ||||
| #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1 | ||||
|  | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic push | ||||
| #pragma clang diagnostic ignored "-Wweak-vtables" | ||||
| #pragma clang diagnostic ignored "-Wexit-time-destructors" | ||||
| #pragma clang diagnostic ignored "-Wshadow" | ||||
| #endif | ||||
|  | ||||
| // Declare Clara inside the Catch namespace | ||||
| #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { | ||||
| #include "../external/clara.h" | ||||
| #undef STITCH_CLARA_OPEN_NAMESPACE | ||||
| #include "../external/clara.hpp" | ||||
|  | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic pop | ||||
| #endif | ||||
|  | ||||
| // Restore Clara's value for console width, if present | ||||
| #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH | ||||
| #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH | ||||
| #define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH | ||||
| #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH | ||||
| #endif | ||||
|  | ||||
|   | ||||
							
								
								
									
										184
									
								
								include/internal/catch_commandline.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								include/internal/catch_commandline.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| /* | ||||
|  *  Created by Phil on 02/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_commandline.h" | ||||
|  | ||||
| #include "catch_string_manip.h" | ||||
|  | ||||
| #include <fstream> | ||||
| #include <ctime> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     clara::Parser makeCommandLineParser( ConfigData& config ) { | ||||
|  | ||||
|         using namespace clara; | ||||
|  | ||||
|         auto const setWarning = [&]( std::string const& warning ) { | ||||
|                 if( warning != "NoAssertions" ) | ||||
|                     return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" ); | ||||
|                 config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions ); | ||||
|                 return ParserResult::ok( ParseResultType::Matched ); | ||||
|             }; | ||||
|         auto const loadTestNamesFromFile = [&]( std::string const& filename ) { | ||||
|                 std::ifstream f( filename.c_str() ); | ||||
|                 if( !f.is_open() ) | ||||
|                     return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" ); | ||||
|  | ||||
|                 std::string line; | ||||
|                 while( std::getline( f, line ) ) { | ||||
|                     line = trim(line); | ||||
|                     if( !line.empty() && !startsWith( line, '#' ) ) { | ||||
|                         if( !startsWith( line, '"' ) ) | ||||
|                             line = '"' + line + '"'; | ||||
|                         config.testsOrTags.push_back( line + ',' ); | ||||
|                     } | ||||
|                 } | ||||
|                 return ParserResult::ok( ParseResultType::Matched ); | ||||
|             }; | ||||
|         auto const setTestOrder = [&]( std::string const& order ) { | ||||
|                 if( startsWith( "declared", order ) ) | ||||
|                     config.runOrder = RunTests::InDeclarationOrder; | ||||
|                 else if( startsWith( "lexical", order ) ) | ||||
|                     config.runOrder = RunTests::InLexicographicalOrder; | ||||
|                 else if( startsWith( "random", order ) ) | ||||
|                     config.runOrder = RunTests::InRandomOrder; | ||||
|                 else | ||||
|                     return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" ); | ||||
|                 return ParserResult::ok( ParseResultType::Matched ); | ||||
|             }; | ||||
|         auto const setRngSeed = [&]( std::string const& seed ) { | ||||
|                 if( seed != "time" ) | ||||
|                     return clara::detail::convertInto( seed, config.rngSeed ); | ||||
|                 config.rngSeed = static_cast<unsigned int>( std::time(nullptr) ); | ||||
|                 return ParserResult::ok( ParseResultType::Matched ); | ||||
|             }; | ||||
|         auto const setColourUsage = [&]( std::string const& useColour ) { | ||||
|                     auto mode = toLower( useColour ); | ||||
|  | ||||
|                     if( mode == "yes" ) | ||||
|                         config.useColour = UseColour::Yes; | ||||
|                     else if( mode == "no" ) | ||||
|                         config.useColour = UseColour::No; | ||||
|                     else if( mode == "auto" ) | ||||
|                         config.useColour = UseColour::Auto; | ||||
|                     else | ||||
|                         return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" ); | ||||
|                 return ParserResult::ok( ParseResultType::Matched ); | ||||
|             }; | ||||
|         auto const setWaitForKeypress = [&]( std::string const& keypress ) { | ||||
|                 auto keypressLc = toLower( keypress ); | ||||
|                 if( keypressLc == "start" ) | ||||
|                     config.waitForKeypress = WaitForKeypress::BeforeStart; | ||||
|                 else if( keypressLc == "exit" ) | ||||
|                     config.waitForKeypress = WaitForKeypress::BeforeExit; | ||||
|                 else if( keypressLc == "both" ) | ||||
|                     config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; | ||||
|                 else | ||||
|                     return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); | ||||
|             return ParserResult::ok( ParseResultType::Matched ); | ||||
|             }; | ||||
|         auto const setVerbosity = [&]( std::string const& verbosity ) { | ||||
|             auto lcVerbosity = toLower( verbosity ); | ||||
|             if( lcVerbosity == "quiet" ) | ||||
|                 config.verbosity = Verbosity::Quiet; | ||||
|             else if( lcVerbosity == "normal" ) | ||||
|                 config.verbosity = Verbosity::Normal; | ||||
|             else if( lcVerbosity == "high" ) | ||||
|                 config.verbosity = Verbosity::High; | ||||
|             else | ||||
|                 return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); | ||||
|             return ParserResult::ok( ParseResultType::Matched ); | ||||
|         }; | ||||
|  | ||||
|         auto cli | ||||
|             = ExeName( config.processName ) | ||||
|             | Help( config.showHelp ) | ||||
|             | Opt( config.listTests ) | ||||
|                 ["-l"]["--list-tests"] | ||||
|                 ( "list all/matching test cases" ) | ||||
|             | Opt( config.listTags ) | ||||
|                 ["-t"]["--list-tags"] | ||||
|                 ( "list all/matching tags" ) | ||||
|             | Opt( config.showSuccessfulTests ) | ||||
|                 ["-s"]["--success"] | ||||
|                 ( "include successful tests in output" ) | ||||
|             | Opt( config.shouldDebugBreak ) | ||||
|                 ["-b"]["--break"] | ||||
|                 ( "break into debugger on failure" ) | ||||
|             | Opt( config.noThrow ) | ||||
|                 ["-e"]["--nothrow"] | ||||
|                 ( "skip exception tests" ) | ||||
|             | Opt( config.showInvisibles ) | ||||
|                 ["-i"]["--invisibles"] | ||||
|                 ( "show invisibles (tabs, newlines)" ) | ||||
|             | Opt( config.outputFilename, "filename" ) | ||||
|                 ["-o"]["--out"] | ||||
|                 ( "output filename" ) | ||||
|             | Opt( config.reporterNames, "name" ) | ||||
|                 ["-r"]["--reporter"] | ||||
|                 ( "reporter to use (defaults to console)" ) | ||||
|             | Opt( config.name, "name" ) | ||||
|                 ["-n"]["--name"] | ||||
|                 ( "suite name" ) | ||||
|             | Opt( [&]( bool ){ config.abortAfter = 1; } ) | ||||
|                 ["-a"]["--abort"] | ||||
|                 ( "abort at first failure" ) | ||||
|             | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" ) | ||||
|                 ["-x"]["--abortx"] | ||||
|                 ( "abort after x failures" ) | ||||
|             | Opt( setWarning, "warning name" ) | ||||
|                 ["-w"]["--warn"] | ||||
|                 ( "enable warnings" ) | ||||
|             | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) | ||||
|                 ["-d"]["--durations"] | ||||
|                 ( "show test durations" ) | ||||
|             | Opt( loadTestNamesFromFile, "filename" ) | ||||
|                 ["-f"]["--input-file"] | ||||
|                 ( "load test names to run from a file" ) | ||||
|             | Opt( config.filenamesAsTags ) | ||||
|                 ["-#"]["--filenames-as-tags"] | ||||
|                 ( "adds a tag for the filename" ) | ||||
|             | Opt( config.sectionsToRun, "section name" ) | ||||
|                 ["-c"]["--section"] | ||||
|                 ( "specify section to run" ) | ||||
|             | Opt( setVerbosity, "quiet|normal|high" ) | ||||
|                 ["-v"]["--verbosity"] | ||||
|                 ( "set output verbosity" ) | ||||
|             | Opt( config.listTestNamesOnly ) | ||||
|                 ["--list-test-names-only"] | ||||
|                 ( "list all/matching test cases names only" ) | ||||
|             | Opt( config.listReporters ) | ||||
|                 ["--list-reporters"] | ||||
|                 ( "list all reporters" ) | ||||
|             | Opt( setTestOrder, "decl|lex|rand" ) | ||||
|                 ["--order"] | ||||
|                 ( "test case order (defaults to decl)" ) | ||||
|             | Opt( setRngSeed, "'time'|number" ) | ||||
|                 ["--rng-seed"] | ||||
|                 ( "set a specific seed for random numbers" ) | ||||
|             | Opt( setColourUsage, "yes|no" ) | ||||
|                 ["--use-colour"] | ||||
|                 ( "should output be colourised" ) | ||||
|             | Opt( config.libIdentify ) | ||||
|                 ["--libidentify"] | ||||
|                 ( "report name and version according to libidentify standard" ) | ||||
|             | Opt( setWaitForKeypress, "start|exit|both" ) | ||||
|                 ["--wait-for-keypress"] | ||||
|                 ( "waits for a keypress before exiting" ) | ||||
|             | Opt( config.benchmarkResolutionMultiple, "multiplier" ) | ||||
|                 ["--benchmark-resolution-multiple"] | ||||
|                 ( "multiple of clock resolution to run benchmarks" ) | ||||
|  | ||||
|             | Arg( config.testsOrTags, "test name|pattern|tags" ) | ||||
|                 ( "which test or tests to use" ); | ||||
|  | ||||
|         return cli; | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
							
								
								
									
										20
									
								
								include/internal/catch_commandline.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								include/internal/catch_commandline.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| /* | ||||
|  *  Created by Phil on 02/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_config.hpp" | ||||
| #include "catch_clara.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     clara::Parser makeCommandLineParser( ConfigData& config ); | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED | ||||
							
								
								
									
										52
									
								
								include/internal/catch_common.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								include/internal/catch_common.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| /* | ||||
|  *  Created by Phil on 27/11/2013. | ||||
|  *  Copyright 2013 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_common.h" | ||||
| #include "catch_context.h" | ||||
| #include "catch_interfaces_config.h" | ||||
|  | ||||
| #include <cstring> | ||||
| #include <ostream> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) noexcept | ||||
|     :   file( _file ), | ||||
|         line( _line ) | ||||
|     {} | ||||
|     bool SourceLineInfo::empty() const noexcept { | ||||
|         return file[0] == '\0'; | ||||
|     } | ||||
|     bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept { | ||||
|         return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); | ||||
|     } | ||||
|     bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept { | ||||
|         return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); | ||||
|     } | ||||
|  | ||||
|     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { | ||||
| #ifndef __GNUG__ | ||||
|         os << info.file << '(' << info.line << ')'; | ||||
| #else | ||||
|         os << info.file << ':' << info.line; | ||||
| #endif | ||||
|         return os; | ||||
|     } | ||||
|  | ||||
|     bool isTrue( bool value ){ return value; } | ||||
|     bool alwaysTrue() { return true; } | ||||
|     bool alwaysFalse() { return false; } | ||||
|  | ||||
|     std::string StreamEndStop::operator+() const { | ||||
|         return std::string(); | ||||
|     } | ||||
|  | ||||
|     NonCopyable::NonCopyable() = default; | ||||
|     NonCopyable::~NonCopyable() = default; | ||||
|  | ||||
| } | ||||
| @@ -18,95 +18,41 @@ | ||||
| #  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) | ||||
| #endif | ||||
|  | ||||
| #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr | ||||
| #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) | ||||
|  | ||||
| #include <sstream> | ||||
| #include <algorithm> | ||||
| #include <iosfwd> | ||||
| #include <string> | ||||
| #include <cstdint> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct IConfig; | ||||
|  | ||||
|     struct CaseSensitive { enum Choice { | ||||
|         Yes, | ||||
|         No | ||||
|     }; }; | ||||
|  | ||||
|     class NonCopyable { | ||||
| #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|         NonCopyable( NonCopyable const& )              = delete; | ||||
|         NonCopyable( NonCopyable && )                  = delete; | ||||
|         NonCopyable& operator = ( NonCopyable const& ) = delete; | ||||
|         NonCopyable& operator = ( NonCopyable && )     = delete; | ||||
| #else | ||||
|         NonCopyable( NonCopyable const& info ); | ||||
|         NonCopyable& operator = ( NonCopyable const& ); | ||||
| #endif | ||||
|  | ||||
|     protected: | ||||
|         NonCopyable() {} | ||||
|         NonCopyable(); | ||||
|         virtual ~NonCopyable(); | ||||
|     }; | ||||
|  | ||||
|     class SafeBool { | ||||
|     public: | ||||
|         typedef void (SafeBool::*type)() const; | ||||
|  | ||||
|         static type makeSafe( bool value ) { | ||||
|             return value ? &SafeBool::trueValue : 0; | ||||
|         } | ||||
|     private: | ||||
|         void trueValue() const {} | ||||
|     }; | ||||
|  | ||||
|     template<typename ContainerT> | ||||
|     void deleteAll( ContainerT& container ) { | ||||
|         typename ContainerT::const_iterator it = container.begin(); | ||||
|         typename ContainerT::const_iterator itEnd = container.end(); | ||||
|         for(; it != itEnd; ++it ) | ||||
|             delete *it; | ||||
|     } | ||||
|     template<typename AssociativeContainerT> | ||||
|     void deleteAllValues( AssociativeContainerT& container ) { | ||||
|         typename AssociativeContainerT::const_iterator it = container.begin(); | ||||
|         typename AssociativeContainerT::const_iterator itEnd = container.end(); | ||||
|         for(; it != itEnd; ++it ) | ||||
|             delete it->second; | ||||
|     } | ||||
|  | ||||
|     bool startsWith( std::string const& s, std::string const& prefix ); | ||||
|     bool startsWith( std::string const& s, char prefix ); | ||||
|     bool endsWith( std::string const& s, std::string const& suffix ); | ||||
|     bool endsWith( std::string const& s, char suffix ); | ||||
|     bool contains( std::string const& s, std::string const& infix ); | ||||
|     void toLowerInPlace( std::string& s ); | ||||
|     std::string toLower( std::string const& s ); | ||||
|     std::string trim( std::string const& str ); | ||||
|     bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); | ||||
|  | ||||
|     struct pluralise { | ||||
|         pluralise( std::size_t count, std::string const& label ); | ||||
|  | ||||
|         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); | ||||
|  | ||||
|         std::size_t m_count; | ||||
|         std::string m_label; | ||||
|     }; | ||||
|  | ||||
|     struct SourceLineInfo { | ||||
|  | ||||
|         SourceLineInfo(); | ||||
|         SourceLineInfo( char const* _file, std::size_t _line ); | ||||
| #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|         SourceLineInfo(SourceLineInfo const& other)          = default; | ||||
|         SourceLineInfo() = delete; | ||||
|         SourceLineInfo( char const* _file, std::size_t _line ) noexcept; | ||||
|  | ||||
|         SourceLineInfo( SourceLineInfo const& other )        = default; | ||||
|         SourceLineInfo( SourceLineInfo && )                  = default; | ||||
|         SourceLineInfo& operator = ( SourceLineInfo const& ) = default; | ||||
|         SourceLineInfo& operator = ( SourceLineInfo && )     = default; | ||||
| #  endif | ||||
|         bool empty() const; | ||||
|         bool operator == ( SourceLineInfo const& other ) const; | ||||
|         bool operator < ( SourceLineInfo const& other ) const; | ||||
|  | ||||
|         bool empty() const noexcept; | ||||
|         bool operator == ( SourceLineInfo const& other ) const noexcept; | ||||
|         bool operator < ( SourceLineInfo const& other ) const noexcept; | ||||
|  | ||||
|         char const* file; | ||||
|         std::size_t line; | ||||
| @@ -115,23 +61,16 @@ namespace Catch { | ||||
|     std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); | ||||
|  | ||||
|     // This is just here to avoid compiler warnings with macro constants and boolean literals | ||||
|     inline bool isTrue( bool value ){ return value; } | ||||
|     inline bool alwaysTrue() { return true; } | ||||
|     inline bool alwaysFalse() { return false; } | ||||
|  | ||||
|     void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); | ||||
|  | ||||
|     void seedRng( IConfig const& config ); | ||||
|     unsigned int rngSeed(); | ||||
|     bool isTrue( bool value ); | ||||
|     bool alwaysTrue(); | ||||
|     bool alwaysFalse(); | ||||
|  | ||||
|     // Use this in variadic streaming macros to allow | ||||
|     //    >> +StreamEndStop | ||||
|     // as well as | ||||
|     //    >> stuff +StreamEndStop | ||||
|     struct StreamEndStop { | ||||
|         std::string operator+() { | ||||
|             return std::string(); | ||||
|         } | ||||
|         std::string operator+() const; | ||||
|     }; | ||||
|     template<typename T> | ||||
|     T const& operator + ( T const& value, StreamEndStop ) { | ||||
| @@ -139,8 +78,8 @@ namespace Catch { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) | ||||
| #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); | ||||
| #define CATCH_INTERNAL_LINEINFO \ | ||||
|     ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED | ||||
|  | ||||
|   | ||||
| @@ -8,23 +8,9 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED | ||||
|  | ||||
| // Detect a number of compiler features - mostly C++11/14 conformance - by compiler | ||||
| // Detect a number of compiler features - by compiler | ||||
| // The following features are defined: | ||||
| // | ||||
| // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? | ||||
| // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? | ||||
| // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods | ||||
| // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? | ||||
| // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported | ||||
| // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? | ||||
| // CATCH_CONFIG_CPP11_OVERRIDE : is override supported? | ||||
| // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) | ||||
| // CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? | ||||
| // CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? | ||||
|  | ||||
| // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? | ||||
|  | ||||
| // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? | ||||
| // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? | ||||
| // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? | ||||
| // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? | ||||
| @@ -34,18 +20,13 @@ | ||||
| // **************** | ||||
|  | ||||
| // In general each macro has a _NO_<feature name> form | ||||
| // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. | ||||
| // (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. | ||||
| // Many features, at point of detection, define an _INTERNAL_ macro, so they | ||||
| // can be combined, en-mass, with the _NO_ forms later. | ||||
|  | ||||
| // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  | ||||
| #  if __cplusplus >= 201103L | ||||
| #    define CATCH_CPP11_OR_GREATER | ||||
| #  endif | ||||
|  | ||||
| #  if __cplusplus >= 201402L | ||||
| #    define CATCH_CPP14_OR_GREATER | ||||
| #  endif | ||||
| @@ -54,19 +35,11 @@ | ||||
|  | ||||
| #ifdef __clang__ | ||||
|  | ||||
| #  if __has_feature(cxx_nullptr) | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR | ||||
| #  endif | ||||
|  | ||||
| #  if __has_feature(cxx_noexcept) | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT | ||||
| #  endif | ||||
|  | ||||
| #   if defined(CATCH_CPP11_OR_GREATER) | ||||
| #       define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ | ||||
| #       define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ | ||||
|             _Pragma( "clang diagnostic push" ) \ | ||||
|             _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) | ||||
| #       define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ | ||||
|             _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ | ||||
|             _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") | ||||
| #       define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ | ||||
|             _Pragma( "clang diagnostic pop" ) | ||||
|  | ||||
| #       define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ | ||||
| @@ -74,7 +47,6 @@ | ||||
|             _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) | ||||
| #       define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ | ||||
|             _Pragma( "clang diagnostic pop" ) | ||||
| #   endif | ||||
|  | ||||
| #endif // __clang__ | ||||
|  | ||||
| @@ -104,174 +76,34 @@ | ||||
|  | ||||
| #endif // __CYGWIN__ | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Borland | ||||
| #ifdef __BORLANDC__ | ||||
|  | ||||
|  | ||||
| #endif // __BORLANDC__ | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // EDG | ||||
| #ifdef __EDG_VERSION__ | ||||
|  | ||||
|  | ||||
| #endif // __EDG_VERSION__ | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Digital Mars | ||||
| #ifdef __DMC__ | ||||
|  | ||||
|  | ||||
| #endif // __DMC__ | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // GCC | ||||
| #ifdef __GNUC__ | ||||
|  | ||||
| #   if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) | ||||
| #       define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR | ||||
| #   endif | ||||
|  | ||||
|  | ||||
| // - otherwise more recent versions define __cplusplus >= 201103L | ||||
| // and will get picked up below | ||||
|  | ||||
|  | ||||
| #endif // __GNUC__ | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Visual C++ | ||||
| #ifdef _MSC_VER | ||||
|  | ||||
| #define CATCH_INTERNAL_CONFIG_WINDOWS_SEH | ||||
|  | ||||
| #if (_MSC_VER >= 1600) | ||||
| #   define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR | ||||
| #   define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR | ||||
| #endif | ||||
|  | ||||
| #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) | ||||
| #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT | ||||
| #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS | ||||
| #define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE | ||||
| #define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS | ||||
| #endif | ||||
| // Universal Windows platform does not support SEH | ||||
| // Or console colours (or console at all...) | ||||
| #  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) | ||||
| #    define CATCH_CONFIG_COLOUR_NONE | ||||
| #  else | ||||
| #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH | ||||
| #  endif | ||||
|  | ||||
| #endif // _MSC_VER | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| // Use variadic macros if the compiler supports them | ||||
| #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ | ||||
|     ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ | ||||
|     ( defined __GNUC__ && __GNUC__ >= 3 ) || \ | ||||
|     ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) | ||||
|  | ||||
| #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS | ||||
|  | ||||
| #endif | ||||
|  | ||||
| // Use __COUNTER__ if the compiler supports it | ||||
| #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ | ||||
|     ( defined __GNUC__  && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \ | ||||
|     ( defined __clang__ && __clang_major__ >= 3 ) | ||||
|  | ||||
| // Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former, | ||||
| // because __COUNTER__ is not properly handled by it. | ||||
| // This does not affect compilation | ||||
| #if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L ) | ||||
| // Use of __COUNTER__ is suppressed during code analysis in | ||||
| // CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly | ||||
| // handled by it. | ||||
| // Otherwise all supported compilers support COUNTER macro, | ||||
| // but user still might want to turn it off | ||||
| #if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) | ||||
|     #define CATCH_INTERNAL_CONFIG_COUNTER | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // C++ language feature support | ||||
|  | ||||
| // catch all support for C++11 | ||||
| #if defined(CATCH_CPP11_OR_GREATER) | ||||
|  | ||||
| #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR | ||||
| #  endif | ||||
|  | ||||
| #  ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT | ||||
| #  endif | ||||
|  | ||||
| #  ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS | ||||
| #  endif | ||||
|  | ||||
| #  ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM | ||||
| #  endif | ||||
|  | ||||
| #  ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_TUPLE | ||||
| #  endif | ||||
|  | ||||
| #  ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS | ||||
| #    define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS | ||||
| #  endif | ||||
|  | ||||
| #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG | ||||
| #  endif | ||||
|  | ||||
| #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE | ||||
| #  endif | ||||
| #  if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) | ||||
| #    define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR | ||||
| #  endif | ||||
| # if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) | ||||
| #   define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE | ||||
| #  endif | ||||
| # if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) | ||||
| #  define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS | ||||
| # endif | ||||
|  | ||||
| #endif // __cplusplus >= 201103L | ||||
|  | ||||
| // Now set the actual defines based on the above + anything the user has configured | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_NULLPTR | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_NOEXCEPT | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_IS_ENUM | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_TUPLE | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) | ||||
| #   define CATCH_CONFIG_VARIADIC_MACROS | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_LONG_LONG | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_OVERRIDE | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_UNIQUE_PTR | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) | ||||
| #   define CATCH_CONFIG_COUNTER | ||||
| #endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #   define CATCH_CONFIG_CPP11_SHUFFLE | ||||
| #endif | ||||
| # if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) | ||||
| #  define CATCH_CONFIG_CPP11_TYPE_TRAITS | ||||
| # endif | ||||
| #if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) | ||||
| #   define CATCH_CONFIG_WINDOWS_SEH | ||||
| #endif | ||||
| @@ -284,40 +116,11 @@ | ||||
| #   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS | ||||
| #   define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS | ||||
| #endif | ||||
| #if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS) | ||||
| #   define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS | ||||
| #   define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS | ||||
| #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) | ||||
| #   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS | ||||
| #   define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS | ||||
| #endif | ||||
|  | ||||
| // noexcept support: | ||||
| #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) | ||||
| #  define CATCH_NOEXCEPT noexcept | ||||
| #  define CATCH_NOEXCEPT_IS(x) noexcept(x) | ||||
| #else | ||||
| #  define CATCH_NOEXCEPT throw() | ||||
| #  define CATCH_NOEXCEPT_IS(x) | ||||
| #endif | ||||
|  | ||||
| // nullptr support | ||||
| #ifdef CATCH_CONFIG_CPP11_NULLPTR | ||||
| #   define CATCH_NULL nullptr | ||||
| #else | ||||
| #   define CATCH_NULL NULL | ||||
| #endif | ||||
|  | ||||
| // override support | ||||
| #ifdef CATCH_CONFIG_CPP11_OVERRIDE | ||||
| #   define CATCH_OVERRIDE override | ||||
| #else | ||||
| #   define CATCH_OVERRIDE | ||||
| #endif | ||||
|  | ||||
| // unique_ptr support | ||||
| #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR | ||||
| #   define CATCH_AUTO_PTR( T ) std::unique_ptr<T> | ||||
| #else | ||||
| #   define CATCH_AUTO_PTR( T ) std::auto_ptr<T> | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED | ||||
|  | ||||
|   | ||||
							
								
								
									
										73
									
								
								include/internal/catch_config.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								include/internal/catch_config.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /* | ||||
|  *  Created by Martin on 19/07/2017. | ||||
|  * | ||||
|  *  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_config.hpp" | ||||
| #include "catch_enforce.h" | ||||
| #include "catch_stream.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     Config::Config( ConfigData const& data ) | ||||
|     :   m_data( data ), | ||||
|         m_stream( openStream() ) | ||||
|     { | ||||
|         if( !data.testsOrTags.empty() ) { | ||||
|             TestSpecParser parser( ITagAliasRegistry::get() ); | ||||
|             for( auto const& testOrTags : data.testsOrTags ) | ||||
|                 parser.parse( testOrTags ); | ||||
|             m_testSpec = parser.testSpec(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     std::string const& Config::getFilename() const { | ||||
|         return m_data.outputFilename ; | ||||
|     } | ||||
|  | ||||
|     bool Config::listTests() const          { return m_data.listTests; } | ||||
|     bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; } | ||||
|     bool Config::listTags() const           { return m_data.listTags; } | ||||
|     bool Config::listReporters() const      { return m_data.listReporters; } | ||||
|  | ||||
|     std::string Config::getProcessName() const { return m_data.processName; } | ||||
|  | ||||
|     std::vector<std::string> const& Config::getReporterNames() const { return m_data.reporterNames; } | ||||
|     std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } | ||||
|  | ||||
|     TestSpec const& Config::testSpec() const { return m_testSpec; } | ||||
|  | ||||
|     bool Config::showHelp() const { return m_data.showHelp; } | ||||
|  | ||||
|     // IConfig interface | ||||
|     bool Config::allowThrows() const                   { return !m_data.noThrow; } | ||||
|     std::ostream& Config::stream() const               { return m_stream->stream(); } | ||||
|     std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; } | ||||
|     bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; } | ||||
|     bool Config::warnAboutMissingAssertions() const    { return m_data.warnings & WarnAbout::NoAssertions; } | ||||
|     ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } | ||||
|     RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; } | ||||
|     unsigned int Config::rngSeed() const               { return m_data.rngSeed; } | ||||
|     int Config::benchmarkResolutionMultiple() const    { return m_data.benchmarkResolutionMultiple; } | ||||
|     UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; } | ||||
|     bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; } | ||||
|     int Config::abortAfter() const                     { return m_data.abortAfter; } | ||||
|     bool Config::showInvisibles() const                { return m_data.showInvisibles; } | ||||
|     Verbosity Config::verbosity() const                { return m_data.verbosity; } | ||||
|  | ||||
|     IStream const* Config::openStream() { | ||||
|         if( m_data.outputFilename.empty() ) | ||||
|             return new CoutStream(); | ||||
|         else if( m_data.outputFilename[0] == '%' ) { | ||||
|             if( m_data.outputFilename == "%debug" ) | ||||
|                 return new DebugOutStream(); | ||||
|             else | ||||
|                 CATCH_ERROR( "Unrecognised stream: '" << m_data.outputFilename << "'" ); | ||||
|         } | ||||
|         else | ||||
|             return new FileStream( m_data.outputFilename ); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
| @@ -8,15 +8,15 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_test_spec_parser.hpp" | ||||
| #include "catch_context.h" | ||||
| #include "catch_test_spec_parser.h" | ||||
| #include "catch_interfaces_config.h" | ||||
|  | ||||
| // Libstdc++ doesn't like incomplete classes for unique_ptr | ||||
| #include "catch_stream.h" | ||||
|  | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <stdexcept> | ||||
|  | ||||
| #ifndef CATCH_CONFIG_CONSOLE_WIDTH | ||||
| #define CATCH_CONFIG_CONSOLE_WIDTH 80 | ||||
| @@ -24,54 +24,32 @@ | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct IStream; | ||||
|  | ||||
|     struct ConfigData { | ||||
|         bool listTests = false; | ||||
|         bool listTags = false; | ||||
|         bool listReporters = false; | ||||
|         bool listTestNamesOnly = false; | ||||
|  | ||||
|         ConfigData() | ||||
|         :   listTests( false ), | ||||
|             listTags( false ), | ||||
|             listReporters( false ), | ||||
|             listTestNamesOnly( false ), | ||||
|             listExtraInfo( false ), | ||||
|             showSuccessfulTests( false ), | ||||
|             shouldDebugBreak( false ), | ||||
|             noThrow( false ), | ||||
|             showHelp( false ), | ||||
|             showInvisibles( false ), | ||||
|             filenamesAsTags( false ), | ||||
|             libIdentify( false ), | ||||
|             abortAfter( -1 ), | ||||
|             rngSeed( 0 ), | ||||
|             verbosity( Verbosity::Normal ), | ||||
|             warnings( WarnAbout::Nothing ), | ||||
|             showDurations( ShowDurations::DefaultForReporter ), | ||||
|             runOrder( RunTests::InDeclarationOrder ), | ||||
|             useColour( UseColour::Auto ), | ||||
|             waitForKeypress( WaitForKeypress::Never ) | ||||
|         {} | ||||
|         bool showSuccessfulTests = false; | ||||
|         bool shouldDebugBreak = false; | ||||
|         bool noThrow = false; | ||||
|         bool showHelp = false; | ||||
|         bool showInvisibles = false; | ||||
|         bool filenamesAsTags = false; | ||||
|         bool libIdentify = false; | ||||
|  | ||||
|         bool listTests; | ||||
|         bool listTags; | ||||
|         bool listReporters; | ||||
|         bool listTestNamesOnly; | ||||
|         bool listExtraInfo; | ||||
|         int abortAfter = -1; | ||||
|         unsigned int rngSeed = 0; | ||||
|         int benchmarkResolutionMultiple = 100; | ||||
|  | ||||
|         bool showSuccessfulTests; | ||||
|         bool shouldDebugBreak; | ||||
|         bool noThrow; | ||||
|         bool showHelp; | ||||
|         bool showInvisibles; | ||||
|         bool filenamesAsTags; | ||||
|         bool libIdentify; | ||||
|  | ||||
|         int abortAfter; | ||||
|         unsigned int rngSeed; | ||||
|  | ||||
|         Verbosity::Level verbosity; | ||||
|         WarnAbout::What warnings; | ||||
|         ShowDurations::OrNot showDurations; | ||||
|         RunTests::InWhatOrder runOrder; | ||||
|         UseColour::YesOrNo useColour; | ||||
|         WaitForKeypress::When waitForKeypress; | ||||
|         Verbosity verbosity = Verbosity::Normal; | ||||
|         WarnAbout::What warnings = WarnAbout::Nothing; | ||||
|         ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; | ||||
|         RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; | ||||
|         UseColour::YesOrNo useColour = UseColour::Auto; | ||||
|         WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; | ||||
|  | ||||
|         std::string outputFilename; | ||||
|         std::string name; | ||||
| @@ -83,80 +61,51 @@ namespace Catch { | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     class Config : public SharedImpl<IConfig> { | ||||
|     private: | ||||
|         Config( Config const& other ); | ||||
|         Config& operator = ( Config const& other ); | ||||
|         virtual void dummy(); | ||||
|     class Config : public IConfig { | ||||
|     public: | ||||
|  | ||||
|         Config() | ||||
|         {} | ||||
|         Config() = default; | ||||
|         Config( ConfigData const& data ); | ||||
|         virtual ~Config() = default; | ||||
|  | ||||
|         Config( ConfigData const& data ) | ||||
|         :   m_data( data ), | ||||
|             m_stream( openStream() ) | ||||
|         { | ||||
|             if( !data.testsOrTags.empty() ) { | ||||
|                 TestSpecParser parser( ITagAliasRegistry::get() ); | ||||
|                 for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) | ||||
|                     parser.parse( data.testsOrTags[i] ); | ||||
|                 m_testSpec = parser.testSpec(); | ||||
|             } | ||||
|         } | ||||
|         std::string const& getFilename() const; | ||||
|  | ||||
|         virtual ~Config() {} | ||||
|         bool listTests() const; | ||||
|         bool listTestNamesOnly() const; | ||||
|         bool listTags() const; | ||||
|         bool listReporters() const; | ||||
|  | ||||
|         std::string const& getFilename() const { | ||||
|             return m_data.outputFilename ; | ||||
|         } | ||||
|         std::string getProcessName() const; | ||||
|  | ||||
|         bool listTests() const { return m_data.listTests; } | ||||
|         bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } | ||||
|         bool listTags() const { return m_data.listTags; } | ||||
|         bool listReporters() const { return m_data.listReporters; } | ||||
|         bool listExtraInfo() const { return m_data.listExtraInfo; } | ||||
|         std::vector<std::string> const& getReporterNames() const; | ||||
|         std::vector<std::string> const& getSectionsToRun() const override; | ||||
|  | ||||
|         std::string getProcessName() const { return m_data.processName; } | ||||
|         virtual TestSpec const& testSpec() const override; | ||||
|  | ||||
|         std::vector<std::string> const& getReporterNames() const { return m_data.reporterNames; } | ||||
|         std::vector<std::string> const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; } | ||||
|  | ||||
|         virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; } | ||||
|  | ||||
|         bool showHelp() const { return m_data.showHelp; } | ||||
|         bool showHelp() const; | ||||
|  | ||||
|         // IConfig interface | ||||
|         virtual bool allowThrows() const CATCH_OVERRIDE                 { return !m_data.noThrow; } | ||||
|         virtual std::ostream& stream() const CATCH_OVERRIDE             { return m_stream->stream(); } | ||||
|         virtual std::string name() const CATCH_OVERRIDE                 { return m_data.name.empty() ? m_data.processName : m_data.name; } | ||||
|         virtual bool includeSuccessfulResults() const CATCH_OVERRIDE    { return m_data.showSuccessfulTests; } | ||||
|         virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE  { return m_data.warnings & WarnAbout::NoAssertions; } | ||||
|         virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; } | ||||
|         virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE   { return m_data.runOrder; } | ||||
|         virtual unsigned int rngSeed() const CATCH_OVERRIDE             { return m_data.rngSeed; } | ||||
|         virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE     { return m_data.useColour; } | ||||
|         virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; } | ||||
|         virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; } | ||||
|         virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; } | ||||
|         bool allowThrows() const override; | ||||
|         std::ostream& stream() const override; | ||||
|         std::string name() const override; | ||||
|         bool includeSuccessfulResults() const override; | ||||
|         bool warnAboutMissingAssertions() const override; | ||||
|         ShowDurations::OrNot showDurations() const override; | ||||
|         RunTests::InWhatOrder runOrder() const override; | ||||
|         unsigned int rngSeed() const override; | ||||
|         int benchmarkResolutionMultiple() const override; | ||||
|         UseColour::YesOrNo useColour() const override; | ||||
|         bool shouldDebugBreak() const override; | ||||
|         int abortAfter() const override; | ||||
|         bool showInvisibles() const override; | ||||
|         Verbosity verbosity() const override; | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         IStream const* openStream() { | ||||
|             if( m_data.outputFilename.empty() ) | ||||
|                 return new CoutStream(); | ||||
|             else if( m_data.outputFilename[0] == '%' ) { | ||||
|                 if( m_data.outputFilename == "%debug" ) | ||||
|                     return new DebugOutStream(); | ||||
|                 else | ||||
|                     throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); | ||||
|             } | ||||
|             else | ||||
|                 return new FileStream( m_data.outputFilename ); | ||||
|         } | ||||
|         IStream const* openStream(); | ||||
|         ConfigData m_data; | ||||
|  | ||||
|         CATCH_AUTO_PTR( IStream const ) m_stream; | ||||
|         std::unique_ptr<IStream const> m_stream; | ||||
|         TestSpec m_testSpec; | ||||
|     }; | ||||
|  | ||||
|   | ||||
| @@ -5,17 +5,29 @@ | ||||
|  *  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_CONSOLE_COLOUR_IMPL_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED | ||||
| 
 | ||||
| #include "catch_console_colour.hpp" | ||||
| #include "catch_errno_guard.hpp" | ||||
| 
 | ||||
| #if defined(__clang__) | ||||
| #    pragma clang diagnostic push | ||||
| #    pragma clang diagnostic ignored "-Wexit-time-destructors" | ||||
| #endif | ||||
|   | ||||
|   | ||||
| #include "catch_console_colour.h" | ||||
| #include "catch_enforce.h" | ||||
| #include "catch_errno_guard.h" | ||||
| #include "catch_interfaces_config.h" | ||||
| #include "catch_stream.h" | ||||
| #include "catch_context.h" | ||||
| #include "catch_platform.h" | ||||
| #include "catch_debugger.h" | ||||
| #include "catch_windows_h_proxy.h" | ||||
| 
 | ||||
| namespace Catch { | ||||
|     namespace { | ||||
| 
 | ||||
|         struct IColourImpl { | ||||
|             virtual ~IColourImpl() {} | ||||
|             virtual ~IColourImpl() = default; | ||||
|             virtual void use( Colour::Code _colourCode ) = 0; | ||||
|         }; | ||||
| 
 | ||||
| @@ -42,8 +54,6 @@ namespace Catch { | ||||
| 
 | ||||
| #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
 | ||||
| 
 | ||||
| #include "catch_windows_h_proxy.h" | ||||
| 
 | ||||
| namespace Catch { | ||||
| namespace { | ||||
| 
 | ||||
| @@ -57,7 +67,7 @@ namespace { | ||||
|             originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); | ||||
|         } | ||||
| 
 | ||||
|         virtual void use( Colour::Code _colourCode ) { | ||||
|         virtual void use( Colour::Code _colourCode ) override { | ||||
|             switch( _colourCode ) { | ||||
|                 case Colour::None:      return setTextAttribute( originalForegroundAttributes ); | ||||
|                 case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); | ||||
| @@ -73,7 +83,7 @@ namespace { | ||||
|                 case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); | ||||
|                 case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); | ||||
| 
 | ||||
|                 case Colour::Bright: throw std::logic_error( "not a colour" ); | ||||
|                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @@ -89,14 +99,12 @@ namespace { | ||||
|     IColourImpl* platformColourInstance() { | ||||
|         static Win32ColourImpl s_instance; | ||||
| 
 | ||||
|         Ptr<IConfig const> config = getCurrentContext().getConfig(); | ||||
|         IConfigPtr config = getCurrentContext().getConfig(); | ||||
|         UseColour::YesOrNo colourMode = config | ||||
|             ? config->useColour() | ||||
|             : UseColour::Auto; | ||||
|         if( colourMode == UseColour::Auto ) | ||||
|             colourMode = !isDebuggerActive() | ||||
|                 ? UseColour::Yes | ||||
|                 : UseColour::No; | ||||
|             colourMode = UseColour::Yes; | ||||
|         return colourMode == UseColour::Yes | ||||
|             ? &s_instance | ||||
|             : NoColourImpl::instance(); | ||||
| @@ -118,7 +126,7 @@ namespace { | ||||
|     // https://github.com/philsquared/Catch/pull/131
 | ||||
|     class PosixColourImpl : public IColourImpl { | ||||
|     public: | ||||
|         virtual void use( Colour::Code _colourCode ) { | ||||
|         virtual void use( Colour::Code _colourCode ) override { | ||||
|             switch( _colourCode ) { | ||||
|                 case Colour::None: | ||||
|                 case Colour::White:     return setColour( "[0m" ); | ||||
| @@ -134,7 +142,7 @@ namespace { | ||||
|                 case Colour::BrightGreen:   return setColour( "[1;32m" ); | ||||
|                 case Colour::BrightWhite:   return setColour( "[1;37m" ); | ||||
| 
 | ||||
|                 case Colour::Bright: throw std::logic_error( "not a colour" ); | ||||
|                 case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); | ||||
|             } | ||||
|         } | ||||
|         static IColourImpl* instance() { | ||||
| @@ -148,14 +156,21 @@ namespace { | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     bool useColourOnPlatform() { | ||||
|         return | ||||
| #ifdef CATCH_PLATFORM_MAC | ||||
|             !isDebuggerActive() && | ||||
| #endif | ||||
|             isatty(STDOUT_FILENO); | ||||
|     } | ||||
|     IColourImpl* platformColourInstance() { | ||||
|         ErrnoGuard guard; | ||||
|         Ptr<IConfig const> config = getCurrentContext().getConfig(); | ||||
|         IConfigPtr config = getCurrentContext().getConfig(); | ||||
|         UseColour::YesOrNo colourMode = config | ||||
|             ? config->useColour() | ||||
|             : UseColour::Auto; | ||||
|         if( colourMode == UseColour::Auto ) | ||||
|             colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) | ||||
|             colourMode = useColourOnPlatform() | ||||
|                 ? UseColour::Yes | ||||
|                 : UseColour::No; | ||||
|         return colourMode == UseColour::Yes | ||||
| @@ -178,8 +193,17 @@ namespace Catch { | ||||
| 
 | ||||
| namespace Catch { | ||||
| 
 | ||||
|     Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } | ||||
|     Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; } | ||||
|     Colour::Colour( Code _colourCode ) { use( _colourCode ); } | ||||
|     Colour::Colour( Colour&& rhs ) noexcept {  | ||||
|         m_moved = rhs.m_moved; | ||||
|         rhs.m_moved = true; | ||||
|     } | ||||
|     Colour& Colour::operator=( Colour&& rhs ) noexcept { | ||||
|         m_moved = rhs.m_moved; | ||||
|         rhs.m_moved  = true; | ||||
|         return *this; | ||||
|     } | ||||
|      | ||||
|     Colour::~Colour(){ if( !m_moved ) use( None ); } | ||||
| 
 | ||||
|     void Colour::use( Code _colourCode ) { | ||||
| @@ -187,6 +211,13 @@ namespace Catch { | ||||
|         impl->use( _colourCode ); | ||||
|     } | ||||
| 
 | ||||
|     std::ostream& operator << ( std::ostream& os, Colour const& ) { | ||||
|         return os; | ||||
|     } | ||||
| 
 | ||||
| } // end namespace Catch
 | ||||
| 
 | ||||
| #endif // TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
 | ||||
| #if defined(__clang__) | ||||
| #    pragma clang diagnostic pop | ||||
| #endif | ||||
| 
 | ||||
| @@ -50,17 +50,18 @@ namespace Catch { | ||||
| 
 | ||||
|         // Use constructed object for RAII guard
 | ||||
|         Colour( Code _colourCode ); | ||||
|         Colour( Colour const& other ); | ||||
|         Colour( Colour&& other ) noexcept; | ||||
|         Colour& operator=( Colour&& other ) noexcept; | ||||
|         ~Colour(); | ||||
| 
 | ||||
|         // Use static method for one-shot changes
 | ||||
|         static void use( Code _colourCode ); | ||||
| 
 | ||||
|     private: | ||||
|         bool m_moved; | ||||
|         bool m_moved = false; | ||||
|     }; | ||||
| 
 | ||||
|     inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } | ||||
|     std::ostream& operator << ( std::ostream& os, Colour const& ); | ||||
| 
 | ||||
| } // end namespace Catch
 | ||||
| 
 | ||||
							
								
								
									
										67
									
								
								include/internal/catch_context.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								include/internal/catch_context.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
|  *  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) | ||||
|  */ | ||||
| #include "catch_context.h" | ||||
| #include "catch_common.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class Context : public IMutableContext, NonCopyable { | ||||
|  | ||||
|     public: // IContext | ||||
|         virtual IResultCapture* getResultCapture() override { | ||||
|             return m_resultCapture; | ||||
|         } | ||||
|         virtual IRunner* getRunner() override { | ||||
|             return m_runner; | ||||
|         } | ||||
|  | ||||
|         virtual IConfigPtr getConfig() const override { | ||||
|             return m_config; | ||||
|         } | ||||
|  | ||||
|         virtual ~Context() override; | ||||
|  | ||||
|     public: // IMutableContext | ||||
|         virtual void setResultCapture( IResultCapture* resultCapture ) override { | ||||
|             m_resultCapture = resultCapture; | ||||
|         } | ||||
|         virtual void setRunner( IRunner* runner ) override { | ||||
|             m_runner = runner; | ||||
|         } | ||||
|         virtual void setConfig( IConfigPtr const& config ) override { | ||||
|             m_config = config; | ||||
|         } | ||||
|  | ||||
|         friend IMutableContext& getCurrentMutableContext(); | ||||
|  | ||||
|     private: | ||||
|         IConfigPtr m_config; | ||||
|         IRunner* m_runner = nullptr; | ||||
|         IResultCapture* m_resultCapture = nullptr; | ||||
|     }; | ||||
|  | ||||
|     namespace { | ||||
|         Context* currentContext = nullptr; | ||||
|     } | ||||
|     IMutableContext& getCurrentMutableContext() { | ||||
|         if( !currentContext ) | ||||
|             currentContext = new Context(); | ||||
|         return *currentContext; | ||||
|     } | ||||
|     IContext& getCurrentContext() { | ||||
|         return getCurrentMutableContext(); | ||||
|     } | ||||
|  | ||||
|     void cleanUpContext() { | ||||
|         delete currentContext; | ||||
|         currentContext = nullptr; | ||||
|     } | ||||
|     IContext::~IContext() = default; | ||||
|     IMutableContext::~IMutableContext() = default; | ||||
|     Context::~Context() = default; | ||||
| } | ||||
| @@ -8,28 +8,23 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_generators.h" | ||||
| #include "catch_ptr.hpp" | ||||
|  | ||||
| #include <memory> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class TestCase; | ||||
|     class Stream; | ||||
|     struct IResultCapture; | ||||
|     struct IRunner; | ||||
|     struct IGeneratorsForTest; | ||||
|     struct IConfig; | ||||
|  | ||||
|     using IConfigPtr = std::shared_ptr<IConfig const>; | ||||
|  | ||||
|     struct IContext | ||||
|     { | ||||
|         virtual ~IContext(); | ||||
|  | ||||
|         virtual IResultCapture* getResultCapture() = 0; | ||||
|         virtual IRunner* getRunner() = 0; | ||||
|         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; | ||||
|         virtual bool advanceGeneratorsForCurrentTest() = 0; | ||||
|         virtual Ptr<IConfig const> getConfig() const = 0; | ||||
|         virtual IConfigPtr getConfig() const = 0; | ||||
|     }; | ||||
|  | ||||
|     struct IMutableContext : IContext | ||||
| @@ -37,14 +32,12 @@ namespace Catch { | ||||
|         virtual ~IMutableContext(); | ||||
|         virtual void setResultCapture( IResultCapture* resultCapture ) = 0; | ||||
|         virtual void setRunner( IRunner* runner ) = 0; | ||||
|         virtual void setConfig( Ptr<IConfig const> const& config ) = 0; | ||||
|         virtual void setConfig( IConfigPtr const& config ) = 0; | ||||
|     }; | ||||
|  | ||||
|     IContext& getCurrentContext(); | ||||
|     IMutableContext& getCurrentMutableContext(); | ||||
|     void cleanUpContext(); | ||||
|     Stream createStream( std::string const& streamName ); | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED | ||||
|   | ||||
| @@ -1,110 +0,0 @@ | ||||
| /* | ||||
|  *  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_CONTEXT_IMPL_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_run_context.hpp" | ||||
|  | ||||
| #include "catch_context.h" | ||||
| #include "catch_stream.hpp" | ||||
| #include "catch_common.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class Context : public IMutableContext { | ||||
|  | ||||
|         Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} | ||||
|         Context( Context const& ); | ||||
|         void operator=( Context const& ); | ||||
|  | ||||
|     public: | ||||
|         virtual ~Context() { | ||||
|             deleteAllValues( m_generatorsByTestName ); | ||||
|         } | ||||
|  | ||||
|     public: // IContext | ||||
|         virtual IResultCapture* getResultCapture() { | ||||
|             return m_resultCapture; | ||||
|         } | ||||
|         virtual IRunner* getRunner() { | ||||
|             return m_runner; | ||||
|         } | ||||
|         virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { | ||||
|             return getGeneratorsForCurrentTest() | ||||
|             .getGeneratorInfo( fileInfo, totalSize ) | ||||
|             .getCurrentIndex(); | ||||
|         } | ||||
|         virtual bool advanceGeneratorsForCurrentTest() { | ||||
|             IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); | ||||
|             return generators && generators->moveNext(); | ||||
|         } | ||||
|  | ||||
|         virtual Ptr<IConfig const> getConfig() const { | ||||
|             return m_config; | ||||
|         } | ||||
|  | ||||
|     public: // IMutableContext | ||||
|         virtual void setResultCapture( IResultCapture* resultCapture ) { | ||||
|             m_resultCapture = resultCapture; | ||||
|         } | ||||
|         virtual void setRunner( IRunner* runner ) { | ||||
|             m_runner = runner; | ||||
|         } | ||||
|         virtual void setConfig( Ptr<IConfig const> const& config ) { | ||||
|             m_config = config; | ||||
|         } | ||||
|  | ||||
|         friend IMutableContext& getCurrentMutableContext(); | ||||
|  | ||||
|     private: | ||||
|         IGeneratorsForTest* findGeneratorsForCurrentTest() { | ||||
|             std::string testName = getResultCapture()->getCurrentTestName(); | ||||
|  | ||||
|             std::map<std::string, IGeneratorsForTest*>::const_iterator it = | ||||
|                 m_generatorsByTestName.find( testName ); | ||||
|             return it != m_generatorsByTestName.end() | ||||
|                 ? it->second | ||||
|                 : CATCH_NULL; | ||||
|         } | ||||
|  | ||||
|         IGeneratorsForTest& getGeneratorsForCurrentTest() { | ||||
|             IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); | ||||
|             if( !generators ) { | ||||
|                 std::string testName = getResultCapture()->getCurrentTestName(); | ||||
|                 generators = createGeneratorsForTest(); | ||||
|                 m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); | ||||
|             } | ||||
|             return *generators; | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         Ptr<IConfig const> m_config; | ||||
|         IRunner* m_runner; | ||||
|         IResultCapture* m_resultCapture; | ||||
|         std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName; | ||||
|     }; | ||||
|  | ||||
|     namespace { | ||||
|         Context* currentContext = CATCH_NULL; | ||||
|     } | ||||
|     IMutableContext& getCurrentMutableContext() { | ||||
|         if( !currentContext ) | ||||
|             currentContext = new Context(); | ||||
|         return *currentContext; | ||||
|     } | ||||
|     IContext& getCurrentContext() { | ||||
|         return getCurrentMutableContext(); | ||||
|     } | ||||
|  | ||||
|     void cleanUpContext() { | ||||
|         delete currentContext; | ||||
|         currentContext = CATCH_NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED | ||||
							
								
								
									
										29
									
								
								include/internal/catch_debug_console.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								include/internal/catch_debug_console.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| /* | ||||
|  *  Created by Martin on 29/08/2017. | ||||
|  * | ||||
|  *  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_debug_console.h" | ||||
| #include "catch_stream.h" | ||||
| #include "catch_platform.h" | ||||
|  | ||||
| #ifdef CATCH_PLATFORM_WINDOWS | ||||
|  | ||||
| #include "catch_windows_h_proxy.h" | ||||
|  | ||||
|     namespace Catch { | ||||
|         void writeToDebugConsole( std::string const& text ) { | ||||
|             ::OutputDebugStringA( text.c_str() ); | ||||
|         } | ||||
|     } | ||||
| #else | ||||
|     namespace Catch { | ||||
|         void writeToDebugConsole( std::string const& text ) { | ||||
|             // !TBD: Need a version for Mac/ XCode and other IDEs | ||||
|             Catch::cout() << text; | ||||
|         } | ||||
|     } | ||||
| #endif // Platform | ||||
							
								
								
									
										17
									
								
								include/internal/catch_debug_console.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/internal/catch_debug_console.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| /* | ||||
|  *  Created by Martin on 29/08/2017. | ||||
|  * | ||||
|  *  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_DEBUG_CONSOLE_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_DEBUG_CONSOLE_H_INCLUDED | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace Catch { | ||||
|     void writeToDebugConsole( std::string const& text ); | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_DEBUG_CONSOLE_H_INCLUDED | ||||
| @@ -6,11 +6,11 @@ | ||||
|  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||||
|  * | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED | ||||
| 
 | ||||
| #include "catch_debugger.h" | ||||
| #include "catch_errno_guard.hpp" | ||||
| #include "catch_errno_guard.h" | ||||
| #include "catch_stream.h" | ||||
| #include "catch_platform.h" | ||||
| 
 | ||||
| #ifdef CATCH_PLATFORM_MAC | ||||
| 
 | ||||
| @@ -20,7 +20,7 @@ | ||||
|     #include <unistd.h> | ||||
|     #include <sys/sysctl.h> | ||||
| 
 | ||||
|     namespace Catch{ | ||||
|     namespace Catch { | ||||
| 
 | ||||
|         // The following function is taken directly from the following technical note:
 | ||||
|         // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
 | ||||
| @@ -31,7 +31,7 @@ | ||||
| 
 | ||||
|             int                 mib[4]; | ||||
|             struct kinfo_proc   info; | ||||
|             size_t              size; | ||||
|             std::size_t         size; | ||||
| 
 | ||||
|             // Initialize the flags so that, if sysctl fails for some bizarre
 | ||||
|             // reason, we get a predictable result.
 | ||||
| @@ -49,7 +49,7 @@ | ||||
|             // Call sysctl.
 | ||||
| 
 | ||||
|             size = sizeof(info); | ||||
|             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { | ||||
|             if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) { | ||||
|                 Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; | ||||
|                 return false; | ||||
|             } | ||||
| @@ -106,26 +106,6 @@ | ||||
|     } | ||||
| #else | ||||
|     namespace Catch { | ||||
|        inline bool isDebuggerActive() { return false; } | ||||
|        bool isDebuggerActive() { return false; } | ||||
|     } | ||||
| #endif // Platform
 | ||||
| 
 | ||||
| #ifdef CATCH_PLATFORM_WINDOWS | ||||
| 
 | ||||
| #include "catch_windows_h_proxy.h" | ||||
| 
 | ||||
|     namespace Catch { | ||||
|         void writeToDebugConsole( std::string const& text ) { | ||||
|             ::OutputDebugStringA( text.c_str() ); | ||||
|         } | ||||
|     } | ||||
| #else | ||||
|     namespace Catch { | ||||
|         void writeToDebugConsole( std::string const& text ) { | ||||
|             // !TBD: Need a version for Mac/ XCode and other IDEs
 | ||||
|             Catch::cout() << text; | ||||
|         } | ||||
|     } | ||||
| #endif // Platform
 | ||||
| 
 | ||||
| #endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
 | ||||
| @@ -11,25 +11,13 @@ | ||||
|  | ||||
| #include "catch_platform.h" | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace Catch{ | ||||
|  | ||||
| namespace Catch { | ||||
|     bool isDebuggerActive(); | ||||
|     void writeToDebugConsole( std::string const& text ); | ||||
| } | ||||
|  | ||||
| #ifdef CATCH_PLATFORM_MAC | ||||
|  | ||||
|     // The following code snippet based on: | ||||
|     // http://cocoawithlove.com/2008/03/break-into-debugger.html | ||||
|     #if defined(__ppc64__) || defined(__ppc__) | ||||
|         #define CATCH_TRAP() \ | ||||
|                 __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ | ||||
|                 : : : "memory","r0","r3","r4" ) /* NOLINT */ | ||||
|     #else | ||||
|         #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ ) | ||||
|     #endif | ||||
|     #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ | ||||
|  | ||||
| #elif defined(CATCH_PLATFORM_LINUX) | ||||
|     // If we can use inline assembler, do it because this allows us to break | ||||
|   | ||||
							
								
								
									
										24
									
								
								include/internal/catch_decomposer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/internal/catch_decomposer.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| /* | ||||
|  *  Created by Phil Nash on 8/8/2017. | ||||
|  *  Copyright 2017 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_decomposer.h" | ||||
| #include "catch_config.hpp" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     ITransientExpression::~ITransientExpression() = default; | ||||
|      | ||||
|     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) { | ||||
|         if( lhs.size() + rhs.size() < 40 && | ||||
|                 lhs.find('\n') == std::string::npos && | ||||
|                 rhs.find('\n') == std::string::npos ) | ||||
|             os << lhs << " " << op << " " << rhs; | ||||
|         else | ||||
|             os << lhs << "\n" << op << "\n" << rhs; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										169
									
								
								include/internal/catch_decomposer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								include/internal/catch_decomposer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | ||||
| /* | ||||
|  *  Created by Phil Nash on 8/8/2017. | ||||
|  *  Copyright 2017 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_DECOMPOSER_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED | ||||
|  | ||||
| #include "catch_tostring.h" | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| #include <ostream> | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
| #pragma warning(push) | ||||
| #pragma warning(disable:4389) // '==' : signed/unsigned mismatch | ||||
| #pragma warning(disable:4018) // more "signed/unsigned mismatch" | ||||
| #pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) | ||||
| #pragma warning(disable:4180) // qualifier applied to function type has no meaning | ||||
| #endif | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct ITransientExpression { | ||||
|         virtual auto isBinaryExpression() const -> bool = 0; | ||||
|         virtual auto getResult() const -> bool = 0; | ||||
|         virtual void streamReconstructedExpression( std::ostream &os ) const = 0; | ||||
|  | ||||
|         // We don't actually need a virtual destructore, but many static analysers | ||||
|         // complain if it's not here :-( | ||||
|         virtual ~ITransientExpression(); | ||||
|     }; | ||||
|  | ||||
|     void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ); | ||||
|  | ||||
|     template<typename LhsT, typename RhsT> | ||||
|     class BinaryExpr  : public ITransientExpression { | ||||
|         bool m_result; | ||||
|         LhsT m_lhs; | ||||
|         StringRef m_op; | ||||
|         RhsT m_rhs; | ||||
|  | ||||
|         auto isBinaryExpression() const -> bool override { return true; } | ||||
|         auto getResult() const -> bool override { return m_result; } | ||||
|  | ||||
|         void streamReconstructedExpression( std::ostream &os ) const override { | ||||
|             formatReconstructedExpression | ||||
|                     ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) ); | ||||
|         } | ||||
|  | ||||
|     public: | ||||
|         BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs ) | ||||
|         :   m_result( comparisonResult ), | ||||
|             m_lhs( lhs ), | ||||
|             m_op( op ), | ||||
|             m_rhs( rhs ) | ||||
|         {} | ||||
|     }; | ||||
|  | ||||
|     template<typename LhsT> | ||||
|     class UnaryExpr : public ITransientExpression { | ||||
|         LhsT m_lhs; | ||||
|  | ||||
|         auto isBinaryExpression() const -> bool override { return false; } | ||||
|         auto getResult() const -> bool override { return m_lhs ? true : false; } | ||||
|  | ||||
|         void streamReconstructedExpression( std::ostream &os ) const override { | ||||
|             os << Catch::Detail::stringify( m_lhs ); | ||||
|         } | ||||
|  | ||||
|     public: | ||||
|         UnaryExpr( LhsT lhs ) : m_lhs( lhs ) {} | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int) | ||||
|     template<typename LhsT, typename RhsT> | ||||
|     auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return lhs == rhs; }; | ||||
|     template<typename T> | ||||
|     auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } | ||||
|     template<typename T> | ||||
|     auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); } | ||||
|     template<typename T> | ||||
|     auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } | ||||
|     template<typename T> | ||||
|     auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; } | ||||
|  | ||||
|     template<typename LhsT, typename RhsT> | ||||
|     auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return lhs != rhs; }; | ||||
|     template<typename T> | ||||
|     auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } | ||||
|     template<typename T> | ||||
|     auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); } | ||||
|     template<typename T> | ||||
|     auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } | ||||
|     template<typename T> | ||||
|     auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; } | ||||
|  | ||||
|  | ||||
|     template<typename LhsT> | ||||
|     class ExprLhs { | ||||
|         LhsT m_lhs; | ||||
|     public: | ||||
|         ExprLhs( LhsT lhs ) : m_lhs( lhs ) {} | ||||
|  | ||||
|         template<typename RhsT> | ||||
|         auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { | ||||
|             return BinaryExpr<LhsT, RhsT const&>( compareEqual( m_lhs, rhs ), m_lhs, "==", rhs ); | ||||
|         } | ||||
|         auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const { | ||||
|             return BinaryExpr<LhsT, bool>( m_lhs == rhs, m_lhs, "==", rhs ); | ||||
|         } | ||||
|  | ||||
|         template<typename RhsT> | ||||
|         auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { | ||||
|             return BinaryExpr<LhsT, RhsT const&>( compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs ); | ||||
|         } | ||||
|         auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const { | ||||
|             return BinaryExpr<LhsT, bool>( m_lhs != rhs, m_lhs, "!=", rhs ); | ||||
|         } | ||||
|  | ||||
|         template<typename RhsT> | ||||
|         auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { | ||||
|             return BinaryExpr<LhsT, RhsT const&>( m_lhs > rhs, m_lhs, ">", rhs ); | ||||
|         } | ||||
|         template<typename RhsT> | ||||
|         auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { | ||||
|             return BinaryExpr<LhsT, RhsT const&>( m_lhs < rhs, m_lhs, "<", rhs ); | ||||
|         } | ||||
|         template<typename RhsT> | ||||
|         auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { | ||||
|             return BinaryExpr<LhsT, RhsT const&>( m_lhs >= rhs, m_lhs, ">=", rhs ); | ||||
|         } | ||||
|         template<typename RhsT> | ||||
|         auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const { | ||||
|             return BinaryExpr<LhsT, RhsT const&>( m_lhs <= rhs, m_lhs, "<=", rhs ); | ||||
|         } | ||||
|  | ||||
|         auto makeUnaryExpr() const -> UnaryExpr<LhsT> { | ||||
|             return UnaryExpr<LhsT>( m_lhs ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     void handleExpression( ITransientExpression const& expr ); | ||||
|  | ||||
|     template<typename T> | ||||
|     void handleExpression( ExprLhs<T> const& expr ) { | ||||
|         handleExpression( expr.makeUnaryExpr() ); | ||||
|     } | ||||
|  | ||||
|     struct Decomposer { | ||||
|         template<typename T> | ||||
|         auto operator <= ( T const& lhs ) -> ExprLhs<T const&> { | ||||
|             return ExprLhs<T const&>( lhs ); | ||||
|         } | ||||
|         auto operator <=( bool value ) -> ExprLhs<bool> { | ||||
|             return ExprLhs<bool>( value ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_DECOMPOSER_H_INCLUDED | ||||
| @@ -8,6 +8,8 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_session.h" | ||||
|  | ||||
| #ifndef __OBJC__ | ||||
|  | ||||
| #if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) | ||||
| @@ -18,8 +20,7 @@ extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { | ||||
| int main (int argc, char * argv[]) { | ||||
| #endif | ||||
|  | ||||
|     int result = Catch::Session().run( argc, argv ); | ||||
|     return ( result < 0xff ? result : 0xff ); | ||||
|     return Catch::Session().run( argc, argv ); | ||||
| } | ||||
|  | ||||
| #else // __OBJC__ | ||||
| @@ -31,13 +32,13 @@ int main (int argc, char * const argv[]) { | ||||
| #endif | ||||
|  | ||||
|     Catch::registerTestMethods(); | ||||
|     int result = Catch::Session().run( argc, (char* const*)argv ); | ||||
|     int result = Catch::Session().run( argc, (char**)argv ); | ||||
|  | ||||
| #if !CATCH_ARC_ENABLED | ||||
|     [pool drain]; | ||||
| #endif | ||||
|  | ||||
|     return ( result < 0xff ? result : 0xff ); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| #endif // __OBJC__ | ||||
|   | ||||
							
								
								
									
										24
									
								
								include/internal/catch_enforce.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/internal/catch_enforce.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| /* | ||||
|  *  Created by Martin on 01/08/2017. | ||||
|  * | ||||
|  *  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_ENFORCE_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED | ||||
|  | ||||
| #include "catch_common.h" | ||||
|  | ||||
| #include <sstream> | ||||
| #include <stdexcept> | ||||
|  | ||||
| #define CATCH_PREPARE_EXCEPTION( type, msg ) \ | ||||
|     type( static_cast<std::ostringstream&&>( std::ostringstream() << msg ).str() ) | ||||
| #define CATCH_INTERNAL_ERROR( msg ) \ | ||||
|     throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg); | ||||
| #define CATCH_ERROR( msg ) \ | ||||
|     throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg ) | ||||
| #define CATCH_ENFORCE( condition, msg ) \ | ||||
|     do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false) | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_ENFORCE_H_INCLUDED | ||||
							
								
								
									
										15
									
								
								include/internal/catch_errno_guard.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								include/internal/catch_errno_guard.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| /* | ||||
|  *  Created by Martin on 06/03/2017. | ||||
|  * | ||||
|  *  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_errno_guard.h" | ||||
|  | ||||
| #include <cerrno> | ||||
|  | ||||
| namespace Catch { | ||||
|         ErrnoGuard::ErrnoGuard():m_oldErrno(errno){} | ||||
|         ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; } | ||||
| } | ||||
| @@ -4,22 +4,19 @@ | ||||
|  *  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_ERRNO_GUARD_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED | ||||
| 
 | ||||
| #include <cerrno> | ||||
| 
 | ||||
| #ifndef TWOBLUECUBES_CATCH_ERRNO_GUARD_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_ERRNO_GUARD_H_INCLUDED | ||||
| 
 | ||||
| namespace Catch { | ||||
| 
 | ||||
|     class ErrnoGuard { | ||||
|     public: | ||||
|         ErrnoGuard():m_oldErrno(errno){} | ||||
|         ~ErrnoGuard() { errno = m_oldErrno; } | ||||
|         ErrnoGuard(); | ||||
|         ~ErrnoGuard(); | ||||
|     private: | ||||
|         int m_oldErrno; | ||||
|     }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED
 | ||||
| #endif // TWOBLUECUBES_CATCH_ERRNO_GUARD_H_INCLUDED
 | ||||
							
								
								
									
										62
									
								
								include/internal/catch_exception_translator_registry.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								include/internal/catch_exception_translator_registry.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| /* | ||||
|  *  Created by Phil on 20/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_assertionhandler.h" | ||||
| #include "catch_exception_translator_registry.h" | ||||
|  | ||||
| #ifdef __OBJC__ | ||||
| #import "Foundation/Foundation.h" | ||||
| #endif | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { | ||||
|     } | ||||
|  | ||||
|     void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) { | ||||
|         m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) ); | ||||
|     } | ||||
|  | ||||
|     std::string ExceptionTranslatorRegistry::translateActiveException() const { | ||||
|         try { | ||||
| #ifdef __OBJC__ | ||||
|             // In Objective-C try objective-c exceptions first | ||||
|             @try { | ||||
|                 return tryTranslators(); | ||||
|             } | ||||
|             @catch (NSException *exception) { | ||||
|                 return Catch::Detail::stringify( [exception description] ); | ||||
|             } | ||||
| #else | ||||
|             return tryTranslators(); | ||||
| #endif | ||||
|         } | ||||
|         catch( TestFailureException& ) { | ||||
|             std::rethrow_exception(std::current_exception()); | ||||
|         } | ||||
|         catch( std::exception& ex ) { | ||||
|             return ex.what(); | ||||
|         } | ||||
|         catch( std::string& msg ) { | ||||
|             return msg; | ||||
|         } | ||||
|         catch( const char* msg ) { | ||||
|             return msg; | ||||
|         } | ||||
|         catch(...) { | ||||
|             return "Unknown exception"; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     std::string ExceptionTranslatorRegistry::tryTranslators() const { | ||||
|         if( m_translators.empty() ) | ||||
|             std::rethrow_exception(std::current_exception()); | ||||
|         else | ||||
|             return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										30
									
								
								include/internal/catch_exception_translator_registry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								include/internal/catch_exception_translator_registry.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| /* | ||||
|  *  Created by Phil on 20/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_exception.h" | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <memory> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { | ||||
|     public: | ||||
|         ~ExceptionTranslatorRegistry(); | ||||
|         virtual void registerTranslator( const IExceptionTranslator* translator ); | ||||
|         virtual std::string translateActiveException() const override; | ||||
|         std::string tryTranslators() const; | ||||
|  | ||||
|     private: | ||||
|         std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED | ||||
| @@ -1,73 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 20/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_exception.h" | ||||
| #include "catch_tostring.h" | ||||
|  | ||||
| #ifdef __OBJC__ | ||||
| #import "Foundation/Foundation.h" | ||||
| #endif | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { | ||||
|     public: | ||||
|         ~ExceptionTranslatorRegistry() { | ||||
|             deleteAll( m_translators ); | ||||
|         } | ||||
|  | ||||
|         virtual void registerTranslator( const IExceptionTranslator* translator ) { | ||||
|             m_translators.push_back( translator ); | ||||
|         } | ||||
|  | ||||
|         virtual std::string translateActiveException() const { | ||||
|             try { | ||||
| #ifdef __OBJC__ | ||||
|                 // In Objective-C try objective-c exceptions first | ||||
|                 @try { | ||||
|                     return tryTranslators(); | ||||
|                 } | ||||
|                 @catch (NSException *exception) { | ||||
|                     return Catch::toString( [exception description] ); | ||||
|                 } | ||||
| #else | ||||
|                 return tryTranslators(); | ||||
| #endif | ||||
|             } | ||||
|             catch( TestFailureException& ) { | ||||
|                 throw; | ||||
|             } | ||||
|             catch( std::exception& ex ) { | ||||
|                 return ex.what(); | ||||
|             } | ||||
|             catch( std::string& msg ) { | ||||
|                 return msg; | ||||
|             } | ||||
|             catch( const char* msg ) { | ||||
|                 return msg; | ||||
|             } | ||||
|             catch(...) { | ||||
|                 return "Unknown exception"; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         std::string tryTranslators() const { | ||||
|             if( m_translators.empty() ) | ||||
|                 throw; | ||||
|             else | ||||
|                 return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         std::vector<const IExceptionTranslator*> m_translators; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED | ||||
							
								
								
									
										14
									
								
								include/internal/catch_external_interfaces.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								include/internal/catch_external_interfaces.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| /* | ||||
|  *  Created by Martin on 17/08/2017. | ||||
|  * | ||||
|  *  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_EXTERNAL_INTERFACES_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_EXTERNAL_INTERFACES_H_INCLUDED | ||||
|  | ||||
| #include "../reporters/catch_reporter_bases.hpp" | ||||
| #include "catch_console_colour.h" | ||||
| #include "catch_reporter_registrars.hpp" | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_EXTERNAL_INTERFACES_H_INCLUDED | ||||
							
								
								
									
										176
									
								
								include/internal/catch_fatal_condition.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								include/internal/catch_fatal_condition.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | ||||
| /* | ||||
|  *  Created by Phil on 21/08/2014 | ||||
|  *  Copyright 2014 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_fatal_condition.h" | ||||
|  | ||||
| #include "catch_context.h" | ||||
| #include "catch_interfaces_capture.h" | ||||
|  | ||||
| namespace { | ||||
|     // Report the error condition | ||||
|     void reportFatal( char const * const message ) { | ||||
|         Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// | ||||
|  | ||||
| #  if !defined ( CATCH_CONFIG_WINDOWS_SEH ) | ||||
|  | ||||
| namespace Catch { | ||||
|     void FatalConditionHandler::reset() {} | ||||
| } | ||||
|  | ||||
| #  else // CATCH_CONFIG_WINDOWS_SEH is defined | ||||
|  | ||||
| namespace Catch { | ||||
|     struct SignalDefs { DWORD id; const char* name; }; | ||||
|  | ||||
|     // There is no 1-1 mapping between signals and windows exceptions. | ||||
|     // Windows can easily distinguish between SO and SigSegV, | ||||
|     // but SigInt, SigTerm, etc are handled differently. | ||||
|     static SignalDefs signalDefs[] = { | ||||
|         { EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" }, | ||||
|         { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, | ||||
|         { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, | ||||
|         { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, | ||||
|     }; | ||||
|  | ||||
|     LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { | ||||
|         for (auto const& def : signalDefs) { | ||||
|             if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { | ||||
|                 reportFatal(def.name); | ||||
|             } | ||||
|         } | ||||
|         // If its not an exception we care about, pass it along. | ||||
|         // This stops us from eating debugger breaks etc. | ||||
|         return EXCEPTION_CONTINUE_SEARCH; | ||||
|     } | ||||
|  | ||||
|     FatalConditionHandler::FatalConditionHandler() { | ||||
|         isSet = true; | ||||
|         // 32k seems enough for Catch to handle stack overflow, | ||||
|         // but the value was found experimentally, so there is no strong guarantee | ||||
|         guaranteeSize = 32 * 1024; | ||||
|         exceptionHandlerHandle = nullptr; | ||||
|         // Register as first handler in current chain | ||||
|         exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); | ||||
|         // Pass in guarantee size to be filled | ||||
|         SetThreadStackGuarantee(&guaranteeSize); | ||||
|     } | ||||
|  | ||||
|     void FatalConditionHandler::reset() { | ||||
|         if (isSet) { | ||||
|             // Unregister handler and restore the old guarantee | ||||
|             RemoveVectoredExceptionHandler(exceptionHandlerHandle); | ||||
|             SetThreadStackGuarantee(&guaranteeSize); | ||||
|             exceptionHandlerHandle = nullptr; | ||||
|             isSet = false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     FatalConditionHandler::~FatalConditionHandler() { | ||||
|         reset(); | ||||
|     } | ||||
|  | ||||
| bool FatalConditionHandler::isSet = false; | ||||
| ULONG FatalConditionHandler::guaranteeSize = 0; | ||||
| PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; | ||||
|  | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #  endif // CATCH_CONFIG_WINDOWS_SEH | ||||
|  | ||||
| #else // Not Windows - assumed to be POSIX compatible ////////////////////////// | ||||
|  | ||||
| #  if !defined(CATCH_CONFIG_POSIX_SIGNALS) | ||||
|  | ||||
| namespace Catch { | ||||
|     void FatalConditionHandler::reset() {} | ||||
| } | ||||
|  | ||||
|  | ||||
| #  else // CATCH_CONFIG_POSIX_SIGNALS is defined | ||||
|  | ||||
| #include <signal.h> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct SignalDefs { | ||||
|         int id; | ||||
|         const char* name; | ||||
|     }; | ||||
|     static SignalDefs signalDefs[] = { | ||||
|         { SIGINT,  "SIGINT - Terminal interrupt signal" }, | ||||
|         { SIGILL,  "SIGILL - Illegal instruction signal" }, | ||||
|         { SIGFPE,  "SIGFPE - Floating point error signal" }, | ||||
|         { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, | ||||
|         { SIGTERM, "SIGTERM - Termination request signal" }, | ||||
|         { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     void FatalConditionHandler::handleSignal( int sig ) { | ||||
|         char const * name = "<unknown signal>"; | ||||
|         for (auto const& def : signalDefs) { | ||||
|             if (sig == def.id) { | ||||
|                 name = def.name; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         reset(); | ||||
|         reportFatal(name); | ||||
|         raise( sig ); | ||||
|     } | ||||
|  | ||||
|     FatalConditionHandler::FatalConditionHandler() { | ||||
|         isSet = true; | ||||
|         stack_t sigStack; | ||||
|         sigStack.ss_sp = altStackMem; | ||||
|         sigStack.ss_size = SIGSTKSZ; | ||||
|         sigStack.ss_flags = 0; | ||||
|         sigaltstack(&sigStack, &oldSigStack); | ||||
|         struct sigaction sa = { }; | ||||
|  | ||||
|         sa.sa_handler = handleSignal; | ||||
|         sa.sa_flags = SA_ONSTACK; | ||||
|         for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { | ||||
|             sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     FatalConditionHandler::~FatalConditionHandler() { | ||||
|         reset(); | ||||
|     } | ||||
|  | ||||
|     void FatalConditionHandler::reset() { | ||||
|         if( isSet ) { | ||||
|             // Set signals back to previous values -- hopefully nobody overwrote them in the meantime | ||||
|             for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { | ||||
|                 sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); | ||||
|             } | ||||
|             // Return the old stack | ||||
|             sigaltstack(&oldSigStack, nullptr); | ||||
|             isSet = false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     bool FatalConditionHandler::isSet = false; | ||||
|     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; | ||||
|     stack_t FatalConditionHandler::oldSigStack = {}; | ||||
|     char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; | ||||
|  | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #  endif // CATCH_CONFIG_POSIX_SIGNALS | ||||
|  | ||||
| #endif // not Windows | ||||
							
								
								
									
										86
									
								
								include/internal/catch_fatal_condition.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								include/internal/catch_fatal_condition.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|  *  Created by Phil on 21/08/2014 | ||||
|  *  Copyright 2014 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_FATAL_CONDITION_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED | ||||
|  | ||||
| #include <string> | ||||
| #include "catch_platform.h" | ||||
| #include "catch_compiler_capabilities.h" | ||||
|  | ||||
|  | ||||
| #if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// | ||||
| #include "catch_windows_h_proxy.h" | ||||
|  | ||||
| #  if !defined ( CATCH_CONFIG_WINDOWS_SEH ) | ||||
|  | ||||
| namespace Catch { | ||||
|     struct FatalConditionHandler { | ||||
|         void reset(); | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #  else // CATCH_CONFIG_WINDOWS_SEH is defined | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct FatalConditionHandler { | ||||
|  | ||||
|         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); | ||||
|         FatalConditionHandler(); | ||||
|         static void reset(); | ||||
|         ~FatalConditionHandler(); | ||||
|  | ||||
|     private: | ||||
|         static bool isSet; | ||||
|         static ULONG guaranteeSize; | ||||
|         static PVOID exceptionHandlerHandle; | ||||
|     }; | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #  endif // CATCH_CONFIG_WINDOWS_SEH | ||||
|  | ||||
| #else // Not Windows - assumed to be POSIX compatible ////////////////////////// | ||||
|  | ||||
| #  if !defined(CATCH_CONFIG_POSIX_SIGNALS) | ||||
|  | ||||
| namespace Catch { | ||||
|     struct FatalConditionHandler { | ||||
|         void reset(); | ||||
|     }; | ||||
| } | ||||
|  | ||||
|  | ||||
| #  else // CATCH_CONFIG_POSIX_SIGNALS is defined | ||||
|  | ||||
| #include <signal.h> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct FatalConditionHandler { | ||||
|  | ||||
|         static bool isSet; | ||||
|         static struct sigaction oldSigActions[];// [sizeof(signalDefs) / sizeof(SignalDefs)]; | ||||
|         static stack_t oldSigStack; | ||||
|         static char altStackMem[]; | ||||
|  | ||||
|         static void handleSignal( int sig ); | ||||
|  | ||||
|         FatalConditionHandler(); | ||||
|         ~FatalConditionHandler(); | ||||
|         static void reset(); | ||||
|     }; | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #  endif // CATCH_CONFIG_POSIX_SIGNALS | ||||
|  | ||||
| #endif // not Windows | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED | ||||
| @@ -1,200 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 21/08/2014 | ||||
|  *  Copyright 2014 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_FATAL_CONDITION_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED | ||||
|  | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     // Report the error condition | ||||
|     inline void reportFatal( std::string const& message ) { | ||||
|         IContext& context = Catch::getCurrentContext(); | ||||
|         IResultCapture* resultCapture = context.getResultCapture(); | ||||
|         resultCapture->handleFatalErrorCondition( message ); | ||||
|     } | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// | ||||
| #include "catch_windows_h_proxy.h" | ||||
|  | ||||
| #  if !defined ( CATCH_CONFIG_WINDOWS_SEH ) | ||||
|  | ||||
| namespace Catch { | ||||
|     struct FatalConditionHandler { | ||||
|         void reset() {} | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #  else // CATCH_CONFIG_WINDOWS_SEH is defined | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct SignalDefs { DWORD id; const char* name; }; | ||||
|     extern SignalDefs signalDefs[]; | ||||
|     // There is no 1-1 mapping between signals and windows exceptions. | ||||
|     // Windows can easily distinguish between SO and SigSegV, | ||||
|     // but SigInt, SigTerm, etc are handled differently. | ||||
|     SignalDefs signalDefs[] = { | ||||
|         { EXCEPTION_ILLEGAL_INSTRUCTION,  "SIGILL - Illegal instruction signal" }, | ||||
|         { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, | ||||
|         { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, | ||||
|         { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, | ||||
|     }; | ||||
|  | ||||
|     struct FatalConditionHandler { | ||||
|  | ||||
|         static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { | ||||
|             for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { | ||||
|                 if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { | ||||
|                     reportFatal(signalDefs[i].name); | ||||
|                 } | ||||
|             } | ||||
|             // If its not an exception we care about, pass it along. | ||||
|             // This stops us from eating debugger breaks etc. | ||||
|             return EXCEPTION_CONTINUE_SEARCH; | ||||
|         } | ||||
|  | ||||
|         FatalConditionHandler() { | ||||
|             isSet = true; | ||||
|             // 32k seems enough for Catch to handle stack overflow, | ||||
|             // but the value was found experimentally, so there is no strong guarantee | ||||
|             guaranteeSize = 32 * 1024; | ||||
|             exceptionHandlerHandle = CATCH_NULL; | ||||
|             // Register as first handler in current chain | ||||
|             exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); | ||||
|             // Pass in guarantee size to be filled | ||||
|             SetThreadStackGuarantee(&guaranteeSize); | ||||
|         } | ||||
|  | ||||
|         static void reset() { | ||||
|             if (isSet) { | ||||
|                 // Unregister handler and restore the old guarantee | ||||
|                 RemoveVectoredExceptionHandler(exceptionHandlerHandle); | ||||
|                 SetThreadStackGuarantee(&guaranteeSize); | ||||
|                 exceptionHandlerHandle = CATCH_NULL; | ||||
|                 isSet = false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         ~FatalConditionHandler() { | ||||
|             reset(); | ||||
|         } | ||||
|     private: | ||||
|         static bool isSet; | ||||
|         static ULONG guaranteeSize; | ||||
|         static PVOID exceptionHandlerHandle; | ||||
|     }; | ||||
|  | ||||
|     bool FatalConditionHandler::isSet = false; | ||||
|     ULONG FatalConditionHandler::guaranteeSize = 0; | ||||
|     PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL; | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #  endif // CATCH_CONFIG_WINDOWS_SEH | ||||
|  | ||||
| #else // Not Windows - assumed to be POSIX compatible ////////////////////////// | ||||
|  | ||||
| #  if !defined(CATCH_CONFIG_POSIX_SIGNALS) | ||||
|  | ||||
| namespace Catch { | ||||
|     struct FatalConditionHandler { | ||||
|         void reset() {} | ||||
|     }; | ||||
| } | ||||
|  | ||||
|  | ||||
| #  else // CATCH_CONFIG_POSIX_SIGNALS is defined | ||||
|  | ||||
| #include <signal.h> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct SignalDefs { | ||||
|         int id; | ||||
|         const char* name; | ||||
|     }; | ||||
|     extern SignalDefs signalDefs[]; | ||||
|     SignalDefs signalDefs[] = { | ||||
|             { SIGINT,  "SIGINT - Terminal interrupt signal" }, | ||||
|             { SIGILL,  "SIGILL - Illegal instruction signal" }, | ||||
|             { SIGFPE,  "SIGFPE - Floating point error signal" }, | ||||
|             { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, | ||||
|             { SIGTERM, "SIGTERM - Termination request signal" }, | ||||
|             { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } | ||||
|     }; | ||||
|  | ||||
|     struct FatalConditionHandler { | ||||
|  | ||||
|         static bool isSet; | ||||
|         static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)]; | ||||
|         static stack_t oldSigStack; | ||||
|         static char altStackMem[SIGSTKSZ]; | ||||
|  | ||||
|         static void handleSignal( int sig ) { | ||||
|             std::string name = "<unknown signal>"; | ||||
|             for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { | ||||
|                 SignalDefs &def = signalDefs[i]; | ||||
|                 if (sig == def.id) { | ||||
|                     name = def.name; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|             reset(); | ||||
|             reportFatal(name); | ||||
|             raise( sig ); | ||||
|         } | ||||
|  | ||||
|         FatalConditionHandler() { | ||||
|             isSet = true; | ||||
|             stack_t sigStack; | ||||
|             sigStack.ss_sp = altStackMem; | ||||
|             sigStack.ss_size = SIGSTKSZ; | ||||
|             sigStack.ss_flags = 0; | ||||
|             sigaltstack(&sigStack, &oldSigStack); | ||||
|             struct sigaction sa = { 0 }; | ||||
|  | ||||
|             sa.sa_handler = handleSignal; | ||||
|             sa.sa_flags = SA_ONSTACK; | ||||
|             for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { | ||||
|                 sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         ~FatalConditionHandler() { | ||||
|             reset(); | ||||
|         } | ||||
|         static void reset() { | ||||
|             if( isSet ) { | ||||
|                 // Set signals back to previous values -- hopefully nobody overwrote them in the meantime | ||||
|                 for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { | ||||
|                     sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL); | ||||
|                 } | ||||
|                 // Return the old stack | ||||
|                 sigaltstack(&oldSigStack, CATCH_NULL); | ||||
|                 isSet = false; | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     bool FatalConditionHandler::isSet = false; | ||||
|     struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; | ||||
|     stack_t FatalConditionHandler::oldSigStack = {}; | ||||
|     char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; | ||||
|  | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #  endif // CATCH_CONFIG_POSIX_SIGNALS | ||||
|  | ||||
| #endif // not Windows | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED | ||||
| @@ -1,189 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 27/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_context.h" | ||||
|  | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| template<typename T> | ||||
| struct IGenerator { | ||||
|     virtual ~IGenerator() {} | ||||
|     virtual T getValue( std::size_t index ) const = 0; | ||||
|     virtual std::size_t size () const = 0; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| class BetweenGenerator : public IGenerator<T> { | ||||
| public: | ||||
|     BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} | ||||
|  | ||||
|     virtual T getValue( std::size_t index ) const { | ||||
|         return m_from+static_cast<int>( index ); | ||||
|     } | ||||
|  | ||||
|     virtual std::size_t size() const { | ||||
|         return static_cast<std::size_t>( 1+m_to-m_from ); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     T m_from; | ||||
|     T m_to; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| class ValuesGenerator : public IGenerator<T> { | ||||
| public: | ||||
|     ValuesGenerator(){} | ||||
|  | ||||
|     void add( T value ) { | ||||
|         m_values.push_back( value ); | ||||
|     } | ||||
|  | ||||
|     virtual T getValue( std::size_t index ) const { | ||||
|         return m_values[index]; | ||||
|     } | ||||
|  | ||||
|     virtual std::size_t size() const { | ||||
|         return m_values.size(); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     std::vector<T> m_values; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| class CompositeGenerator { | ||||
| public: | ||||
|     CompositeGenerator() : m_totalSize( 0 ) {} | ||||
|  | ||||
|     // *** Move semantics, similar to auto_ptr *** | ||||
|     CompositeGenerator( CompositeGenerator& other ) | ||||
|     :   m_fileInfo( other.m_fileInfo ), | ||||
|         m_totalSize( 0 ) | ||||
|     { | ||||
|         move( other ); | ||||
|     } | ||||
|  | ||||
|     CompositeGenerator& setFileInfo( const char* fileInfo ) { | ||||
|         m_fileInfo = fileInfo; | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     ~CompositeGenerator() { | ||||
|         deleteAll( m_composed ); | ||||
|     } | ||||
|  | ||||
|     operator T () const { | ||||
|         size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); | ||||
|  | ||||
|         typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin(); | ||||
|         typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end(); | ||||
|         for( size_t index = 0; it != itEnd; ++it ) | ||||
|         { | ||||
|             const IGenerator<T>* generator = *it; | ||||
|             if( overallIndex >= index && overallIndex < index + generator->size() ) | ||||
|             { | ||||
|                 return generator->getValue( overallIndex-index ); | ||||
|             } | ||||
|             index += generator->size(); | ||||
|         } | ||||
|         CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); | ||||
|         return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so | ||||
|     } | ||||
|  | ||||
|     void add( const IGenerator<T>* generator ) { | ||||
|         m_totalSize += generator->size(); | ||||
|         m_composed.push_back( generator ); | ||||
|     } | ||||
|  | ||||
|     CompositeGenerator& then( CompositeGenerator& other ) { | ||||
|         move( other ); | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     CompositeGenerator& then( T value ) { | ||||
|         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); | ||||
|         valuesGen->add( value ); | ||||
|         add( valuesGen ); | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|  | ||||
|     void move( CompositeGenerator& other ) { | ||||
|         m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() ); | ||||
|         m_totalSize += other.m_totalSize; | ||||
|         other.m_composed.clear(); | ||||
|     } | ||||
|  | ||||
|     std::vector<const IGenerator<T>*> m_composed; | ||||
|     std::string m_fileInfo; | ||||
|     size_t m_totalSize; | ||||
| }; | ||||
|  | ||||
| namespace Generators | ||||
| { | ||||
|     template<typename T> | ||||
|     CompositeGenerator<T> between( T from, T to ) { | ||||
|         CompositeGenerator<T> generators; | ||||
|         generators.add( new BetweenGenerator<T>( from, to ) ); | ||||
|         return generators; | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     CompositeGenerator<T> values( T val1, T val2 ) { | ||||
|         CompositeGenerator<T> generators; | ||||
|         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); | ||||
|         valuesGen->add( val1 ); | ||||
|         valuesGen->add( val2 ); | ||||
|         generators.add( valuesGen ); | ||||
|         return generators; | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     CompositeGenerator<T> values( T val1, T val2, T val3 ){ | ||||
|         CompositeGenerator<T> generators; | ||||
|         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); | ||||
|         valuesGen->add( val1 ); | ||||
|         valuesGen->add( val2 ); | ||||
|         valuesGen->add( val3 ); | ||||
|         generators.add( valuesGen ); | ||||
|         return generators; | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) { | ||||
|         CompositeGenerator<T> generators; | ||||
|         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); | ||||
|         valuesGen->add( val1 ); | ||||
|         valuesGen->add( val2 ); | ||||
|         valuesGen->add( val3 ); | ||||
|         valuesGen->add( val4 ); | ||||
|         generators.add( valuesGen ); | ||||
|         return generators; | ||||
|     } | ||||
|  | ||||
| } // end namespace Generators | ||||
|  | ||||
| using namespace Generators; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #define INTERNAL_CATCH_LINESTR2( line ) #line | ||||
| #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) | ||||
|  | ||||
| #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED | ||||
| @@ -1,86 +0,0 @@ | ||||
| /* | ||||
|  *  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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_generators.h" | ||||
|  | ||||
| #include "catch_common.h" | ||||
|  | ||||
| #include <vector> | ||||
| #include <string> | ||||
| #include <map> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct GeneratorInfo : IGeneratorInfo { | ||||
|  | ||||
|         GeneratorInfo( std::size_t size ) | ||||
|         :   m_size( size ), | ||||
|             m_currentIndex( 0 ) | ||||
|         {} | ||||
|  | ||||
|         bool moveNext() { | ||||
|             if( ++m_currentIndex == m_size ) { | ||||
|                 m_currentIndex = 0; | ||||
|                 return false; | ||||
|             } | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         std::size_t getCurrentIndex() const { | ||||
|             return m_currentIndex; | ||||
|         } | ||||
|  | ||||
|         std::size_t m_size; | ||||
|         std::size_t m_currentIndex; | ||||
|     }; | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|     class GeneratorsForTest : public IGeneratorsForTest { | ||||
|  | ||||
|     public: | ||||
|         ~GeneratorsForTest() { | ||||
|             deleteAll( m_generatorsInOrder ); | ||||
|         } | ||||
|  | ||||
|         IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { | ||||
|             std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo ); | ||||
|             if( it == m_generatorsByName.end() ) { | ||||
|                 IGeneratorInfo* info = new GeneratorInfo( size ); | ||||
|                 m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); | ||||
|                 m_generatorsInOrder.push_back( info ); | ||||
|                 return *info; | ||||
|             } | ||||
|             return *it->second; | ||||
|         } | ||||
|  | ||||
|         bool moveNext() { | ||||
|             std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin(); | ||||
|             std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end(); | ||||
|             for(; it != itEnd; ++it ) { | ||||
|                 if( (*it)->moveNext() ) | ||||
|                     return true; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         std::map<std::string, IGeneratorInfo*> m_generatorsByName; | ||||
|         std::vector<IGeneratorInfo*> m_generatorsInOrder; | ||||
|     }; | ||||
|  | ||||
|     IGeneratorsForTest* createGeneratorsForTest() | ||||
|     { | ||||
|         return new GeneratorsForTest(); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED | ||||
| @@ -8,99 +8,22 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED | ||||
|  | ||||
| // Collect all the implementation files together here | ||||
| // These are the equivalent of what would usually be cpp files | ||||
|  | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic push | ||||
| #pragma clang diagnostic ignored "-Wweak-vtables" | ||||
| #endif | ||||
|  | ||||
| #include "../catch_session.hpp" | ||||
| #include "catch_registry_hub.hpp" | ||||
| #include "catch_notimplemented_exception.hpp" | ||||
| #include "catch_context_impl.hpp" | ||||
| #include "catch_console_colour_impl.hpp" | ||||
| #include "catch_generators_impl.hpp" | ||||
| #include "catch_assertionresult.hpp" | ||||
| #include "catch_test_case_info.hpp" | ||||
| #include "catch_test_spec.hpp" | ||||
| #include "catch_version.hpp" | ||||
| #include "catch_message.hpp" | ||||
| #include "catch_legacy_reporter_adapter.hpp" | ||||
| #include "catch_timer.hpp" | ||||
| #include "catch_common.hpp" | ||||
| #include "catch_section.hpp" | ||||
| #include "catch_debugger.hpp" | ||||
| #include "catch_tostring.hpp" | ||||
| #include "catch_result_builder.hpp" | ||||
| #include "catch_tag_alias_registry.hpp" | ||||
| #include "catch_test_case_tracker.hpp" | ||||
| #include "catch_matchers_string.hpp" | ||||
| // Keep these here for external reporters | ||||
| #include "catch_test_spec.h" | ||||
| #include "catch_test_case_tracker.h" | ||||
|  | ||||
| #include "../reporters/catch_reporter_multi.hpp" | ||||
| #include "../reporters/catch_reporter_xml.hpp" | ||||
| #include "../reporters/catch_reporter_junit.hpp" | ||||
| #include "../reporters/catch_reporter_console.hpp" | ||||
| #include "../reporters/catch_reporter_compact.hpp" | ||||
| #include "catch_leak_detector.h" | ||||
|  | ||||
| // Cpp files will be included in the single-header file here | ||||
| // ~*~* CATCH_CPP_STITCH_PLACE *~*~ | ||||
|  | ||||
| namespace Catch { | ||||
|     // These are all here to avoid warnings about not having any out of line | ||||
|     // virtual methods | ||||
|     NonCopyable::~NonCopyable() {} | ||||
|     IShared::~IShared() {} | ||||
|     IStream::~IStream() CATCH_NOEXCEPT {} | ||||
|     FileStream::~FileStream() CATCH_NOEXCEPT {} | ||||
|     CoutStream::~CoutStream() CATCH_NOEXCEPT {} | ||||
|     DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} | ||||
|     StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} | ||||
|     IContext::~IContext() {} | ||||
|     IResultCapture::~IResultCapture() {} | ||||
|     ITestCase::~ITestCase() {} | ||||
|     ITestCaseRegistry::~ITestCaseRegistry() {} | ||||
|     IRegistryHub::~IRegistryHub() {} | ||||
|     IMutableRegistryHub::~IMutableRegistryHub() {} | ||||
|     IExceptionTranslator::~IExceptionTranslator() {} | ||||
|     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} | ||||
|     IReporter::~IReporter() {} | ||||
|     IReporterFactory::~IReporterFactory() {} | ||||
|     IReporterRegistry::~IReporterRegistry() {} | ||||
|     IStreamingReporter::~IStreamingReporter() {} | ||||
|     AssertionStats::~AssertionStats() {} | ||||
|     SectionStats::~SectionStats() {} | ||||
|     TestCaseStats::~TestCaseStats() {} | ||||
|     TestGroupStats::~TestGroupStats() {} | ||||
|     TestRunStats::~TestRunStats() {} | ||||
|     CumulativeReporterBase::SectionNode::~SectionNode() {} | ||||
|     CumulativeReporterBase::~CumulativeReporterBase() {} | ||||
|  | ||||
|     StreamingReporterBase::~StreamingReporterBase() {} | ||||
|     ConsoleReporter::~ConsoleReporter() {} | ||||
|     CompactReporter::~CompactReporter() {} | ||||
|     IRunner::~IRunner() {} | ||||
|     IMutableContext::~IMutableContext() {} | ||||
|     IConfig::~IConfig() {} | ||||
|     XmlReporter::~XmlReporter() {} | ||||
|     JunitReporter::~JunitReporter() {} | ||||
|     TestRegistry::~TestRegistry() {} | ||||
|     FreeFunctionTestCase::~FreeFunctionTestCase() {} | ||||
|     IGeneratorInfo::~IGeneratorInfo() {} | ||||
|     IGeneratorsForTest::~IGeneratorsForTest() {} | ||||
|     WildcardPattern::~WildcardPattern() {} | ||||
|     TestSpec::Pattern::~Pattern() {} | ||||
|     TestSpec::NamePattern::~NamePattern() {} | ||||
|     TestSpec::TagPattern::~TagPattern() {} | ||||
|     TestSpec::ExcludedPattern::~ExcludedPattern() {} | ||||
|     Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {} | ||||
|  | ||||
|     void Config::dummy() {} | ||||
|  | ||||
|     namespace TestCaseTracking { | ||||
|         ITracker::~ITracker() {} | ||||
|         TrackerBase::~TrackerBase() {} | ||||
|         SectionTracker::~SectionTracker() {} | ||||
|         IndexTracker::~IndexTracker() {} | ||||
|     } | ||||
|     LeakDetector leakDetector; | ||||
| } | ||||
|  | ||||
| #ifdef __clang__ | ||||
|   | ||||
							
								
								
									
										5
									
								
								include/internal/catch_interfaces_capture.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								include/internal/catch_interfaces_capture.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| #include "catch_interfaces_capture.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     IResultCapture::~IResultCapture() = default; | ||||
| } | ||||
| @@ -9,29 +9,34 @@ | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED | ||||
|  | ||||
| #include <string> | ||||
| #include "catch_result_type.h" | ||||
| #include "catch_common.h" | ||||
|  | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class TestCase; | ||||
|     class AssertionResult; | ||||
|     struct AssertionInfo; | ||||
|     struct SectionInfo; | ||||
|     struct SectionEndInfo; | ||||
|     struct MessageInfo; | ||||
|     class ScopedMessageBuilder; | ||||
|     struct Counts; | ||||
|     struct BenchmarkInfo; | ||||
|     struct BenchmarkStats; | ||||
|  | ||||
|     struct IResultCapture { | ||||
|  | ||||
|         virtual ~IResultCapture(); | ||||
|  | ||||
|         virtual void assertionStarting( AssertionInfo const& info ) = 0; | ||||
|         virtual void assertionEnded( AssertionResult const& result ) = 0; | ||||
|         virtual bool sectionStarted(    SectionInfo const& sectionInfo, | ||||
|                                         Counts& assertions ) = 0; | ||||
|         virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; | ||||
|         virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; | ||||
|  | ||||
|         virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; | ||||
|         virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0; | ||||
|  | ||||
|         virtual void pushScopedMessage( MessageInfo const& message ) = 0; | ||||
|         virtual void popScopedMessage( MessageInfo const& message ) = 0; | ||||
|  | ||||
| @@ -40,7 +45,7 @@ namespace Catch { | ||||
|  | ||||
|         virtual void exceptionEarlyReported() = 0; | ||||
|  | ||||
|         virtual void handleFatalErrorCondition( std::string const& message ) = 0; | ||||
|         virtual void handleFatalErrorCondition( StringRef message ) = 0; | ||||
|  | ||||
|         virtual bool lastAssertionPassed() = 0; | ||||
|         virtual void assertionPassed() = 0; | ||||
|   | ||||
							
								
								
									
										5
									
								
								include/internal/catch_interfaces_config.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								include/internal/catch_interfaces_config.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| #include "internal/catch_interfaces_config.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     IConfig::~IConfig() = default; | ||||
| } | ||||
| @@ -8,19 +8,20 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED | ||||
|  | ||||
| #include "catch_common.h" | ||||
|  | ||||
| #include <iosfwd> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| #include "catch_ptr.hpp" | ||||
| #include <memory> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct Verbosity { enum Level { | ||||
|         NoOutput = 0, | ||||
|         Quiet, | ||||
|         Normal | ||||
|     }; }; | ||||
|     enum class Verbosity { | ||||
|         Quiet = 0, | ||||
|         Normal, | ||||
|         High | ||||
|     }; | ||||
|  | ||||
|     struct WarnAbout { enum What { | ||||
|         Nothing = 0x00, | ||||
| @@ -51,7 +52,7 @@ namespace Catch { | ||||
|  | ||||
|     class TestSpec; | ||||
|  | ||||
|     struct IConfig : IShared { | ||||
|     struct IConfig : NonCopyable { | ||||
|  | ||||
|         virtual ~IConfig(); | ||||
|  | ||||
| @@ -67,10 +68,13 @@ namespace Catch { | ||||
|         virtual TestSpec const& testSpec() const = 0; | ||||
|         virtual RunTests::InWhatOrder runOrder() const = 0; | ||||
|         virtual unsigned int rngSeed() const = 0; | ||||
|         virtual int benchmarkResolutionMultiple() const = 0; | ||||
|         virtual UseColour::YesOrNo useColour() const = 0; | ||||
|         virtual std::vector<std::string> const& getSectionsToRun() const = 0; | ||||
|  | ||||
|         virtual Verbosity verbosity() const = 0; | ||||
|     }; | ||||
|  | ||||
|     using IConfigPtr = std::shared_ptr<IConfig const>; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED | ||||
|   | ||||
							
								
								
									
										6
									
								
								include/internal/catch_interfaces_exception.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/internal/catch_interfaces_exception.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #include "internal/catch_interfaces_exception.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     IExceptionTranslator::~IExceptionTranslator() = default; | ||||
|     IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default; | ||||
| } | ||||
| @@ -8,17 +8,22 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
|  | ||||
| #if defined(CATCH_CONFIG_DISABLE) | ||||
|     #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \ | ||||
|         static std::string translatorName( signature ) | ||||
| #endif | ||||
|  | ||||
| #include <exception> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     typedef std::string(*exceptionTranslateFunction)(); | ||||
|     using exceptionTranslateFunction = std::string(*)(); | ||||
|  | ||||
|     struct IExceptionTranslator; | ||||
|     typedef std::vector<const IExceptionTranslator*> ExceptionTranslators; | ||||
|     using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>; | ||||
|  | ||||
|     struct IExceptionTranslator { | ||||
|         virtual ~IExceptionTranslator(); | ||||
| @@ -40,10 +45,10 @@ namespace Catch { | ||||
|             : m_translateFunction( translateFunction ) | ||||
|             {} | ||||
|  | ||||
|             virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { | ||||
|             std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override { | ||||
|                 try { | ||||
|                     if( it == itEnd ) | ||||
|                         throw; | ||||
|                         std::rethrow_exception(std::current_exception()); | ||||
|                     else | ||||
|                         return (*it)->translate( it+1, itEnd ); | ||||
|                 } | ||||
|   | ||||
| @@ -1,32 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 7/8/2012. | ||||
|  *  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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct IGeneratorInfo { | ||||
|         virtual ~IGeneratorInfo(); | ||||
|         virtual bool moveNext() = 0; | ||||
|         virtual std::size_t getCurrentIndex() const = 0; | ||||
|     }; | ||||
|  | ||||
|     struct IGeneratorsForTest { | ||||
|         virtual ~IGeneratorsForTest(); | ||||
|  | ||||
|         virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; | ||||
|         virtual bool moveNext() = 0; | ||||
|     }; | ||||
|  | ||||
|     IGeneratorsForTest* createGeneratorsForTest(); | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED | ||||
							
								
								
									
										6
									
								
								include/internal/catch_interfaces_registry_hub.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/internal/catch_interfaces_registry_hub.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #include "internal/catch_interfaces_registry_hub.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     IRegistryHub::~IRegistryHub() = default; | ||||
|     IMutableRegistryHub::~IMutableRegistryHub() = default; | ||||
| } | ||||
| @@ -8,9 +8,10 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED | ||||
|  | ||||
| #include "catch_ptr.hpp" | ||||
| #include "catch_common.h" | ||||
|  | ||||
| #include <string> | ||||
| #include <memory> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -21,6 +22,9 @@ namespace Catch { | ||||
|     struct IReporterRegistry; | ||||
|     struct IReporterFactory; | ||||
|     struct ITagAliasRegistry; | ||||
|     class StartupExceptionRegistry; | ||||
|  | ||||
|     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; | ||||
|  | ||||
|     struct IRegistryHub { | ||||
|         virtual ~IRegistryHub(); | ||||
| @@ -30,15 +34,19 @@ namespace Catch { | ||||
|         virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; | ||||
|  | ||||
|         virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; | ||||
|  | ||||
|  | ||||
|         virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0; | ||||
|     }; | ||||
|  | ||||
|     struct IMutableRegistryHub { | ||||
|         virtual ~IMutableRegistryHub(); | ||||
|         virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0; | ||||
|         virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0; | ||||
|         virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0; | ||||
|         virtual void registerListener( IReporterFactoryPtr const& factory ) = 0; | ||||
|         virtual void registerTest( TestCase const& testInfo ) = 0; | ||||
|         virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; | ||||
|         virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; | ||||
|         virtual void registerStartupException() noexcept = 0; | ||||
|     }; | ||||
|  | ||||
|     IRegistryHub& getRegistryHub(); | ||||
|   | ||||
							
								
								
									
										135
									
								
								include/internal/catch_interfaces_reporter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								include/internal/catch_interfaces_reporter.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| /* | ||||
|  *  Created by Martin on 19/07/2017. | ||||
|  * | ||||
|  *  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_interfaces_reporter.h" | ||||
| #include "../reporters/catch_reporter_multi.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig ) | ||||
|     :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} | ||||
|  | ||||
|     ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ) | ||||
|     :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {} | ||||
|  | ||||
|     std::ostream& ReporterConfig::stream() const { return *m_stream; } | ||||
|     IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; } | ||||
|  | ||||
|  | ||||
|     TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {} | ||||
|  | ||||
|     GroupInfo::GroupInfo(  std::string const& _name, | ||||
|                            std::size_t _groupIndex, | ||||
|                            std::size_t _groupsCount ) | ||||
|     :   name( _name ), | ||||
|         groupIndex( _groupIndex ), | ||||
|         groupsCounts( _groupsCount ) | ||||
|     {} | ||||
|  | ||||
|      AssertionStats::AssertionStats( AssertionResult const& _assertionResult, | ||||
|                                      std::vector<MessageInfo> const& _infoMessages, | ||||
|                                      Totals const& _totals ) | ||||
|     :   assertionResult( _assertionResult ), | ||||
|         infoMessages( _infoMessages ), | ||||
|         totals( _totals ) | ||||
|     { | ||||
|         assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression; | ||||
|  | ||||
|         if( assertionResult.hasMessage() ) { | ||||
|             // Copy message into messages list. | ||||
|             // !TBD This should have been done earlier, somewhere | ||||
|             MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); | ||||
|             builder << assertionResult.getMessage(); | ||||
|             builder.m_info.message = builder.m_stream.str(); | ||||
|  | ||||
|             infoMessages.push_back( builder.m_info ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|      AssertionStats::~AssertionStats() = default; | ||||
|  | ||||
|     SectionStats::SectionStats(  SectionInfo const& _sectionInfo, | ||||
|                                  Counts const& _assertions, | ||||
|                                  double _durationInSeconds, | ||||
|                                  bool _missingAssertions ) | ||||
|     :   sectionInfo( _sectionInfo ), | ||||
|         assertions( _assertions ), | ||||
|         durationInSeconds( _durationInSeconds ), | ||||
|         missingAssertions( _missingAssertions ) | ||||
|     {} | ||||
|  | ||||
|     SectionStats::~SectionStats() = default; | ||||
|  | ||||
|  | ||||
|     TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo, | ||||
|                                    Totals const& _totals, | ||||
|                                    std::string const& _stdOut, | ||||
|                                    std::string const& _stdErr, | ||||
|                                    bool _aborting ) | ||||
|     : testInfo( _testInfo ), | ||||
|         totals( _totals ), | ||||
|         stdOut( _stdOut ), | ||||
|         stdErr( _stdErr ), | ||||
|         aborting( _aborting ) | ||||
|     {} | ||||
|  | ||||
|     TestCaseStats::~TestCaseStats() = default; | ||||
|  | ||||
|  | ||||
|     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo, | ||||
|                                     Totals const& _totals, | ||||
|                                     bool _aborting ) | ||||
|     :   groupInfo( _groupInfo ), | ||||
|         totals( _totals ), | ||||
|         aborting( _aborting ) | ||||
|     {} | ||||
|  | ||||
|     TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo ) | ||||
|     :   groupInfo( _groupInfo ), | ||||
|         aborting( false ) | ||||
|     {} | ||||
|  | ||||
|     TestGroupStats::~TestGroupStats() = default; | ||||
|  | ||||
|     TestRunStats::TestRunStats(   TestRunInfo const& _runInfo, | ||||
|                     Totals const& _totals, | ||||
|                     bool _aborting ) | ||||
|     :   runInfo( _runInfo ), | ||||
|         totals( _totals ), | ||||
|         aborting( _aborting ) | ||||
|     {} | ||||
|  | ||||
|     TestRunStats::~TestRunStats() = default; | ||||
|  | ||||
|     void IStreamingReporter::fatalErrorEncountered( StringRef ) {} | ||||
|     bool IStreamingReporter::isMulti() const { return false; } | ||||
|  | ||||
|     IReporterFactory::~IReporterFactory() = default; | ||||
|     IReporterRegistry::~IReporterRegistry() = default; | ||||
|  | ||||
|     void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ) { | ||||
|  | ||||
|         if( !existingReporter ) { | ||||
|             existingReporter = std::move( additionalReporter ); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         MultipleReporters* multi = nullptr; | ||||
|  | ||||
|         if( existingReporter->isMulti() ) { | ||||
|             multi = static_cast<MultipleReporters*>( existingReporter.get() ); | ||||
|         } | ||||
|         else { | ||||
|             auto newMulti = std::unique_ptr<MultipleReporters>( new MultipleReporters ); | ||||
|             newMulti->add( std::move( existingReporter ) ); | ||||
|             multi = newMulti.get(); | ||||
|             existingReporter = std::move( newMulti ); | ||||
|         } | ||||
|         multi->add( std::move( additionalReporter ) ); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
| @@ -10,46 +10,42 @@ | ||||
|  | ||||
| #include "catch_section_info.h" | ||||
| #include "catch_common.h" | ||||
| #include "catch_totals.hpp" | ||||
| #include "catch_ptr.hpp" | ||||
| #include "catch_config.hpp" | ||||
| #include "catch_totals.h" | ||||
| #include "catch_test_case_info.h" | ||||
| #include "catch_assertionresult.h" | ||||
| #include "catch_message.h" | ||||
| #include "catch_option.hpp" | ||||
| #include "catch_stringref.h" | ||||
|  | ||||
|  | ||||
| #include <string> | ||||
| #include <ostream> | ||||
| #include <iosfwd> | ||||
| #include <map> | ||||
| #include <set> | ||||
| #include <memory> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| namespace Catch | ||||
| { | ||||
|     struct ReporterConfig { | ||||
|         explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig ) | ||||
|         :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} | ||||
|         explicit ReporterConfig( IConfigPtr const& _fullConfig ); | ||||
|  | ||||
|         ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream ) | ||||
|         :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {} | ||||
|         ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ); | ||||
|  | ||||
|         std::ostream& stream() const    { return *m_stream; } | ||||
|         Ptr<IConfig const> fullConfig() const { return m_fullConfig; } | ||||
|         std::ostream& stream() const; | ||||
|         IConfigPtr fullConfig() const; | ||||
|  | ||||
|     private: | ||||
|         std::ostream* m_stream; | ||||
|         Ptr<IConfig const> m_fullConfig; | ||||
|         IConfigPtr m_fullConfig; | ||||
|     }; | ||||
|  | ||||
|     struct ReporterPreferences { | ||||
|         ReporterPreferences() | ||||
|         : shouldRedirectStdOut( false ) | ||||
|         {} | ||||
|  | ||||
|         bool shouldRedirectStdOut; | ||||
|         bool shouldRedirectStdOut = false; | ||||
|     }; | ||||
|  | ||||
|     template<typename T> | ||||
|     struct LazyStat : Option<T> { | ||||
|         LazyStat() : used( false ) {} | ||||
|         LazyStat& operator=( T const& _value ) { | ||||
|             Option<T>::operator=( _value ); | ||||
|             used = false; | ||||
| @@ -59,21 +55,17 @@ namespace Catch | ||||
|             Option<T>::reset(); | ||||
|             used = false; | ||||
|         } | ||||
|         bool used; | ||||
|         bool used = false; | ||||
|     }; | ||||
|  | ||||
|     struct TestRunInfo { | ||||
|         TestRunInfo( std::string const& _name ) : name( _name ) {} | ||||
|         TestRunInfo( std::string const& _name ); | ||||
|         std::string name; | ||||
|     }; | ||||
|     struct GroupInfo { | ||||
|         GroupInfo(  std::string const& _name, | ||||
|                     std::size_t _groupIndex, | ||||
|                     std::size_t _groupsCount ) | ||||
|         :   name( _name ), | ||||
|             groupIndex( _groupIndex ), | ||||
|             groupsCounts( _groupsCount ) | ||||
|         {} | ||||
|                     std::size_t _groupsCount ); | ||||
|  | ||||
|         std::string name; | ||||
|         std::size_t groupIndex; | ||||
| @@ -83,29 +75,13 @@ namespace Catch | ||||
|     struct AssertionStats { | ||||
|         AssertionStats( AssertionResult const& _assertionResult, | ||||
|                         std::vector<MessageInfo> const& _infoMessages, | ||||
|                         Totals const& _totals ) | ||||
|         :   assertionResult( _assertionResult ), | ||||
|             infoMessages( _infoMessages ), | ||||
|             totals( _totals ) | ||||
|         { | ||||
|             if( assertionResult.hasMessage() ) { | ||||
|                 // Copy message into messages list. | ||||
|                 // !TBD This should have been done earlier, somewhere | ||||
|                 MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); | ||||
|                 builder << assertionResult.getMessage(); | ||||
|                 builder.m_info.message = builder.m_stream.str(); | ||||
|                         Totals const& _totals ); | ||||
|  | ||||
|                 infoMessages.push_back( builder.m_info ); | ||||
|             } | ||||
|         } | ||||
|         virtual ~AssertionStats(); | ||||
|  | ||||
| #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|         AssertionStats( AssertionStats const& )              = default; | ||||
|         AssertionStats( AssertionStats && )                  = default; | ||||
|         AssertionStats& operator = ( AssertionStats const& ) = default; | ||||
|         AssertionStats& operator = ( AssertionStats && )     = default; | ||||
| #  endif | ||||
|         virtual ~AssertionStats(); | ||||
|  | ||||
|         AssertionResult assertionResult; | ||||
|         std::vector<MessageInfo> infoMessages; | ||||
| @@ -116,19 +92,12 @@ namespace Catch | ||||
|         SectionStats(   SectionInfo const& _sectionInfo, | ||||
|                         Counts const& _assertions, | ||||
|                         double _durationInSeconds, | ||||
|                         bool _missingAssertions ) | ||||
|         :   sectionInfo( _sectionInfo ), | ||||
|             assertions( _assertions ), | ||||
|             durationInSeconds( _durationInSeconds ), | ||||
|             missingAssertions( _missingAssertions ) | ||||
|         {} | ||||
|         virtual ~SectionStats(); | ||||
| #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|                         bool _missingAssertions ); | ||||
|         SectionStats( SectionStats const& )              = default; | ||||
|         SectionStats( SectionStats && )                  = default; | ||||
|         SectionStats& operator = ( SectionStats const& ) = default; | ||||
|         SectionStats& operator = ( SectionStats && )     = default; | ||||
| #  endif | ||||
|         virtual ~SectionStats(); | ||||
|  | ||||
|         SectionInfo sectionInfo; | ||||
|         Counts assertions; | ||||
| @@ -141,21 +110,13 @@ namespace Catch | ||||
|                         Totals const& _totals, | ||||
|                         std::string const& _stdOut, | ||||
|                         std::string const& _stdErr, | ||||
|                         bool _aborting ) | ||||
|         : testInfo( _testInfo ), | ||||
|             totals( _totals ), | ||||
|             stdOut( _stdOut ), | ||||
|             stdErr( _stdErr ), | ||||
|             aborting( _aborting ) | ||||
|         {} | ||||
|         virtual ~TestCaseStats(); | ||||
|                         bool _aborting ); | ||||
|  | ||||
| #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|         TestCaseStats( TestCaseStats const& )              = default; | ||||
|         TestCaseStats( TestCaseStats && )                  = default; | ||||
|         TestCaseStats& operator = ( TestCaseStats const& ) = default; | ||||
|         TestCaseStats& operator = ( TestCaseStats && )     = default; | ||||
| #  endif | ||||
|         virtual ~TestCaseStats(); | ||||
|  | ||||
|         TestCaseInfo testInfo; | ||||
|         Totals totals; | ||||
| @@ -167,23 +128,14 @@ namespace Catch | ||||
|     struct TestGroupStats { | ||||
|         TestGroupStats( GroupInfo const& _groupInfo, | ||||
|                         Totals const& _totals, | ||||
|                         bool _aborting ) | ||||
|         :   groupInfo( _groupInfo ), | ||||
|             totals( _totals ), | ||||
|             aborting( _aborting ) | ||||
|         {} | ||||
|         TestGroupStats( GroupInfo const& _groupInfo ) | ||||
|         :   groupInfo( _groupInfo ), | ||||
|             aborting( false ) | ||||
|         {} | ||||
|         virtual ~TestGroupStats(); | ||||
|                         bool _aborting ); | ||||
|         TestGroupStats( GroupInfo const& _groupInfo ); | ||||
|  | ||||
| #  ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|         TestGroupStats( TestGroupStats const& )              = default; | ||||
|         TestGroupStats( TestGroupStats && )                  = default; | ||||
|         TestGroupStats& operator = ( TestGroupStats const& ) = default; | ||||
|         TestGroupStats& operator = ( TestGroupStats && )     = default; | ||||
| #  endif | ||||
|         virtual ~TestGroupStats(); | ||||
|  | ||||
|         GroupInfo groupInfo; | ||||
|         Totals totals; | ||||
| @@ -193,38 +145,34 @@ namespace Catch | ||||
|     struct TestRunStats { | ||||
|         TestRunStats(   TestRunInfo const& _runInfo, | ||||
|                         Totals const& _totals, | ||||
|                         bool _aborting ) | ||||
|         :   runInfo( _runInfo ), | ||||
|             totals( _totals ), | ||||
|             aborting( _aborting ) | ||||
|         {} | ||||
|         virtual ~TestRunStats(); | ||||
|                         bool _aborting ); | ||||
|  | ||||
| #  ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS | ||||
|         TestRunStats( TestRunStats const& _other ) | ||||
|         :   runInfo( _other.runInfo ), | ||||
|             totals( _other.totals ), | ||||
|             aborting( _other.aborting ) | ||||
|         {} | ||||
| #  else | ||||
|         TestRunStats( TestRunStats const& )              = default; | ||||
|         TestRunStats( TestRunStats && )                  = default; | ||||
|         TestRunStats& operator = ( TestRunStats const& ) = default; | ||||
|         TestRunStats& operator = ( TestRunStats && )     = default; | ||||
| #  endif | ||||
|         virtual ~TestRunStats(); | ||||
|  | ||||
|         TestRunInfo runInfo; | ||||
|         Totals totals; | ||||
|         bool aborting; | ||||
|     }; | ||||
|  | ||||
|     class MultipleReporters; | ||||
|     struct BenchmarkInfo { | ||||
|         std::string name; | ||||
|     }; | ||||
|     struct BenchmarkStats { | ||||
|         BenchmarkInfo info; | ||||
|         std::size_t iterations; | ||||
|         uint64_t elapsedTimeInNanoseconds; | ||||
|     }; | ||||
|  | ||||
|     struct IStreamingReporter : IShared { | ||||
|         virtual ~IStreamingReporter(); | ||||
|     struct IStreamingReporter { | ||||
|         virtual ~IStreamingReporter() = default; | ||||
|  | ||||
|         // Implementing class must also provide the following static method: | ||||
|         // Implementing class must also provide the following static methods: | ||||
|         // static std::string getDescription(); | ||||
|         // static std::set<Verbosity> getSupportedVerbosities() | ||||
|  | ||||
|         virtual ReporterPreferences getPreferences() const = 0; | ||||
|  | ||||
| @@ -236,11 +184,17 @@ namespace Catch | ||||
|         virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; | ||||
|         virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; | ||||
|  | ||||
|         // *** experimental *** | ||||
|         virtual void benchmarkStarting( BenchmarkInfo const& ) {} | ||||
|  | ||||
|         virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; | ||||
|  | ||||
|         // The return value indicates if the messages buffer should be cleared: | ||||
|         virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; | ||||
|  | ||||
|         // *** experimental *** | ||||
|         virtual void benchmarkEnded( BenchmarkStats const& ) {} | ||||
|  | ||||
|         virtual void sectionEnded( SectionStats const& sectionStats ) = 0; | ||||
|         virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; | ||||
|         virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; | ||||
| @@ -248,28 +202,32 @@ namespace Catch | ||||
|  | ||||
|         virtual void skipTest( TestCaseInfo const& testInfo ) = 0; | ||||
|  | ||||
|         virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } | ||||
|         // Default empty implementation provided | ||||
|         virtual void fatalErrorEncountered( StringRef name ); | ||||
|  | ||||
|         virtual bool isMulti() const; | ||||
|     }; | ||||
|     using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>; | ||||
|  | ||||
|  | ||||
|     struct IReporterFactory : IShared { | ||||
|     struct IReporterFactory { | ||||
|         virtual ~IReporterFactory(); | ||||
|         virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; | ||||
|         virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0; | ||||
|         virtual std::string getDescription() const = 0; | ||||
|     }; | ||||
|     using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>; | ||||
|  | ||||
|     struct IReporterRegistry { | ||||
|         typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap; | ||||
|         typedef std::vector<Ptr<IReporterFactory> > Listeners; | ||||
|         using FactoryMap = std::map<std::string, IReporterFactoryPtr>; | ||||
|         using Listeners = std::vector<IReporterFactoryPtr>; | ||||
|  | ||||
|         virtual ~IReporterRegistry(); | ||||
|         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0; | ||||
|         virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0; | ||||
|         virtual FactoryMap const& getFactories() const = 0; | ||||
|         virtual Listeners const& getListeners() const = 0; | ||||
|     }; | ||||
|  | ||||
|     Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ); | ||||
|     void addReporter( IStreamingReporterPtr& existingReporter, IStreamingReporterPtr&& additionalReporter ); | ||||
|  | ||||
| } | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED | ||||
|   | ||||
							
								
								
									
										5
									
								
								include/internal/catch_interfaces_runner.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								include/internal/catch_interfaces_runner.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| #include "internal/catch_interfaces_runner.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     IRunner::~IRunner() = default; | ||||
| } | ||||
| @@ -9,7 +9,6 @@ | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED | ||||
|  | ||||
| namespace Catch { | ||||
|     class TestCase; | ||||
|  | ||||
|     struct IRunner { | ||||
|         virtual ~IRunner(); | ||||
|   | ||||
| @@ -8,14 +8,16 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED | ||||
|  | ||||
| #include "catch_tag_alias.h" | ||||
| #include "catch_option.hpp" | ||||
| #include <string> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct TagAlias; | ||||
|  | ||||
|     struct ITagAliasRegistry { | ||||
|         virtual ~ITagAliasRegistry(); | ||||
|         virtual Option<TagAlias> find( std::string const& alias ) const = 0; | ||||
|         // Nullptr if not present | ||||
|         virtual TagAlias const* find( std::string const& alias ) const = 0; | ||||
|         virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; | ||||
|  | ||||
|         static ITagAliasRegistry const& get(); | ||||
|   | ||||
							
								
								
									
										6
									
								
								include/internal/catch_interfaces_testcase.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/internal/catch_interfaces_testcase.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #include "internal/catch_interfaces_testcase.h" | ||||
|  | ||||
| namespace Catch { | ||||
|     ITestInvoker::~ITestInvoker() = default; | ||||
|     ITestCaseRegistry::~ITestCaseRegistry() = default; | ||||
| } | ||||
| @@ -8,20 +8,20 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED | ||||
|  | ||||
| #include "catch_ptr.hpp" | ||||
|  | ||||
| #include <vector> | ||||
| #include <memory> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class TestSpec; | ||||
|  | ||||
|     struct ITestCase : IShared { | ||||
|     struct ITestInvoker { | ||||
|         virtual void invoke () const = 0; | ||||
|     protected: | ||||
|         virtual ~ITestCase(); | ||||
|         virtual ~ITestInvoker(); | ||||
|     }; | ||||
|  | ||||
|     using ITestCasePtr = std::shared_ptr<ITestInvoker>; | ||||
|  | ||||
|     class TestCase; | ||||
|     struct IConfig; | ||||
|  | ||||
|   | ||||
							
								
								
									
										33
									
								
								include/internal/catch_leak_detector.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								include/internal/catch_leak_detector.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| /* | ||||
|  *  Created by Martin on 12/07/2017. | ||||
|  * | ||||
|  *  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_leak_detector.h" | ||||
|  | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| #ifdef CATCH_CONFIG_WINDOWS_CRTDBG | ||||
| #include <crtdbg.h> | ||||
|  | ||||
| 	LeakDetector::LeakDetector() { | ||||
| 		int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); | ||||
| 		flag |= _CRTDBG_LEAK_CHECK_DF; | ||||
| 		flag |= _CRTDBG_ALLOC_MEM_DF; | ||||
| 		_CrtSetDbgFlag(flag); | ||||
| 		_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); | ||||
| 		_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); | ||||
| 		// Change this to leaking allocation's number to break there | ||||
| 		_CrtSetBreakAlloc(-1); | ||||
| 	} | ||||
|  | ||||
| #else | ||||
|  | ||||
|     LeakDetector::LeakDetector(){} | ||||
|  | ||||
| #endif | ||||
|  | ||||
| } | ||||
							
								
								
									
										17
									
								
								include/internal/catch_leak_detector.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/internal/catch_leak_detector.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| /* | ||||
|  *  Created by Martin on 12/07/2017. | ||||
|  * | ||||
|  *  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_LEAK_DETECTOR_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_LEAK_DETECTOR_H_INCLUDED | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct LeakDetector { | ||||
|         LeakDetector(); | ||||
|     }; | ||||
|  | ||||
| } | ||||
| #endif // TWOBLUECUBES_CATCH_LEAK_DETECTOR_H_INCLUDED | ||||
| @@ -1,60 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 6th April 2013. | ||||
|  *  Copyright 2013 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_LEGACY_REPORTER_ADAPTER_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_reporter.h" | ||||
|  | ||||
| namespace Catch | ||||
| { | ||||
|     // Deprecated | ||||
|     struct IReporter : IShared { | ||||
|         virtual ~IReporter(); | ||||
|  | ||||
|         virtual bool shouldRedirectStdout() const = 0; | ||||
|  | ||||
|         virtual void StartTesting() = 0; | ||||
|         virtual void EndTesting( Totals const& totals ) = 0; | ||||
|         virtual void StartGroup( std::string const& groupName ) = 0; | ||||
|         virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; | ||||
|         virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; | ||||
|         virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; | ||||
|         virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; | ||||
|         virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; | ||||
|         virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; | ||||
|         virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; | ||||
|         virtual void Aborted() = 0; | ||||
|         virtual void Result( AssertionResult const& result ) = 0; | ||||
|     }; | ||||
|  | ||||
|     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter> | ||||
|     { | ||||
|     public: | ||||
|         LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter ); | ||||
|         virtual ~LegacyReporterAdapter(); | ||||
|  | ||||
|         virtual ReporterPreferences getPreferences() const; | ||||
|         virtual void noMatchingTestCases( std::string const& ); | ||||
|         virtual void testRunStarting( TestRunInfo const& ); | ||||
|         virtual void testGroupStarting( GroupInfo const& groupInfo ); | ||||
|         virtual void testCaseStarting( TestCaseInfo const& testInfo ); | ||||
|         virtual void sectionStarting( SectionInfo const& sectionInfo ); | ||||
|         virtual void assertionStarting( AssertionInfo const& ); | ||||
|         virtual bool assertionEnded( AssertionStats const& assertionStats ); | ||||
|         virtual void sectionEnded( SectionStats const& sectionStats ); | ||||
|         virtual void testCaseEnded( TestCaseStats const& testCaseStats ); | ||||
|         virtual void testGroupEnded( TestGroupStats const& testGroupStats ); | ||||
|         virtual void testRunEnded( TestRunStats const& testRunStats ); | ||||
|         virtual void skipTest( TestCaseInfo const& ); | ||||
|  | ||||
|     private: | ||||
|         Ptr<IReporter> m_legacyReporter; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED | ||||
| @@ -1,84 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 6th April 2013. | ||||
|  *  Copyright 2013 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_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_legacy_reporter_adapter.h" | ||||
|  | ||||
| namespace Catch | ||||
| { | ||||
|     LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter ) | ||||
|     :   m_legacyReporter( legacyReporter ) | ||||
|     {} | ||||
|     LegacyReporterAdapter::~LegacyReporterAdapter() {} | ||||
|  | ||||
|     ReporterPreferences LegacyReporterAdapter::getPreferences() const { | ||||
|         ReporterPreferences prefs; | ||||
|         prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); | ||||
|         return prefs; | ||||
|     } | ||||
|  | ||||
|     void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} | ||||
|     void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { | ||||
|         m_legacyReporter->StartTesting(); | ||||
|     } | ||||
|     void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { | ||||
|         m_legacyReporter->StartGroup( groupInfo.name ); | ||||
|     } | ||||
|     void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { | ||||
|         m_legacyReporter->StartTestCase( testInfo ); | ||||
|     } | ||||
|     void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { | ||||
|         m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); | ||||
|     } | ||||
|     void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { | ||||
|         // Not on legacy interface | ||||
|     } | ||||
|  | ||||
|     bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { | ||||
|         if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { | ||||
|             for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); | ||||
|                     it != itEnd; | ||||
|                     ++it ) { | ||||
|                 if( it->type == ResultWas::Info ) { | ||||
|                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); | ||||
|                     rb << it->message; | ||||
|                     rb.setResultType( ResultWas::Info ); | ||||
|                     AssertionResult result = rb.build(); | ||||
|                     m_legacyReporter->Result( result ); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         m_legacyReporter->Result( assertionStats.assertionResult ); | ||||
|         return true; | ||||
|     } | ||||
|     void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { | ||||
|         if( sectionStats.missingAssertions ) | ||||
|             m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); | ||||
|         m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); | ||||
|     } | ||||
|     void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { | ||||
|         m_legacyReporter->EndTestCase | ||||
|             (   testCaseStats.testInfo, | ||||
|                 testCaseStats.totals, | ||||
|                 testCaseStats.stdOut, | ||||
|                 testCaseStats.stdErr ); | ||||
|     } | ||||
|     void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { | ||||
|         if( testGroupStats.aborting ) | ||||
|             m_legacyReporter->Aborted(); | ||||
|         m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); | ||||
|     } | ||||
|     void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { | ||||
|         m_legacyReporter->EndTesting( testRunStats.totals ); | ||||
|     } | ||||
|     void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED | ||||
							
								
								
									
										165
									
								
								include/internal/catch_list.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								include/internal/catch_list.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| /* | ||||
|  *  Created by Phil on 5/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_list.h" | ||||
|  | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
| #include "catch_interfaces_reporter.h" | ||||
| #include "catch_interfaces_testcase.h" | ||||
|  | ||||
| #include "catch_stream.h" | ||||
| #include "catch_text.h" | ||||
|  | ||||
| #include "catch_console_colour.h" | ||||
| #include "catch_test_spec_parser.h" | ||||
| #include "catch_tostring.h" | ||||
| #include "catch_string_manip.h" | ||||
|  | ||||
| #include <limits> | ||||
| #include <algorithm> | ||||
| #include <iomanip> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     std::size_t listTests( Config const& config ) { | ||||
|         TestSpec testSpec = config.testSpec(); | ||||
|         if( config.testSpec().hasFilters() ) | ||||
|             Catch::cout() << "Matching test cases:\n"; | ||||
|         else { | ||||
|             Catch::cout() << "All available test cases:\n"; | ||||
|             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); | ||||
|         } | ||||
|  | ||||
|         auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); | ||||
|         for( auto const& testCaseInfo : matchedTestCases ) { | ||||
|             Colour::Code colour = testCaseInfo.isHidden() | ||||
|                 ? Colour::SecondaryText | ||||
|                 : Colour::None; | ||||
|             Colour colourGuard( colour ); | ||||
|  | ||||
|             Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n"; | ||||
|             if( config.verbosity() >= Verbosity::High ) { | ||||
|                 Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl; | ||||
|                 std::string description = testCaseInfo.description; | ||||
|                 if( description.empty() ) | ||||
|                     description = "(NO DESCRIPTION)"; | ||||
|                 Catch::cout() << Column( description ).indent(4) << std::endl; | ||||
|             } | ||||
|             if( !testCaseInfo.tags.empty() ) | ||||
|                 Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n"; | ||||
|         } | ||||
|  | ||||
|         if( !config.testSpec().hasFilters() ) | ||||
|             Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl; | ||||
|         else | ||||
|             Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl; | ||||
|         return matchedTestCases.size(); | ||||
|     } | ||||
|  | ||||
|     std::size_t listTestsNamesOnly( Config const& config ) { | ||||
|         TestSpec testSpec = config.testSpec(); | ||||
|         if( !config.testSpec().hasFilters() ) | ||||
|             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); | ||||
|         std::size_t matchedTests = 0; | ||||
|         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); | ||||
|         for( auto const& testCaseInfo : matchedTestCases ) { | ||||
|             matchedTests++; | ||||
|             if( startsWith( testCaseInfo.name, '#' ) ) | ||||
|                Catch::cout() << '"' << testCaseInfo.name << '"'; | ||||
|             else | ||||
|                Catch::cout() << testCaseInfo.name; | ||||
|             if ( config.verbosity() >= Verbosity::High ) | ||||
|                 Catch::cout() << "\t@" << testCaseInfo.lineInfo; | ||||
|             Catch::cout() << std::endl; | ||||
|         } | ||||
|         return matchedTests; | ||||
|     } | ||||
|  | ||||
|     void TagInfo::add( std::string const& spelling ) { | ||||
|         ++count; | ||||
|         spellings.insert( spelling ); | ||||
|     } | ||||
|  | ||||
|     std::string TagInfo::all() const { | ||||
|         std::string out; | ||||
|         for( auto const& spelling : spellings ) | ||||
|             out += "[" + spelling + "]"; | ||||
|         return out; | ||||
|     } | ||||
|  | ||||
|     std::size_t listTags( Config const& config ) { | ||||
|         TestSpec testSpec = config.testSpec(); | ||||
|         if( config.testSpec().hasFilters() ) | ||||
|             Catch::cout() << "Tags for matching test cases:\n"; | ||||
|         else { | ||||
|             Catch::cout() << "All available tags:\n"; | ||||
|             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); | ||||
|         } | ||||
|  | ||||
|         std::map<std::string, TagInfo> tagCounts; | ||||
|  | ||||
|         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); | ||||
|         for( auto const& testCase : matchedTestCases ) { | ||||
|             for( auto const& tagName : testCase.getTestCaseInfo().tags ) { | ||||
|                 std::string lcaseTagName = toLower( tagName ); | ||||
|                 auto countIt = tagCounts.find( lcaseTagName ); | ||||
|                 if( countIt == tagCounts.end() ) | ||||
|                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; | ||||
|                 countIt->second.add( tagName ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for( auto const& tagCount : tagCounts ) { | ||||
|             std::ostringstream oss; | ||||
|             oss << "  " << std::setw(2) << tagCount.second.count << "  "; | ||||
|             auto wrapper = Column( tagCount.second.all() ) | ||||
|                                                     .initialIndent( 0 ) | ||||
|                                                     .indent( oss.str().size() ) | ||||
|                                                     .width( CATCH_CONFIG_CONSOLE_WIDTH-10 ); | ||||
|             Catch::cout() << oss.str() << wrapper << '\n'; | ||||
|         } | ||||
|         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; | ||||
|         return tagCounts.size(); | ||||
|     } | ||||
|  | ||||
|     std::size_t listReporters( Config const& /*config*/ ) { | ||||
|         Catch::cout() << "Available reporters:\n"; | ||||
|         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); | ||||
|         std::size_t maxNameLen = 0; | ||||
|         for( auto const& factoryKvp : factories ) | ||||
|             maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() ); | ||||
|  | ||||
|         for( auto const& factoryKvp : factories ) { | ||||
|             Catch::cout() | ||||
|                     << Column( factoryKvp.first + ":" ) | ||||
|                             .indent(2) | ||||
|                             .width( 5+maxNameLen ) | ||||
|                     +  Column( factoryKvp.second->getDescription() ) | ||||
|                             .initialIndent(0) | ||||
|                             .indent(2) | ||||
|                             .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) | ||||
|                     << "\n"; | ||||
|         } | ||||
|         Catch::cout() << std::endl; | ||||
|         return factories.size(); | ||||
|     } | ||||
|  | ||||
|     Option<std::size_t> list( Config const& config ) { | ||||
|         Option<std::size_t> listedCount; | ||||
|         if( config.listTests() ) | ||||
|             listedCount = listedCount.valueOr(0) + listTests( config ); | ||||
|         if( config.listTestNamesOnly() ) | ||||
|             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); | ||||
|         if( config.listTags() ) | ||||
|             listedCount = listedCount.valueOr(0) + listTags( config ); | ||||
|         if( config.listReporters() ) | ||||
|             listedCount = listedCount.valueOr(0) + listReporters( config ); | ||||
|         return listedCount; | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
							
								
								
									
										38
									
								
								include/internal/catch_list.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								include/internal/catch_list.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|  *  Created by Phil on 5/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_LIST_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_LIST_H_INCLUDED | ||||
|  | ||||
| #include "catch_option.hpp" | ||||
| #include "catch_config.hpp" | ||||
|  | ||||
| #include <set> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     std::size_t listTests( Config const& config ); | ||||
|  | ||||
|     std::size_t listTestsNamesOnly( Config const& config ); | ||||
|  | ||||
|     struct TagInfo { | ||||
|         void add( std::string const& spelling ); | ||||
|         std::string all() const; | ||||
|  | ||||
|         std::set<std::string> spellings; | ||||
|         std::size_t count = 0; | ||||
|     }; | ||||
|  | ||||
|     std::size_t listTags( Config const& config ); | ||||
|  | ||||
|     std::size_t listReporters( Config const& /*config*/ ); | ||||
|      | ||||
|     Option<std::size_t> list( Config const& config ); | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_LIST_H_INCLUDED | ||||
| @@ -1,190 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 5/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_commandline.hpp" | ||||
| #include "catch_text.h" | ||||
| #include "catch_console_colour.hpp" | ||||
| #include "catch_interfaces_reporter.h" | ||||
| #include "catch_test_spec_parser.hpp" | ||||
|  | ||||
| #include <limits> | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     inline std::size_t listTests( Config const& config ) { | ||||
|  | ||||
|         TestSpec testSpec = config.testSpec(); | ||||
|         if( config.testSpec().hasFilters() ) | ||||
|             Catch::cout() << "Matching test cases:\n"; | ||||
|         else { | ||||
|             Catch::cout() << "All available test cases:\n"; | ||||
|             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); | ||||
|         } | ||||
|  | ||||
|         std::size_t matchedTests = 0; | ||||
|         TextAttributes nameAttr, descAttr, tagsAttr; | ||||
|         nameAttr.setInitialIndent( 2 ).setIndent( 4 ); | ||||
|         descAttr.setIndent( 4 ); | ||||
|         tagsAttr.setIndent( 6 ); | ||||
|  | ||||
|         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) { | ||||
|             matchedTests++; | ||||
|             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); | ||||
|             Colour::Code colour = testCaseInfo.isHidden() | ||||
|                 ? Colour::SecondaryText | ||||
|                 : Colour::None; | ||||
|             Colour colourGuard( colour ); | ||||
|  | ||||
|             Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; | ||||
|             if( config.listExtraInfo() ) { | ||||
|                 Catch::cout() << "    " << testCaseInfo.lineInfo << std::endl; | ||||
|                 std::string description = testCaseInfo.description; | ||||
|                 if( description.empty() ) | ||||
|                     description = "(NO DESCRIPTION)"; | ||||
|                 Catch::cout() << Text( description, descAttr ) << std::endl; | ||||
|             } | ||||
|             if( !testCaseInfo.tags.empty() ) | ||||
|                 Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; | ||||
|         } | ||||
|  | ||||
|         if( !config.testSpec().hasFilters() ) | ||||
|             Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; | ||||
|         else | ||||
|             Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; | ||||
|         return matchedTests; | ||||
|     } | ||||
|  | ||||
|     inline std::size_t listTestsNamesOnly( Config const& config ) { | ||||
|         TestSpec testSpec = config.testSpec(); | ||||
|         if( !config.testSpec().hasFilters() ) | ||||
|             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); | ||||
|         std::size_t matchedTests = 0; | ||||
|         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) { | ||||
|             matchedTests++; | ||||
|             TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); | ||||
|             if( startsWith( testCaseInfo.name, '#' ) ) | ||||
|                Catch::cout() << '"' << testCaseInfo.name << '"'; | ||||
|             else | ||||
|                Catch::cout() << testCaseInfo.name; | ||||
|             if ( config.listExtraInfo() ) | ||||
|                 Catch::cout() << "\t@" << testCaseInfo.lineInfo; | ||||
|             Catch::cout() << std::endl; | ||||
|         } | ||||
|         return matchedTests; | ||||
|     } | ||||
|  | ||||
|     struct TagInfo { | ||||
|         TagInfo() : count ( 0 ) {} | ||||
|         void add( std::string const& spelling ) { | ||||
|             ++count; | ||||
|             spellings.insert( spelling ); | ||||
|         } | ||||
|         std::string all() const { | ||||
|             std::string out; | ||||
|             for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end(); | ||||
|                         it != itEnd; | ||||
|                         ++it ) | ||||
|                 out += "[" + *it + "]"; | ||||
|             return out; | ||||
|         } | ||||
|         std::set<std::string> spellings; | ||||
|         std::size_t count; | ||||
|     }; | ||||
|  | ||||
|     inline std::size_t listTags( Config const& config ) { | ||||
|         TestSpec testSpec = config.testSpec(); | ||||
|         if( config.testSpec().hasFilters() ) | ||||
|             Catch::cout() << "Tags for matching test cases:\n"; | ||||
|         else { | ||||
|             Catch::cout() << "All available tags:\n"; | ||||
|             testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); | ||||
|         } | ||||
|  | ||||
|         std::map<std::string, TagInfo> tagCounts; | ||||
|  | ||||
|         std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); | ||||
|         for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); | ||||
|                 it != itEnd; | ||||
|                 ++it ) { | ||||
|             for( std::set<std::string>::const_iterator  tagIt = it->getTestCaseInfo().tags.begin(), | ||||
|                                                         tagItEnd = it->getTestCaseInfo().tags.end(); | ||||
|                     tagIt != tagItEnd; | ||||
|                     ++tagIt ) { | ||||
|                 std::string tagName = *tagIt; | ||||
|                 std::string lcaseTagName = toLower( tagName ); | ||||
|                 std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName ); | ||||
|                 if( countIt == tagCounts.end() ) | ||||
|                     countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; | ||||
|                 countIt->second.add( tagName ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(), | ||||
|                                                             countItEnd = tagCounts.end(); | ||||
|                 countIt != countItEnd; | ||||
|                 ++countIt ) { | ||||
|             std::ostringstream oss; | ||||
|             oss << "  " << std::setw(2) << countIt->second.count << "  "; | ||||
|             Text wrapper( countIt->second.all(), TextAttributes() | ||||
|                                                     .setInitialIndent( 0 ) | ||||
|                                                     .setIndent( oss.str().size() ) | ||||
|                                                     .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); | ||||
|             Catch::cout() << oss.str() << wrapper << '\n'; | ||||
|         } | ||||
|         Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; | ||||
|         return tagCounts.size(); | ||||
|     } | ||||
|  | ||||
|     inline std::size_t listReporters( Config const& /*config*/ ) { | ||||
|         Catch::cout() << "Available reporters:\n"; | ||||
|         IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); | ||||
|         IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; | ||||
|         std::size_t maxNameLen = 0; | ||||
|         for(it = itBegin; it != itEnd; ++it ) | ||||
|             maxNameLen = (std::max)( maxNameLen, it->first.size() ); | ||||
|  | ||||
|         for(it = itBegin; it != itEnd; ++it ) { | ||||
|             Text wrapper( it->second->getDescription(), TextAttributes() | ||||
|                                                         .setInitialIndent( 0 ) | ||||
|                                                         .setIndent( 7+maxNameLen ) | ||||
|                                                         .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); | ||||
|             Catch::cout() << "  " | ||||
|                     << it->first | ||||
|                     << ':' | ||||
|                     << std::string( maxNameLen - it->first.size() + 2, ' ' ) | ||||
|                     << wrapper << '\n'; | ||||
|         } | ||||
|         Catch::cout() << std::endl; | ||||
|         return factories.size(); | ||||
|     } | ||||
|  | ||||
|     inline Option<std::size_t> list( Config const& config ) { | ||||
|         Option<std::size_t> listedCount; | ||||
|         if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) ) | ||||
|             listedCount = listedCount.valueOr(0) + listTests( config ); | ||||
|         if( config.listTestNamesOnly() ) | ||||
|             listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); | ||||
|         if( config.listTags() ) | ||||
|             listedCount = listedCount.valueOr(0) + listTags( config ); | ||||
|         if( config.listReporters() ) | ||||
|             listedCount = listedCount.valueOr(0) + listReporters( config ); | ||||
|         return listedCount; | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED | ||||
							
								
								
									
										28
									
								
								include/internal/catch_matchers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								include/internal/catch_matchers.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|  *  Created by Phil Nash on 19/07/2017. | ||||
|  * | ||||
|  * 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_matchers.h" | ||||
|  | ||||
| namespace Catch { | ||||
| namespace Matchers { | ||||
|     namespace Impl { | ||||
|  | ||||
|         std::string MatcherUntypedBase::toString() const { | ||||
|             if( m_cachedToString.empty() ) | ||||
|                 m_cachedToString = describe(); | ||||
|             return m_cachedToString; | ||||
|         } | ||||
|  | ||||
|         MatcherUntypedBase::~MatcherUntypedBase() = default; | ||||
|  | ||||
|     } // namespace Impl | ||||
| } // namespace Matchers | ||||
|  | ||||
| using namespace Matchers; | ||||
| using Matchers::Impl::MatcherBase; | ||||
|  | ||||
| } // namespace Catch | ||||
| @@ -10,6 +10,9 @@ | ||||
| 
 | ||||
| #include "catch_common.h" | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace Catch { | ||||
| namespace Matchers { | ||||
|     namespace Impl { | ||||
| @@ -20,18 +23,15 @@ namespace Matchers { | ||||
| 
 | ||||
|         class MatcherUntypedBase { | ||||
|         public: | ||||
|             std::string toString() const { | ||||
|                 if( m_cachedToString.empty() ) | ||||
|                     m_cachedToString = describe(); | ||||
|                 return m_cachedToString; | ||||
|             } | ||||
|             MatcherUntypedBase() = default; | ||||
|             MatcherUntypedBase ( MatcherUntypedBase const& ) = default; | ||||
|             MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete; | ||||
|             std::string toString() const; | ||||
| 
 | ||||
|         protected: | ||||
|             virtual ~MatcherUntypedBase(); | ||||
|             virtual std::string describe() const = 0; | ||||
|             mutable std::string m_cachedToString; | ||||
|         private: | ||||
|             MatcherUntypedBase& operator = ( MatcherUntypedBase const& ); | ||||
|         }; | ||||
| 
 | ||||
|         template<typename ObjectT> | ||||
| @@ -54,21 +54,24 @@ namespace Matchers { | ||||
| 
 | ||||
|         template<typename ArgT> | ||||
|         struct MatchAllOf : MatcherBase<ArgT> { | ||||
|             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { | ||||
|                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) { | ||||
|                     if (!m_matchers[i]->match(arg)) | ||||
|             bool match( ArgT const& arg ) const override { | ||||
|                 for( auto matcher : m_matchers ) { | ||||
|                     if (!matcher->match(arg)) | ||||
|                         return false; | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             virtual std::string describe() const CATCH_OVERRIDE { | ||||
|             std::string describe() const override { | ||||
|                 std::string description; | ||||
|                 description.reserve( 4 + m_matchers.size()*32 ); | ||||
|                 description += "( "; | ||||
|                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) { | ||||
|                     if( i != 0 ) | ||||
|                 bool first = true; | ||||
|                 for( auto matcher : m_matchers ) { | ||||
|                     if( first ) | ||||
|                         first = false; | ||||
|                     else | ||||
|                         description += " and "; | ||||
|                     description += m_matchers[i]->toString(); | ||||
|                     description += matcher->toString(); | ||||
|                 } | ||||
|                 description += " )"; | ||||
|                 return description; | ||||
| @@ -84,21 +87,24 @@ namespace Matchers { | ||||
|         template<typename ArgT> | ||||
|         struct MatchAnyOf : MatcherBase<ArgT> { | ||||
| 
 | ||||
|             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { | ||||
|                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) { | ||||
|                     if (m_matchers[i]->match(arg)) | ||||
|             bool match( ArgT const& arg ) const override { | ||||
|                 for( auto matcher : m_matchers ) { | ||||
|                     if (matcher->match(arg)) | ||||
|                         return true; | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|             virtual std::string describe() const CATCH_OVERRIDE { | ||||
|             std::string describe() const override { | ||||
|                 std::string description; | ||||
|                 description.reserve( 4 + m_matchers.size()*32 ); | ||||
|                 description += "( "; | ||||
|                 for( std::size_t i = 0; i < m_matchers.size(); ++i ) { | ||||
|                     if( i != 0 ) | ||||
|                 bool first = true; | ||||
|                 for( auto matcher : m_matchers ) { | ||||
|                     if( first ) | ||||
|                         first = false; | ||||
|                     else | ||||
|                         description += " or "; | ||||
|                     description += m_matchers[i]->toString(); | ||||
|                     description += matcher->toString(); | ||||
|                 } | ||||
|                 description += " )"; | ||||
|                 return description; | ||||
| @@ -117,11 +123,11 @@ namespace Matchers { | ||||
| 
 | ||||
|             MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} | ||||
| 
 | ||||
|             virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { | ||||
|             bool match( ArgT const& arg ) const override { | ||||
|                 return !m_underlyingMatcher.match( arg ); | ||||
|             } | ||||
| 
 | ||||
|             virtual std::string describe() const CATCH_OVERRIDE { | ||||
|             std::string describe() const override { | ||||
|                 return "not " + m_underlyingMatcher.toString(); | ||||
|             } | ||||
|             MatcherBase<ArgT> const& m_underlyingMatcher; | ||||
| @@ -142,31 +148,6 @@ namespace Matchers { | ||||
| 
 | ||||
|     } // namespace Impl
 | ||||
| 
 | ||||
| 
 | ||||
|     // The following functions create the actual matcher objects.
 | ||||
|     // This allows the types to be inferred
 | ||||
|     // - deprecated: prefer ||, && and !
 | ||||
|     template<typename T> | ||||
|     Impl::MatchNotOf<T> Not( Impl::MatcherBase<T> const& underlyingMatcher ) { | ||||
|         return Impl::MatchNotOf<T>( underlyingMatcher ); | ||||
|     } | ||||
|     template<typename T> | ||||
|     Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) { | ||||
|         return Impl::MatchAllOf<T>() && m1 && m2; | ||||
|     } | ||||
|     template<typename T> | ||||
|     Impl::MatchAllOf<T> AllOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) { | ||||
|         return Impl::MatchAllOf<T>() && m1 && m2 && m3; | ||||
|     } | ||||
|     template<typename T> | ||||
|     Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2 ) { | ||||
|         return Impl::MatchAnyOf<T>() || m1 || m2; | ||||
|     } | ||||
|     template<typename T> | ||||
|     Impl::MatchAnyOf<T> AnyOf( Impl::MatcherBase<T> const& m1, Impl::MatcherBase<T> const& m2, Impl::MatcherBase<T> const& m3 ) { | ||||
|         return Impl::MatchAnyOf<T>() || m1 || m2 || m3; | ||||
|     } | ||||
| 
 | ||||
| } // namespace Matchers
 | ||||
| 
 | ||||
| using namespace Matchers; | ||||
| @@ -6,7 +6,8 @@ | ||||
|  * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | ||||
|  */ | ||||
| 
 | ||||
| #include "catch_matchers.hpp" | ||||
| #include "catch_matchers_string.h" | ||||
| #include "catch_string_manip.h" | ||||
| 
 | ||||
| namespace Catch { | ||||
| namespace Matchers { | ||||
| @@ -8,7 +8,9 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED | ||||
|  | ||||
| #include "catch_matchers.hpp" | ||||
| #include "catch_matchers.h" | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace Catch { | ||||
| namespace Matchers { | ||||
| @@ -27,7 +29,7 @@ namespace Matchers { | ||||
|  | ||||
|         struct StringMatcherBase : MatcherBase<std::string> { | ||||
|             StringMatcherBase( std::string const& operation, CasedString const& comparator ); | ||||
|             virtual std::string describe() const CATCH_OVERRIDE; | ||||
|             std::string describe() const override; | ||||
|  | ||||
|             CasedString m_comparator; | ||||
|             std::string m_operation; | ||||
| @@ -35,19 +37,19 @@ namespace Matchers { | ||||
|  | ||||
|         struct EqualsMatcher : StringMatcherBase { | ||||
|             EqualsMatcher( CasedString const& comparator ); | ||||
|             virtual bool match( std::string const& source ) const CATCH_OVERRIDE; | ||||
|             bool match( std::string const& source ) const override; | ||||
|         }; | ||||
|         struct ContainsMatcher : StringMatcherBase { | ||||
|             ContainsMatcher( CasedString const& comparator ); | ||||
|             virtual bool match( std::string const& source ) const CATCH_OVERRIDE; | ||||
|             bool match( std::string const& source ) const override; | ||||
|         }; | ||||
|         struct StartsWithMatcher : StringMatcherBase { | ||||
|             StartsWithMatcher( CasedString const& comparator ); | ||||
|             virtual bool match( std::string const& source ) const CATCH_OVERRIDE; | ||||
|             bool match( std::string const& source ) const override; | ||||
|         }; | ||||
|         struct EndsWithMatcher : StringMatcherBase { | ||||
|             EndsWithMatcher( CasedString const& comparator ); | ||||
|             virtual bool match( std::string const& source ) const CATCH_OVERRIDE; | ||||
|             bool match( std::string const& source ) const override; | ||||
|         }; | ||||
|  | ||||
|     } // namespace StdString | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED | ||||
|  | ||||
| #include "catch_matchers.hpp" | ||||
| #include "catch_matchers.h" | ||||
|  | ||||
| namespace Catch { | ||||
| namespace Matchers { | ||||
| @@ -20,12 +20,17 @@ namespace Matchers { | ||||
|  | ||||
|             ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} | ||||
|  | ||||
|             bool match(std::vector<T> const &v) const CATCH_OVERRIDE { | ||||
|                 return std::find(v.begin(), v.end(), m_comparator) != v.end(); | ||||
|             bool match(std::vector<T> const &v) const override { | ||||
|                 for (auto const& el : v) { | ||||
|                     if (el == m_comparator) { | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             virtual std::string describe() const CATCH_OVERRIDE { | ||||
|                 return "Contains: " + Catch::toString( m_comparator ); | ||||
|             std::string describe() const override { | ||||
|                 return "Contains: " + ::Catch::Detail::stringify( m_comparator ); | ||||
|             } | ||||
|  | ||||
|             T const& m_comparator; | ||||
| @@ -36,17 +41,26 @@ namespace Matchers { | ||||
|  | ||||
|             ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} | ||||
|  | ||||
|             bool match(std::vector<T> const &v) const CATCH_OVERRIDE { | ||||
|             bool match(std::vector<T> const &v) const override { | ||||
|                 // !TBD: see note in EqualsMatcher | ||||
|                 if (m_comparator.size() > v.size()) | ||||
|                     return false; | ||||
|                 for (size_t i = 0; i < m_comparator.size(); ++i) | ||||
|                     if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end()) | ||||
|                 for (auto const& comparator : m_comparator) { | ||||
|                     auto present = false; | ||||
|                     for (const auto& el : v) { | ||||
|                         if (el == comparator) { | ||||
|                             present = true; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     if (!present) { | ||||
|                         return false; | ||||
|                     } | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|             virtual std::string describe() const CATCH_OVERRIDE { | ||||
|                 return "Contains: " + Catch::toString( m_comparator ); | ||||
|             std::string describe() const override { | ||||
|                 return "Contains: " + ::Catch::Detail::stringify( m_comparator ); | ||||
|             } | ||||
|  | ||||
|             std::vector<T> const& m_comparator; | ||||
| @@ -57,20 +71,20 @@ namespace Matchers { | ||||
|  | ||||
|             EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {} | ||||
|  | ||||
|             bool match(std::vector<T> const &v) const CATCH_OVERRIDE { | ||||
|             bool match(std::vector<T> const &v) const override { | ||||
|                 // !TBD: This currently works if all elements can be compared using != | ||||
|                 // - a more general approach would be via a compare template that defaults | ||||
|                 // to using !=. but could be specialised for, e.g. std::vector<T> etc | ||||
|                 // - then just call that directly | ||||
|                 if (m_comparator.size() != v.size()) | ||||
|                     return false; | ||||
|                 for (size_t i = 0; i < v.size(); ++i) | ||||
|                 for (std::size_t i = 0; i < v.size(); ++i) | ||||
|                     if (m_comparator[i] != v[i]) | ||||
|                         return false; | ||||
|                 return true; | ||||
|             } | ||||
|             virtual std::string describe() const CATCH_OVERRIDE { | ||||
|                 return "Equals: " + Catch::toString( m_comparator ); | ||||
|             std::string describe() const override { | ||||
|                 return "Equals: " + ::Catch::Detail::stringify( m_comparator ); | ||||
|             } | ||||
|             std::vector<T> const& m_comparator; | ||||
|         }; | ||||
|   | ||||
| @@ -5,10 +5,9 @@ | ||||
|  *  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_MESSAGE_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED | ||||
| 
 | ||||
| #include "catch_message.h" | ||||
| #include "catch_interfaces_capture.h" | ||||
| 
 | ||||
| namespace Catch { | ||||
| 
 | ||||
| @@ -21,21 +20,34 @@ namespace Catch { | ||||
|         sequence( ++globalCount ) | ||||
|     {} | ||||
| 
 | ||||
|     bool MessageInfo::operator==( MessageInfo const& other ) const { | ||||
|         return sequence == other.sequence; | ||||
|     } | ||||
| 
 | ||||
|     bool MessageInfo::operator<( MessageInfo const& other ) const { | ||||
|         return sequence < other.sequence; | ||||
|     } | ||||
| 
 | ||||
|     // This may need protecting if threading support is added
 | ||||
|     unsigned int MessageInfo::globalCount = 0; | ||||
| 
 | ||||
| 
 | ||||
|     ////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
|     Catch::MessageBuilder::MessageBuilder( std::string const& macroName, | ||||
|                                            SourceLineInfo const& lineInfo, | ||||
|                                            ResultWas::OfType type ) | ||||
|         :m_info(macroName, lineInfo, type) {} | ||||
| 
 | ||||
|     ////////////////////////////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| 
 | ||||
|     ScopedMessage::ScopedMessage( MessageBuilder const& builder ) | ||||
|     : m_info( builder.m_info ) | ||||
|     { | ||||
|         m_info.message = builder.m_stream.str(); | ||||
|         getResultCapture().pushScopedMessage( m_info ); | ||||
|     } | ||||
|     ScopedMessage::ScopedMessage( ScopedMessage const& other ) | ||||
|     : m_info( other.m_info ) | ||||
|     {} | ||||
| 
 | ||||
|     ScopedMessage::~ScopedMessage() { | ||||
|         if ( !std::uncaught_exception() ){ | ||||
| @@ -45,5 +57,3 @@ namespace Catch { | ||||
| 
 | ||||
| 
 | ||||
| } // end namespace Catch
 | ||||
| 
 | ||||
| #endif // TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
 | ||||
| @@ -9,6 +9,7 @@ | ||||
| #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED | ||||
|  | ||||
| #include <string> | ||||
| #include <sstream> | ||||
| #include "catch_result_type.h" | ||||
| #include "catch_common.h" | ||||
|  | ||||
| @@ -20,27 +21,33 @@ namespace Catch { | ||||
|                         ResultWas::OfType _type ); | ||||
|  | ||||
|         std::string macroName; | ||||
|         std::string message; | ||||
|         SourceLineInfo lineInfo; | ||||
|         ResultWas::OfType type; | ||||
|         std::string message; | ||||
|         unsigned int sequence; | ||||
|  | ||||
|         bool operator == ( MessageInfo const& other ) const { | ||||
|             return sequence == other.sequence; | ||||
|         } | ||||
|         bool operator < ( MessageInfo const& other ) const { | ||||
|             return sequence < other.sequence; | ||||
|         } | ||||
|         bool operator == ( MessageInfo const& other ) const; | ||||
|         bool operator < ( MessageInfo const& other ) const; | ||||
|     private: | ||||
|         static unsigned int globalCount; | ||||
|     }; | ||||
|  | ||||
|     struct MessageBuilder { | ||||
|     struct MessageStream { | ||||
|  | ||||
|         template<typename T> | ||||
|         MessageStream& operator << ( T const& value ) { | ||||
|             m_stream << value; | ||||
|             return *this; | ||||
|         } | ||||
|  | ||||
|         // !TBD reuse a global/ thread-local stream | ||||
|         std::ostringstream m_stream; | ||||
|     }; | ||||
|  | ||||
|     struct MessageBuilder : MessageStream { | ||||
|         MessageBuilder( std::string const& macroName, | ||||
|                         SourceLineInfo const& lineInfo, | ||||
|                         ResultWas::OfType type ) | ||||
|         : m_info( macroName, lineInfo, type ) | ||||
|         {} | ||||
|                         ResultWas::OfType type ); | ||||
|  | ||||
|         template<typename T> | ||||
|         MessageBuilder& operator << ( T const& value ) { | ||||
| @@ -49,13 +56,11 @@ namespace Catch { | ||||
|         } | ||||
|  | ||||
|         MessageInfo m_info; | ||||
|         std::ostringstream m_stream; | ||||
|     }; | ||||
|  | ||||
|     class ScopedMessage { | ||||
|     public: | ||||
|         ScopedMessage( MessageBuilder const& builder ); | ||||
|         ScopedMessage( ScopedMessage const& other ); | ||||
|         ~ScopedMessage(); | ||||
|  | ||||
|         MessageInfo m_info; | ||||
|   | ||||
| @@ -1,34 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 5/8/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED | ||||
|  | ||||
| #include "catch_common.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class NotImplementedException : public std::exception | ||||
|     { | ||||
|     public: | ||||
|         NotImplementedException( SourceLineInfo const& lineInfo ); | ||||
|  | ||||
|         virtual ~NotImplementedException() CATCH_NOEXCEPT {} | ||||
|  | ||||
|         virtual const char* what() const CATCH_NOEXCEPT; | ||||
|  | ||||
|     private: | ||||
|         std::string m_what; | ||||
|         SourceLineInfo m_lineInfo; | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED | ||||
| @@ -1,30 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 5/8/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_notimplemented_exception.h" | ||||
| #include <sstream> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) | ||||
|     :   m_lineInfo( lineInfo ) { | ||||
|         std::ostringstream oss; | ||||
|         oss << lineInfo << ": function "; | ||||
|         oss << "not implemented"; | ||||
|         m_what = oss.str(); | ||||
|     } | ||||
|  | ||||
|     const char* NotImplementedException::what() const CATCH_NOEXCEPT { | ||||
|         return m_what.c_str(); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED | ||||
| @@ -18,6 +18,8 @@ | ||||
| // in catch.hpp first to make sure they are included by the single | ||||
| // header for non obj-usage | ||||
| #include "catch_test_case_info.h" | ||||
| #include "catch_string_manip.h" | ||||
| #include "catch_tostring.h" | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| // This protocol is really only here for (self) documenting purposes, since | ||||
| @@ -33,7 +35,7 @@ | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class OcMethod : public SharedImpl<ITestCase> { | ||||
|     class OcMethod : public ITestInvoker { | ||||
|  | ||||
|     public: | ||||
|         OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} | ||||
| @@ -70,9 +72,9 @@ namespace Catch { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     inline size_t registerTestMethods() { | ||||
|         size_t noTestMethods = 0; | ||||
|         int noClasses = objc_getClassList( CATCH_NULL, 0 ); | ||||
|     inline std::size_t registerTestMethods() { | ||||
|         std::size_t noTestMethods = 0; | ||||
|         int noClasses = objc_getClassList( nullptr, 0 ); | ||||
|  | ||||
|         Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); | ||||
|         objc_getClassList( classes, noClasses ); | ||||
| @@ -91,7 +93,7 @@ namespace Catch { | ||||
|                         std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); | ||||
|                         const char* className = class_getName( cls ); | ||||
|  | ||||
|                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); | ||||
|                         getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) ); | ||||
|                         noTestMethods++; | ||||
|                     } | ||||
|                 } | ||||
| @@ -101,6 +103,8 @@ namespace Catch { | ||||
|         return noTestMethods; | ||||
|     } | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_DISABLE_MATCHERS) | ||||
|  | ||||
|     namespace Matchers { | ||||
|         namespace Impl { | ||||
|         namespace NSStringMatchers { | ||||
| @@ -112,61 +116,61 @@ namespace Catch { | ||||
|                     arcSafeRelease( m_substr ); | ||||
|                 } | ||||
|  | ||||
|                 virtual bool match( NSString* arg ) const CATCH_OVERRIDE { | ||||
|                 bool match( NSString* arg ) const override { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 NSString* m_substr; | ||||
|                 NSString* CATCH_ARC_STRONG m_substr; | ||||
|             }; | ||||
|  | ||||
|             struct Equals : StringHolder { | ||||
|                 Equals( NSString* substr ) : StringHolder( substr ){} | ||||
|  | ||||
|                 virtual bool match( NSString* str ) const CATCH_OVERRIDE { | ||||
|                 bool match( NSString* str ) const override { | ||||
|                     return  (str != nil || m_substr == nil ) && | ||||
|                             [str isEqualToString:m_substr]; | ||||
|                 } | ||||
|  | ||||
|                 virtual std::string describe() const CATCH_OVERRIDE { | ||||
|                     return "equals string: " + Catch::toString( m_substr ); | ||||
|                 std::string describe() const override { | ||||
|                     return "equals string: " + Catch::Detail::stringify( m_substr ); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             struct Contains : StringHolder { | ||||
|                 Contains( NSString* substr ) : StringHolder( substr ){} | ||||
|  | ||||
|                 virtual bool match( NSString* str ) const { | ||||
|                 bool match( NSString* str ) const { | ||||
|                     return  (str != nil || m_substr == nil ) && | ||||
|                             [str rangeOfString:m_substr].location != NSNotFound; | ||||
|                 } | ||||
|  | ||||
|                 virtual std::string describe() const CATCH_OVERRIDE { | ||||
|                     return "contains string: " + Catch::toString( m_substr ); | ||||
|                 std::string describe() const override { | ||||
|                     return "contains string: " + Catch::Detail::stringify( m_substr ); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             struct StartsWith : StringHolder { | ||||
|                 StartsWith( NSString* substr ) : StringHolder( substr ){} | ||||
|  | ||||
|                 virtual bool match( NSString* str ) const { | ||||
|                 bool match( NSString* str ) const override { | ||||
|                     return  (str != nil || m_substr == nil ) && | ||||
|                             [str rangeOfString:m_substr].location == 0; | ||||
|                 } | ||||
|  | ||||
|                 virtual std::string describe() const CATCH_OVERRIDE { | ||||
|                     return "starts with: " + Catch::toString( m_substr ); | ||||
|                 std::string describe() const override { | ||||
|                     return "starts with: " + Catch::Detail::stringify( m_substr ); | ||||
|                 } | ||||
|             }; | ||||
|             struct EndsWith : StringHolder { | ||||
|                 EndsWith( NSString* substr ) : StringHolder( substr ){} | ||||
|  | ||||
|                 virtual bool match( NSString* str ) const { | ||||
|                 bool match( NSString* str ) const override { | ||||
|                     return  (str != nil || m_substr == nil ) && | ||||
|                             [str rangeOfString:m_substr].location == [str length] - [m_substr length]; | ||||
|                 } | ||||
|  | ||||
|                 virtual std::string describe() const CATCH_OVERRIDE { | ||||
|                     return "ends with: " + Catch::toString( m_substr ); | ||||
|                 std::string describe() const override { | ||||
|                     return "ends with: " + Catch::Detail::stringify( m_substr ); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
| @@ -189,18 +193,23 @@ namespace Catch { | ||||
|  | ||||
|     using namespace Matchers; | ||||
|  | ||||
| #endif // CATCH_CONFIG_DISABLE_MATCHERS | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////// | ||||
| #define OC_TEST_CASE( name, desc )\ | ||||
| +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ | ||||
| {\ | ||||
| #define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix | ||||
| #define OC_TEST_CASE2( name, desc, uniqueSuffix ) \ | ||||
| +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \ | ||||
| { \ | ||||
| return @ name; \ | ||||
| }\ | ||||
| +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ | ||||
| } \ | ||||
| +(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \ | ||||
| { \ | ||||
| return @ desc; \ | ||||
| } \ | ||||
| -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) | ||||
| -(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix ) | ||||
|  | ||||
| #define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ ) | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED | ||||
|   | ||||
| @@ -8,20 +8,18 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_common.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     // An optional type | ||||
|     template<typename T> | ||||
|     class Option { | ||||
|     public: | ||||
|         Option() : nullableValue( CATCH_NULL ) {} | ||||
|         Option() : nullableValue( nullptr ) {} | ||||
|         Option( T const& _value ) | ||||
|         : nullableValue( new( storage ) T( _value ) ) | ||||
|         {} | ||||
|         Option( Option const& _other ) | ||||
|         : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) | ||||
|         : nullableValue( _other ? new( storage ) T( *_other ) : nullptr ) | ||||
|         {} | ||||
|  | ||||
|         ~Option() { | ||||
| @@ -45,7 +43,7 @@ namespace Catch { | ||||
|         void reset() { | ||||
|             if( nullableValue ) | ||||
|                 nullableValue->~T(); | ||||
|             nullableValue = CATCH_NULL; | ||||
|             nullableValue = nullptr; | ||||
|         } | ||||
|  | ||||
|         T& operator*() { return *nullableValue; } | ||||
| @@ -57,27 +55,17 @@ namespace Catch { | ||||
|             return nullableValue ? *nullableValue : defaultValue; | ||||
|         } | ||||
|  | ||||
|         bool some() const { return nullableValue != CATCH_NULL; } | ||||
|         bool none() const { return nullableValue == CATCH_NULL; } | ||||
|         bool some() const { return nullableValue != nullptr; } | ||||
|         bool none() const { return nullableValue == nullptr; } | ||||
|  | ||||
|         bool operator !() const { return nullableValue == CATCH_NULL; } | ||||
|         operator SafeBool::type() const { | ||||
|             return SafeBool::makeSafe( some() ); | ||||
|         bool operator !() const { return nullableValue == nullptr; } | ||||
|         explicit operator bool() const { | ||||
|             return some(); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         T *nullableValue; | ||||
|         union { | ||||
|             char storage[sizeof(T)]; | ||||
|  | ||||
|             // These are here to force alignment for the storage | ||||
|             long double dummy1; | ||||
|             void (*dummy2)(); | ||||
|             long double dummy3; | ||||
| #ifdef CATCH_CONFIG_CPP11_LONG_LONG | ||||
|             long long dummy4; | ||||
| #endif | ||||
|         }; | ||||
|         alignas(alignof(T)) char storage[sizeof(T)]; | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|   | ||||
| @@ -9,20 +9,19 @@ | ||||
| #ifndef TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED | ||||
|  | ||||
| #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) | ||||
| #ifdef __APPLE__ | ||||
| # include <TargetConditionals.h> | ||||
| # if TARGET_OS_MAC == 1 | ||||
| #  define CATCH_PLATFORM_MAC | ||||
| #elif  defined(__IPHONE_OS_VERSION_MIN_REQUIRED) | ||||
| # elif TARGET_OS_IPHONE == 1 | ||||
| #  define CATCH_PLATFORM_IPHONE | ||||
| # endif | ||||
|  | ||||
| #elif defined(linux) || defined(__linux) || defined(__linux__) | ||||
| #  define CATCH_PLATFORM_LINUX | ||||
|  | ||||
| #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) | ||||
| #  define CATCH_PLATFORM_WINDOWS | ||||
| #  if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) | ||||
| #    define CATCH_DEFINES_NOMINMAX | ||||
| #  endif | ||||
| #  if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) | ||||
| #    define CATCH_DEFINES_WIN32_LEAN_AND_MEAN | ||||
| #  endif | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED | ||||
|   | ||||
| @@ -1,93 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 02/05/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) | ||||
|  */ | ||||
| #ifndef TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_common.h" | ||||
|  | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic push | ||||
| #pragma clang diagnostic ignored "-Wpadded" | ||||
| #endif | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     // An intrusive reference counting smart pointer. | ||||
|     // T must implement addRef() and release() methods | ||||
|     // typically implementing the IShared interface | ||||
|     template<typename T> | ||||
|     class Ptr { | ||||
|     public: | ||||
|         Ptr() : m_p( CATCH_NULL ){} | ||||
|         Ptr( T* p ) : m_p( p ){ | ||||
|             if( m_p ) | ||||
|                 m_p->addRef(); | ||||
|         } | ||||
|         Ptr( Ptr const& other ) : m_p( other.m_p ){ | ||||
|             if( m_p ) | ||||
|                 m_p->addRef(); | ||||
|         } | ||||
|         ~Ptr(){ | ||||
|             if( m_p ) | ||||
|                 m_p->release(); | ||||
|         } | ||||
|         void reset() { | ||||
|             if( m_p ) | ||||
|                 m_p->release(); | ||||
|             m_p = CATCH_NULL; | ||||
|         } | ||||
|         Ptr& operator = ( T* p ){ | ||||
|             Ptr temp( p ); | ||||
|             swap( temp ); | ||||
|             return *this; | ||||
|         } | ||||
|         Ptr& operator = ( Ptr const& other ){ | ||||
|             Ptr temp( other ); | ||||
|             swap( temp ); | ||||
|             return *this; | ||||
|         } | ||||
|         void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } | ||||
|         T* get() const{ return m_p; } | ||||
|         T& operator*() const { return *m_p; } | ||||
|         T* operator->() const { return m_p; } | ||||
|         bool operator !() const { return m_p == CATCH_NULL; } | ||||
|         operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } | ||||
|  | ||||
|     private: | ||||
|         T* m_p; | ||||
|     }; | ||||
|  | ||||
|     struct IShared : NonCopyable { | ||||
|         virtual ~IShared(); | ||||
|         virtual void addRef() const = 0; | ||||
|         virtual void release() const = 0; | ||||
|     }; | ||||
|  | ||||
|     template<typename T = IShared> | ||||
|     struct SharedImpl : T { | ||||
|  | ||||
|         SharedImpl() : m_rc( 0 ){} | ||||
|  | ||||
|         virtual void addRef() const { | ||||
|             ++m_rc; | ||||
|         } | ||||
|         virtual void release() const { | ||||
|             if( --m_rc == 0 ) | ||||
|                 delete this; | ||||
|         } | ||||
|  | ||||
|         mutable unsigned int m_rc; | ||||
|     }; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic pop | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED | ||||
							
								
								
									
										31
									
								
								include/internal/catch_random_number_generator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								include/internal/catch_random_number_generator.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| /* | ||||
|  *  Created by Martin on 30/08/2017. | ||||
|  * | ||||
|  *  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_random_number_generator.h" | ||||
| #include "catch_context.h" | ||||
| #include "catch_interfaces_config.h" | ||||
|  | ||||
| #include <cstdlib> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     void seedRng( IConfig const& config ) { | ||||
|         if( config.rngSeed() != 0 ) | ||||
|             std::srand( config.rngSeed() ); | ||||
|     } | ||||
|     unsigned int rngSeed() { | ||||
|         return getCurrentContext().getConfig()->rngSeed(); | ||||
|     } | ||||
|  | ||||
|     RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const { | ||||
|         return std::rand() % n; | ||||
|     } | ||||
|     RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const { | ||||
|         return std::rand() % (max)(); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										40
									
								
								include/internal/catch_random_number_generator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								include/internal/catch_random_number_generator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  *  Created by Martin on 30/08/2017. | ||||
|  * | ||||
|  *  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_RANDOM_NUMBER_GENERATOR_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED | ||||
|  | ||||
| #include "catch_random_number_generator.h" | ||||
|  | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct IConfig; | ||||
|  | ||||
|     void seedRng( IConfig const& config ); | ||||
|  | ||||
|     unsigned int rngSeed(); | ||||
|  | ||||
|     struct RandomNumberGenerator { | ||||
|         using result_type = unsigned int; | ||||
|  | ||||
|         static constexpr result_type (min)() { return 0; } | ||||
|         static constexpr result_type (max)() { return 1000000; } | ||||
|  | ||||
|         result_type operator()( result_type n ) const; | ||||
|         result_type operator()() const; | ||||
|  | ||||
|         template<typename V> | ||||
|         static void shuffle( V& vector ) { | ||||
|             RandomNumberGenerator rng; | ||||
|             std::shuffle( vector.begin(), vector.end(), rng ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_RANDOM_NUMBER_GENERATOR_H_INCLUDED | ||||
| @@ -5,69 +5,72 @@ | ||||
|  *  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_REGISTRY_HUB_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED | ||||
| 
 | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
| 
 | ||||
| #include "catch_test_case_registry_impl.hpp" | ||||
| #include "catch_reporter_registry.hpp" | ||||
| #include "catch_exception_translator_registry.hpp" | ||||
| #include "catch_context.h" | ||||
| #include "catch_test_case_registry_impl.h" | ||||
| #include "catch_reporter_registry.h" | ||||
| #include "catch_exception_translator_registry.h" | ||||
| #include "catch_tag_alias_registry.h" | ||||
| #include "catch_startup_exception_registry.h" | ||||
| 
 | ||||
| namespace Catch { | ||||
| 
 | ||||
|     namespace { | ||||
| 
 | ||||
|         class RegistryHub : public IRegistryHub, public IMutableRegistryHub { | ||||
| 
 | ||||
|             RegistryHub( RegistryHub const& ); | ||||
|             void operator=( RegistryHub const& ); | ||||
|         class RegistryHub : public IRegistryHub, public IMutableRegistryHub, | ||||
|                             private NonCopyable { | ||||
| 
 | ||||
|         public: // IRegistryHub
 | ||||
|             RegistryHub() { | ||||
|             } | ||||
|             virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { | ||||
|             RegistryHub() = default; | ||||
|             IReporterRegistry const& getReporterRegistry() const override { | ||||
|                 return m_reporterRegistry; | ||||
|             } | ||||
|             virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { | ||||
|             ITestCaseRegistry const& getTestCaseRegistry() const override { | ||||
|                 return m_testCaseRegistry; | ||||
|             } | ||||
|             virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { | ||||
|             IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override { | ||||
|                 return m_exceptionTranslatorRegistry; | ||||
|             } | ||||
|             virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE { | ||||
|             ITagAliasRegistry const& getTagAliasRegistry() const override { | ||||
|                 return m_tagAliasRegistry; | ||||
|             } | ||||
| 
 | ||||
|             StartupExceptionRegistry const& getStartupExceptionRegistry() const override { | ||||
|                 return m_exceptionRegistry; | ||||
|             } | ||||
| 
 | ||||
|         public: // IMutableRegistryHub
 | ||||
|             virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE { | ||||
|             void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override { | ||||
|                 m_reporterRegistry.registerReporter( name, factory ); | ||||
|             } | ||||
|             virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE { | ||||
|             void registerListener( IReporterFactoryPtr const& factory ) override { | ||||
|                 m_reporterRegistry.registerListener( factory ); | ||||
|             } | ||||
|             virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { | ||||
|             void registerTest( TestCase const& testInfo ) override { | ||||
|                 m_testCaseRegistry.registerTest( testInfo ); | ||||
|             } | ||||
|             virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { | ||||
|             void registerTranslator( const IExceptionTranslator* translator ) override { | ||||
|                 m_exceptionTranslatorRegistry.registerTranslator( translator ); | ||||
|             } | ||||
|             virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE { | ||||
|             void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override { | ||||
|                 m_tagAliasRegistry.add( alias, tag, lineInfo ); | ||||
|             } | ||||
|             void registerStartupException() noexcept override { | ||||
|                 m_exceptionRegistry.add(std::current_exception()); | ||||
|             } | ||||
| 
 | ||||
|         private: | ||||
|             TestRegistry m_testCaseRegistry; | ||||
|             ReporterRegistry m_reporterRegistry; | ||||
|             ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; | ||||
|             TagAliasRegistry m_tagAliasRegistry; | ||||
|             StartupExceptionRegistry m_exceptionRegistry; | ||||
|         }; | ||||
| 
 | ||||
|         // Single, global, instance
 | ||||
|         inline RegistryHub*& getTheRegistryHub() { | ||||
|             static RegistryHub* theRegistryHub = CATCH_NULL; | ||||
|         RegistryHub*& getTheRegistryHub() { | ||||
|             static RegistryHub* theRegistryHub = nullptr; | ||||
|             if( !theRegistryHub ) | ||||
|                 theRegistryHub = new RegistryHub(); | ||||
|             return theRegistryHub; | ||||
| @@ -82,7 +85,7 @@ namespace Catch { | ||||
|     } | ||||
|     void cleanUp() { | ||||
|         delete getTheRegistryHub(); | ||||
|         getTheRegistryHub() = CATCH_NULL; | ||||
|         getTheRegistryHub() = nullptr; | ||||
|         cleanUpContext(); | ||||
|     } | ||||
|     std::string translateActiveException() { | ||||
| @@ -91,5 +94,3 @@ namespace Catch { | ||||
| 
 | ||||
| 
 | ||||
| } // end namespace Catch
 | ||||
| 
 | ||||
| #endif // TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
 | ||||
| @@ -1,3 +1,4 @@ | ||||
|  | ||||
| /* | ||||
|  *  Created by Phil on 31/12/2010. | ||||
|  *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved. | ||||
| @@ -9,51 +10,19 @@ | ||||
| #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
| #include "catch_legacy_reporter_adapter.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     template<typename T> | ||||
|     class LegacyReporterRegistrar { | ||||
|  | ||||
|         class ReporterFactory : public IReporterFactory { | ||||
|             virtual IStreamingReporter* create( ReporterConfig const& config ) const { | ||||
|                 return new LegacyReporterAdapter( new T( config ) ); | ||||
|             } | ||||
|  | ||||
|             virtual std::string getDescription() const { | ||||
|                 return T::getDescription(); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         LegacyReporterRegistrar( std::string const& name ) { | ||||
|             getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     template<typename T> | ||||
|     class ReporterRegistrar { | ||||
|  | ||||
|         class ReporterFactory : public SharedImpl<IReporterFactory> { | ||||
|         class ReporterFactory : public IReporterFactory { | ||||
|  | ||||
|             // *** Please Note ***: | ||||
|             // - If you end up here looking at a compiler error because it's trying to register | ||||
|             // your custom reporter class be aware that the native reporter interface has changed | ||||
|             // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via | ||||
|             // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. | ||||
|             // However please consider updating to the new interface as the old one is now | ||||
|             // deprecated and will probably be removed quite soon! | ||||
|             // Please contact me via github if you have any questions at all about this. | ||||
|             // In fact, ideally, please contact me anyway to let me know you've hit this - as I have | ||||
|             // no idea who is actually using custom reporters at all (possibly no-one!). | ||||
|             // The new interface is designed to minimise exposure to interface changes in the future. | ||||
|             virtual IStreamingReporter* create( ReporterConfig const& config ) const { | ||||
|                 return new T( config ); | ||||
|             virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override { | ||||
|                 return std::unique_ptr<T>( new T( config ) ); | ||||
|             } | ||||
|  | ||||
|             virtual std::string getDescription() const { | ||||
|             virtual std::string getDescription() const override { | ||||
|                 return T::getDescription(); | ||||
|             } | ||||
|         }; | ||||
| @@ -61,19 +30,19 @@ namespace Catch { | ||||
|     public: | ||||
|  | ||||
|         ReporterRegistrar( std::string const& name ) { | ||||
|             getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); | ||||
|             getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() ); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     template<typename T> | ||||
|     class ListenerRegistrar { | ||||
|  | ||||
|         class ListenerFactory : public SharedImpl<IReporterFactory> { | ||||
|         class ListenerFactory : public IReporterFactory { | ||||
|  | ||||
|             virtual IStreamingReporter* create( ReporterConfig const& config ) const { | ||||
|                 return new T( config ); | ||||
|             virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override { | ||||
|                 return std::unique_ptr<T>( new T( config ) ); | ||||
|             } | ||||
|             virtual std::string getDescription() const { | ||||
|             virtual std::string getDescription() const override { | ||||
|                 return std::string(); | ||||
|             } | ||||
|         }; | ||||
| @@ -81,22 +50,27 @@ namespace Catch { | ||||
|     public: | ||||
|  | ||||
|         ListenerRegistrar() { | ||||
|             getMutableRegistryHub().registerListener( new ListenerFactory() ); | ||||
|             getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() ); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ | ||||
|     namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } | ||||
| #if !defined(CATCH_CONFIG_DISABLE) | ||||
|  | ||||
| #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ | ||||
|     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } | ||||
|  | ||||
| // Deprecated - use the form without INTERNAL_ | ||||
| #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ | ||||
|     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } | ||||
| #define CATCH_REGISTER_REPORTER( name, reporterType ) \ | ||||
|     CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \ | ||||
|     namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \ | ||||
|     CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS | ||||
|  | ||||
| #define CATCH_REGISTER_LISTENER( listenerType ) \ | ||||
|     namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } | ||||
|      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS   \ | ||||
|      namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \ | ||||
|      CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS | ||||
| #else // CATCH_CONFIG_DISABLE | ||||
|  | ||||
| #define CATCH_REGISTER_REPORTER(name, reporterType) | ||||
| #define CATCH_REGISTER_LISTENER(listenerType) | ||||
|  | ||||
| #endif // CATCH_CONFIG_DISABLE | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED | ||||
|   | ||||
							
								
								
									
										34
									
								
								include/internal/catch_reporter_registry.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								include/internal/catch_reporter_registry.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  *  Created by Martin on 31/08/2017. | ||||
|  * | ||||
|  *  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_reporter_registry.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     ReporterRegistry::~ReporterRegistry() = default; | ||||
|  | ||||
|     IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const { | ||||
|         auto it =  m_factories.find( name ); | ||||
|         if( it == m_factories.end() ) | ||||
|             return nullptr; | ||||
|         return it->second->create( ReporterConfig( config ) ); | ||||
|     } | ||||
|  | ||||
|     void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) { | ||||
|         m_factories.emplace(name, factory); | ||||
|     } | ||||
|     void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) { | ||||
|         m_listeners.push_back( factory ); | ||||
|     } | ||||
|  | ||||
|     IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const { | ||||
|         return m_factories; | ||||
|     } | ||||
|     IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const { | ||||
|         return m_listeners; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										37
									
								
								include/internal/catch_reporter_registry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								include/internal/catch_reporter_registry.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* | ||||
|  *  Created by Phil on 29/10/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_REPORTER_REGISTRY_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_H_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_reporter.h" | ||||
|  | ||||
| #include <map> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class ReporterRegistry : public IReporterRegistry { | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         ~ReporterRegistry() override; | ||||
|  | ||||
|         IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override; | ||||
|  | ||||
|         void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ); | ||||
|         void registerListener( IReporterFactoryPtr const& factory ); | ||||
|  | ||||
|         FactoryMap const& getFactories() const override; | ||||
|         Listeners const& getListeners() const override; | ||||
|  | ||||
|     private: | ||||
|         FactoryMap m_factories; | ||||
|         Listeners m_listeners; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRY_H_INCLUDED | ||||
| @@ -1,50 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 29/10/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_REPORTER_REGISTRY_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_reporter.h" | ||||
|  | ||||
| #include <map> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     class ReporterRegistry : public IReporterRegistry { | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         virtual ~ReporterRegistry() CATCH_OVERRIDE {} | ||||
|  | ||||
|         virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE { | ||||
|             FactoryMap::const_iterator it =  m_factories.find( name ); | ||||
|             if( it == m_factories.end() ) | ||||
|                 return CATCH_NULL; | ||||
|             return it->second->create( ReporterConfig( config ) ); | ||||
|         } | ||||
|  | ||||
|         void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) { | ||||
|             m_factories.insert( std::make_pair( name, factory ) ); | ||||
|         } | ||||
|         void registerListener( Ptr<IReporterFactory> const& factory ) { | ||||
|             m_listeners.push_back( factory ); | ||||
|         } | ||||
|  | ||||
|         virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { | ||||
|             return m_factories; | ||||
|         } | ||||
|         virtual Listeners const& getListeners() const CATCH_OVERRIDE { | ||||
|             return m_listeners; | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         FactoryMap m_factories; | ||||
|         Listeners m_listeners; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED | ||||
| @@ -1,133 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 28/5/2014. | ||||
|  *  Copyright 2014 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_RESULT_BUILDER_H_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | ||||
|  | ||||
| #include "catch_result_type.h" | ||||
| #include "catch_assertionresult.h" | ||||
| #include "catch_common.h" | ||||
| #include "catch_matchers.hpp" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct TestFailureException{}; | ||||
|  | ||||
|     template<typename T> class ExpressionLhs; | ||||
|  | ||||
|     struct CopyableStream { | ||||
|         CopyableStream() {} | ||||
|         CopyableStream( CopyableStream const& other ) { | ||||
|             oss << other.oss.str(); | ||||
|         } | ||||
|         CopyableStream& operator=( CopyableStream const& other ) { | ||||
|             oss.str(std::string()); | ||||
|             oss << other.oss.str(); | ||||
|             return *this; | ||||
|         } | ||||
|         std::ostringstream oss; | ||||
|     }; | ||||
|  | ||||
|     class ResultBuilder : public DecomposedExpression { | ||||
|     public: | ||||
|         ResultBuilder(  char const* macroName, | ||||
|                         SourceLineInfo const& lineInfo, | ||||
|                         char const* capturedExpression, | ||||
|                         ResultDisposition::Flags resultDisposition, | ||||
|                         char const* secondArg = "" ); | ||||
|         ~ResultBuilder(); | ||||
|  | ||||
|         template<typename T> | ||||
|         ExpressionLhs<T const&> operator <= ( T const& operand ); | ||||
|         ExpressionLhs<bool> operator <= ( bool value ); | ||||
|  | ||||
|         template<typename T> | ||||
|         ResultBuilder& operator << ( T const& value ) { | ||||
|             stream().oss << value; | ||||
|             return *this; | ||||
|         } | ||||
|  | ||||
|         ResultBuilder& setResultType( ResultWas::OfType result ); | ||||
|         ResultBuilder& setResultType( bool result ); | ||||
|  | ||||
|         void endExpression( DecomposedExpression const& expr ); | ||||
|  | ||||
|         virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; | ||||
|  | ||||
|         AssertionResult build() const; | ||||
|         AssertionResult build( DecomposedExpression const& expr ) const; | ||||
|  | ||||
|         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); | ||||
|         void captureResult( ResultWas::OfType resultType ); | ||||
|         void captureExpression(); | ||||
|         void captureExpectedException( std::string const& expectedMessage ); | ||||
|         void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher ); | ||||
|         void handleResult( AssertionResult const& result ); | ||||
|         void react(); | ||||
|         bool shouldDebugBreak() const; | ||||
|         bool allowThrows() const; | ||||
|  | ||||
|         template<typename ArgT, typename MatcherT> | ||||
|         void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); | ||||
|  | ||||
|         void setExceptionGuard(); | ||||
|         void unsetExceptionGuard(); | ||||
|  | ||||
|     private: | ||||
|         AssertionInfo m_assertionInfo; | ||||
|         AssertionResultData m_data; | ||||
|  | ||||
|         CopyableStream &stream() | ||||
|         { | ||||
|             if(!m_usedStream) | ||||
|             { | ||||
|                 m_usedStream = true; | ||||
|                 m_stream().oss.str(""); | ||||
|             } | ||||
|             return m_stream(); | ||||
|         } | ||||
|  | ||||
|         static CopyableStream &m_stream() | ||||
|         { | ||||
|             static CopyableStream s; | ||||
|             return s; | ||||
|         } | ||||
|  | ||||
|         bool m_shouldDebugBreak; | ||||
|         bool m_shouldThrow; | ||||
|         bool m_guardException; | ||||
|         bool m_usedStream; | ||||
|     }; | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| // Include after due to circular dependency: | ||||
| #include "catch_expression_lhs.hpp" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     template<typename T> | ||||
|     ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) { | ||||
|         return ExpressionLhs<T const&>( *this, operand ); | ||||
|     } | ||||
|  | ||||
|     inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) { | ||||
|         return ExpressionLhs<bool>( *this, value ); | ||||
|     } | ||||
|  | ||||
|     template<typename ArgT, typename MatcherT> | ||||
|     void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, | ||||
|                                              char const* matcherString ) { | ||||
|         MatchExpression<ArgT const&, MatcherT const&> expr( arg, matcher, matcherString ); | ||||
|         setResultType( matcher.match( arg ) ); | ||||
|         endExpression( expr ); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } // namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | ||||
| @@ -1,173 +0,0 @@ | ||||
| /* | ||||
|  *  Created by Phil on 28/5/2014. | ||||
|  *  Copyright 2014 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_RESULT_BUILDER_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_result_builder.h" | ||||
| #include "catch_context.h" | ||||
| #include "catch_interfaces_config.h" | ||||
| #include "catch_interfaces_runner.h" | ||||
| #include "catch_interfaces_capture.h" | ||||
| #include "catch_interfaces_registry_hub.h" | ||||
| #include "catch_wildcard_pattern.hpp" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     ResultBuilder::ResultBuilder(   char const* macroName, | ||||
|                                     SourceLineInfo const& lineInfo, | ||||
|                                     char const* capturedExpression, | ||||
|                                     ResultDisposition::Flags resultDisposition, | ||||
|                                     char const* secondArg ) | ||||
|     :   m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ), | ||||
|         m_shouldDebugBreak( false ), | ||||
|         m_shouldThrow( false ), | ||||
|         m_guardException( false ), | ||||
|         m_usedStream( false ) | ||||
|     {} | ||||
|  | ||||
|     ResultBuilder::~ResultBuilder() { | ||||
| #if defined(CATCH_CONFIG_FAST_COMPILE) | ||||
|         if ( m_guardException ) { | ||||
|             stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; | ||||
|             captureResult( ResultWas::ThrewException ); | ||||
|             getCurrentContext().getResultCapture()->exceptionEarlyReported(); | ||||
|         } | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { | ||||
|         m_data.resultType = result; | ||||
|         return *this; | ||||
|     } | ||||
|     ResultBuilder& ResultBuilder::setResultType( bool result ) { | ||||
|         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; | ||||
|         return *this; | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::endExpression( DecomposedExpression const& expr ) { | ||||
|         // Flip bool results if FalseTest flag is set | ||||
|         if( isFalseTest( m_assertionInfo.resultDisposition ) ) { | ||||
|             m_data.negate( expr.isBinaryExpression() ); | ||||
|         } | ||||
|  | ||||
|         getResultCapture().assertionRun(); | ||||
|  | ||||
|         if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok) | ||||
|         { | ||||
|             AssertionResult result = build( expr ); | ||||
|             handleResult( result ); | ||||
|         } | ||||
|         else | ||||
|             getResultCapture().assertionPassed(); | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { | ||||
|         m_assertionInfo.resultDisposition = resultDisposition; | ||||
|         stream().oss << Catch::translateActiveException(); | ||||
|         captureResult( ResultWas::ThrewException ); | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::captureResult( ResultWas::OfType resultType ) { | ||||
|         setResultType( resultType ); | ||||
|         captureExpression(); | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { | ||||
|         if( expectedMessage.empty() ) | ||||
|             captureExpectedException( Matchers::Impl::MatchAllOf<std::string>() ); | ||||
|         else | ||||
|             captureExpectedException( Matchers::Equals( expectedMessage ) ); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher ) { | ||||
|  | ||||
|         assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); | ||||
|         AssertionResultData data = m_data; | ||||
|         data.resultType = ResultWas::Ok; | ||||
|         data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); | ||||
|  | ||||
|         std::string actualMessage = Catch::translateActiveException(); | ||||
|         if( !matcher.match( actualMessage ) ) { | ||||
|             data.resultType = ResultWas::ExpressionFailed; | ||||
|             data.reconstructedExpression = actualMessage; | ||||
|         } | ||||
|         AssertionResult result( m_assertionInfo, data ); | ||||
|         handleResult( result ); | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::captureExpression() { | ||||
|         AssertionResult result = build(); | ||||
|         handleResult( result ); | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::handleResult( AssertionResult const& result ) | ||||
|     { | ||||
|         getResultCapture().assertionEnded( result ); | ||||
|  | ||||
|         if( !result.isOk() ) { | ||||
|             if( getCurrentContext().getConfig()->shouldDebugBreak() ) | ||||
|                 m_shouldDebugBreak = true; | ||||
|             if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) | ||||
|                 m_shouldThrow = true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::react() { | ||||
| #if defined(CATCH_CONFIG_FAST_COMPILE) | ||||
|         if (m_shouldDebugBreak) { | ||||
|             /////////////////////////////////////////////////////////////////// | ||||
|             // To inspect the state during test, you need to go one level up the callstack | ||||
|             // To go back to the test and change execution, jump over the throw statement | ||||
|             /////////////////////////////////////////////////////////////////// | ||||
|             CATCH_BREAK_INTO_DEBUGGER(); | ||||
|         } | ||||
| #endif | ||||
|         if( m_shouldThrow ) | ||||
|             throw Catch::TestFailureException(); | ||||
|     } | ||||
|  | ||||
|     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } | ||||
|     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } | ||||
|  | ||||
|     AssertionResult ResultBuilder::build() const | ||||
|     { | ||||
|         return build( *this ); | ||||
|     } | ||||
|  | ||||
|     // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, | ||||
|     //         a temporary DecomposedExpression, which in turn holds references to | ||||
|     //         operands, possibly temporary as well. | ||||
|     //         It should immediately be passed to handleResult; if the expression | ||||
|     //         needs to be reported, its string expansion must be composed before | ||||
|     //         the temporaries are destroyed. | ||||
|     AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const | ||||
|     { | ||||
|         assert( m_data.resultType != ResultWas::Unknown ); | ||||
|         AssertionResultData data = m_data; | ||||
|  | ||||
|         if(m_usedStream) | ||||
|             data.message = m_stream().oss.str(); | ||||
|         data.decomposedExpression = &expr; // for lazy reconstruction | ||||
|         return AssertionResult( m_assertionInfo, data ); | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::reconstructExpression( std::string& dest ) const { | ||||
|         dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); | ||||
|     } | ||||
|  | ||||
|     void ResultBuilder::setExceptionGuard() { | ||||
|         m_guardException = true; | ||||
|     } | ||||
|     void ResultBuilder::unsetExceptionGuard() { | ||||
|         m_guardException = false; | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED | ||||
							
								
								
									
										28
									
								
								include/internal/catch_result_type.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								include/internal/catch_result_type.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|  *  Created by Phil on 07/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) | ||||
|  */ | ||||
|  | ||||
| #include "catch_result_type.h" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     bool isOk( ResultWas::OfType resultType ) { | ||||
|         return ( resultType & ResultWas::FailureBit ) == 0; | ||||
|     } | ||||
|     bool isJustInfo( int flags ) { | ||||
|         return flags == ResultWas::Info; | ||||
|     } | ||||
|  | ||||
|     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { | ||||
|         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); | ||||
|     } | ||||
|  | ||||
|     bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } | ||||
|     bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; } | ||||
|     bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; } | ||||
|  | ||||
| } // end namespace Catch | ||||
| @@ -31,12 +31,8 @@ namespace Catch { | ||||
|  | ||||
|     }; }; | ||||
|  | ||||
|     inline bool isOk( ResultWas::OfType resultType ) { | ||||
|         return ( resultType & ResultWas::FailureBit ) == 0; | ||||
|     } | ||||
|     inline bool isJustInfo( int flags ) { | ||||
|         return flags == ResultWas::Info; | ||||
|     } | ||||
|     bool isOk( ResultWas::OfType resultType ); | ||||
|     bool isJustInfo( int flags ); | ||||
|  | ||||
|  | ||||
|     // ResultDisposition::Flags enum | ||||
| @@ -48,13 +44,11 @@ namespace Catch { | ||||
|         SuppressFail = 0x08         // Failures are reported but do not fail the test | ||||
|     }; }; | ||||
|  | ||||
|     inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { | ||||
|         return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); | ||||
|     } | ||||
|     ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ); | ||||
|  | ||||
|     inline bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } | ||||
|     inline bool isFalseTest( int flags )                { return ( flags & ResultDisposition::FalseTest ) != 0; } | ||||
|     inline bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; } | ||||
|     bool shouldContinueOnFailure( int flags ); | ||||
|     bool isFalseTest( int flags ); | ||||
|     bool shouldSuppressFailure( int flags ); | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
|   | ||||
							
								
								
									
										335
									
								
								include/internal/catch_run_context.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								include/internal/catch_run_context.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,335 @@ | ||||
| #include "catch_run_context.h" | ||||
| #include "catch_context.h" | ||||
| #include "catch_enforce.h" | ||||
| #include "catch_random_number_generator.h" | ||||
| #include "catch_stream.h" | ||||
|  | ||||
| #include <cassert> | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     StreamRedirect::StreamRedirect(std::ostream& stream, std::string& targetString) | ||||
|         : m_stream(stream), | ||||
|         m_prevBuf(stream.rdbuf()), | ||||
|         m_targetString(targetString) { | ||||
|         stream.rdbuf(m_oss.rdbuf()); | ||||
|     } | ||||
|  | ||||
|     StreamRedirect::~StreamRedirect() { | ||||
|         m_targetString += m_oss.str(); | ||||
|         m_stream.rdbuf(m_prevBuf); | ||||
|     } | ||||
|  | ||||
|     StdErrRedirect::StdErrRedirect(std::string & targetString) | ||||
|         :m_cerrBuf(cerr().rdbuf()), m_clogBuf(clog().rdbuf()), | ||||
|         m_targetString(targetString) { | ||||
|         cerr().rdbuf(m_oss.rdbuf()); | ||||
|         clog().rdbuf(m_oss.rdbuf()); | ||||
|     } | ||||
|  | ||||
|     StdErrRedirect::~StdErrRedirect() { | ||||
|         m_targetString += m_oss.str(); | ||||
|         cerr().rdbuf(m_cerrBuf); | ||||
|         clog().rdbuf(m_clogBuf); | ||||
|     } | ||||
|  | ||||
|     RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter) | ||||
|     :   m_runInfo(_config->name()), | ||||
|         m_context(getCurrentMutableContext()), | ||||
|         m_config(_config), | ||||
|         m_reporter(std::move(reporter)), | ||||
|         m_lastAssertionInfo{ "", SourceLineInfo("",0), "", ResultDisposition::Normal } | ||||
|     { | ||||
|         m_context.setRunner(this); | ||||
|         m_context.setConfig(m_config); | ||||
|         m_context.setResultCapture(this); | ||||
|         m_reporter->testRunStarting(m_runInfo); | ||||
|     } | ||||
|  | ||||
|     RunContext::~RunContext() { | ||||
|         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting())); | ||||
|     } | ||||
|  | ||||
|     void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) { | ||||
|         m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount)); | ||||
|     } | ||||
|  | ||||
|     void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) { | ||||
|         m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting())); | ||||
|     } | ||||
|  | ||||
|     Totals RunContext::runTest(TestCase const& testCase) { | ||||
|         Totals prevTotals = m_totals; | ||||
|  | ||||
|         std::string redirectedCout; | ||||
|         std::string redirectedCerr; | ||||
|  | ||||
|         TestCaseInfo testInfo = testCase.getTestCaseInfo(); | ||||
|  | ||||
|         m_reporter->testCaseStarting(testInfo); | ||||
|  | ||||
|         m_activeTestCase = &testCase; | ||||
|  | ||||
|  | ||||
|         ITracker& rootTracker = m_trackerContext.startRun(); | ||||
|         assert(rootTracker.isSectionTracker()); | ||||
|         static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun()); | ||||
|         do { | ||||
|             m_trackerContext.startCycle(); | ||||
|             m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo)); | ||||
|             runCurrentTest(redirectedCout, redirectedCerr); | ||||
|         } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting()); | ||||
|  | ||||
|         Totals deltaTotals = m_totals.delta(prevTotals); | ||||
|         if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) { | ||||
|             deltaTotals.assertions.failed++; | ||||
|             deltaTotals.testCases.passed--; | ||||
|             deltaTotals.testCases.failed++; | ||||
|         } | ||||
|         m_totals.testCases += deltaTotals.testCases; | ||||
|         m_reporter->testCaseEnded(TestCaseStats(testInfo, | ||||
|                                   deltaTotals, | ||||
|                                   redirectedCout, | ||||
|                                   redirectedCerr, | ||||
|                                   aborting())); | ||||
|  | ||||
|         m_activeTestCase = nullptr; | ||||
|         m_testCaseTracker = nullptr; | ||||
|  | ||||
|         return deltaTotals; | ||||
|     } | ||||
|  | ||||
|     IConfigPtr RunContext::config() const { | ||||
|         return m_config; | ||||
|     } | ||||
|  | ||||
|     IStreamingReporter& RunContext::reporter() const { | ||||
|         return *m_reporter; | ||||
|     } | ||||
|  | ||||
|     void RunContext::assertionStarting(AssertionInfo const& info) { | ||||
|         m_reporter->assertionStarting( info ); | ||||
|     } | ||||
|     void RunContext::assertionEnded(AssertionResult const & result) { | ||||
|         if (result.getResultType() == ResultWas::Ok) { | ||||
|             m_totals.assertions.passed++; | ||||
|         } else if (!result.isOk()) { | ||||
|             if( m_activeTestCase->getTestCaseInfo().okToFail() ) | ||||
|                 m_totals.assertions.failedButOk++; | ||||
|             else | ||||
|                 m_totals.assertions.failed++; | ||||
|         } | ||||
|  | ||||
|         // We have no use for the return value (whether messages should be cleared), because messages were made scoped | ||||
|         // and should be let to clear themselves out. | ||||
|         static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); | ||||
|  | ||||
|         // Reset working state | ||||
|         m_lastAssertionInfo = { "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}", m_lastAssertionInfo.resultDisposition }; | ||||
|         m_lastResult = result; | ||||
|     } | ||||
|  | ||||
|     bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) { | ||||
|         ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); | ||||
|         if (!sectionTracker.isOpen()) | ||||
|             return false; | ||||
|         m_activeSections.push_back(§ionTracker); | ||||
|  | ||||
|         m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; | ||||
|  | ||||
|         m_reporter->sectionStarting(sectionInfo); | ||||
|  | ||||
|         assertions = m_totals.assertions; | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     bool RunContext::testForMissingAssertions(Counts& assertions) { | ||||
|         if (assertions.total() != 0) | ||||
|             return false; | ||||
|         if (!m_config->warnAboutMissingAssertions()) | ||||
|             return false; | ||||
|         if (m_trackerContext.currentTracker().hasChildren()) | ||||
|             return false; | ||||
|         m_totals.assertions.failed++; | ||||
|         assertions.failed++; | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void RunContext::sectionEnded(SectionEndInfo const & endInfo) { | ||||
|         Counts assertions = m_totals.assertions - endInfo.prevAssertions; | ||||
|         bool missingAssertions = testForMissingAssertions(assertions); | ||||
|  | ||||
|         if (!m_activeSections.empty()) { | ||||
|             m_activeSections.back()->close(); | ||||
|             m_activeSections.pop_back(); | ||||
|         } | ||||
|  | ||||
|         m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); | ||||
|         m_messages.clear(); | ||||
|     } | ||||
|  | ||||
|     void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { | ||||
|         if (m_unfinishedSections.empty()) | ||||
|             m_activeSections.back()->fail(); | ||||
|         else | ||||
|             m_activeSections.back()->close(); | ||||
|         m_activeSections.pop_back(); | ||||
|  | ||||
|         m_unfinishedSections.push_back(endInfo); | ||||
|     } | ||||
|     void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { | ||||
|         m_reporter->benchmarkStarting( info ); | ||||
|     } | ||||
|     void RunContext::benchmarkEnded( BenchmarkStats const& stats ) { | ||||
|         m_reporter->benchmarkEnded( stats ); | ||||
|     } | ||||
|  | ||||
|     void RunContext::pushScopedMessage(MessageInfo const & message) { | ||||
|         m_messages.push_back(message); | ||||
|     } | ||||
|  | ||||
|     void RunContext::popScopedMessage(MessageInfo const & message) { | ||||
|         m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); | ||||
|     } | ||||
|  | ||||
|     std::string RunContext::getCurrentTestName() const { | ||||
|         return m_activeTestCase | ||||
|             ? m_activeTestCase->getTestCaseInfo().name | ||||
|             : std::string(); | ||||
|     } | ||||
|  | ||||
|     const AssertionResult * RunContext::getLastResult() const { | ||||
|         return &(*m_lastResult); | ||||
|     } | ||||
|  | ||||
|     void RunContext::exceptionEarlyReported() { | ||||
|         m_shouldReportUnexpected = false; | ||||
|     } | ||||
|  | ||||
|     void RunContext::handleFatalErrorCondition( StringRef message ) { | ||||
|         // First notify reporter that bad things happened | ||||
|         m_reporter->fatalErrorEncountered(message); | ||||
|  | ||||
|         // Don't rebuild the result -- the stringification itself can cause more fatal errors | ||||
|         // Instead, fake a result data. | ||||
|         AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); | ||||
|         tempResult.message = message; | ||||
|         AssertionResult result(m_lastAssertionInfo, tempResult); | ||||
|  | ||||
|         getResultCapture().assertionEnded(result); | ||||
|  | ||||
|         handleUnfinishedSections(); | ||||
|  | ||||
|         // Recreate section for test case (as we will lose the one that was in scope) | ||||
|         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); | ||||
|         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); | ||||
|  | ||||
|         Counts assertions; | ||||
|         assertions.failed = 1; | ||||
|         SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); | ||||
|         m_reporter->sectionEnded(testCaseSectionStats); | ||||
|  | ||||
|         auto const& testInfo = m_activeTestCase->getTestCaseInfo(); | ||||
|  | ||||
|         Totals deltaTotals; | ||||
|         deltaTotals.testCases.failed = 1; | ||||
|         deltaTotals.assertions.failed = 1; | ||||
|         m_reporter->testCaseEnded(TestCaseStats(testInfo, | ||||
|                                   deltaTotals, | ||||
|                                   std::string(), | ||||
|                                   std::string(), | ||||
|                                   false)); | ||||
|         m_totals.testCases.failed++; | ||||
|         testGroupEnded(std::string(), m_totals, 1, 1); | ||||
|         m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false)); | ||||
|     } | ||||
|  | ||||
|     bool RunContext::lastAssertionPassed() { | ||||
|          return m_totals.assertions.passed == (m_prevPassed + 1); | ||||
|     } | ||||
|  | ||||
|     void RunContext::assertionPassed() { | ||||
|         ++m_totals.assertions.passed; | ||||
|         m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; | ||||
|         m_lastAssertionInfo.macroName = ""; | ||||
|     } | ||||
|  | ||||
|     void RunContext::assertionRun() { | ||||
|         m_prevPassed = m_totals.assertions.passed; | ||||
|     } | ||||
|  | ||||
|     bool RunContext::aborting() const { | ||||
|         return m_totals.assertions.failed == static_cast<std::size_t>(m_config->abortAfter()); | ||||
|     } | ||||
|  | ||||
|     void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) { | ||||
|         auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); | ||||
|         SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); | ||||
|         m_reporter->sectionStarting(testCaseSection); | ||||
|         Counts prevAssertions = m_totals.assertions; | ||||
|         double duration = 0; | ||||
|         m_shouldReportUnexpected = true; | ||||
|         try { | ||||
|             m_lastAssertionInfo = { "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal }; | ||||
|  | ||||
|             seedRng(*m_config); | ||||
|  | ||||
|             Timer timer; | ||||
|             timer.start(); | ||||
|             if (m_reporter->getPreferences().shouldRedirectStdOut) { | ||||
|                 StreamRedirect coutRedir(cout(), redirectedCout); | ||||
|                 StdErrRedirect errRedir(redirectedCerr); | ||||
|                 invokeActiveTestCase(); | ||||
|             } else { | ||||
|                 invokeActiveTestCase(); | ||||
|             } | ||||
|             duration = timer.getElapsedSeconds(); | ||||
|         } catch (TestFailureException&) { | ||||
|             // This just means the test was aborted due to failure | ||||
|         } catch (...) { | ||||
|             // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions | ||||
|             // are reported without translation at the point of origin. | ||||
|             if (m_shouldReportUnexpected) { | ||||
|                 AssertionHandler | ||||
|                     ( m_lastAssertionInfo.macroName, | ||||
|                       m_lastAssertionInfo.lineInfo, | ||||
|                       m_lastAssertionInfo.capturedExpression, | ||||
|                       m_lastAssertionInfo.resultDisposition ).useActiveException(); | ||||
|             } | ||||
|         } | ||||
|         m_testCaseTracker->close(); | ||||
|         handleUnfinishedSections(); | ||||
|         m_messages.clear(); | ||||
|  | ||||
|         Counts assertions = m_totals.assertions - prevAssertions; | ||||
|         bool missingAssertions = testForMissingAssertions(assertions); | ||||
|         SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); | ||||
|         m_reporter->sectionEnded(testCaseSectionStats); | ||||
|     } | ||||
|  | ||||
|     void RunContext::invokeActiveTestCase() { | ||||
|         FatalConditionHandler fatalConditionHandler; // Handle signals | ||||
|         m_activeTestCase->invoke(); | ||||
|         fatalConditionHandler.reset(); | ||||
|     } | ||||
|  | ||||
|     void RunContext::handleUnfinishedSections() { | ||||
|         // If sections ended prematurely due to an exception we stored their | ||||
|         // infos here so we can tear them down outside the unwind process. | ||||
|         for (auto it = m_unfinishedSections.rbegin(), | ||||
|              itEnd = m_unfinishedSections.rend(); | ||||
|              it != itEnd; | ||||
|              ++it) | ||||
|             sectionEnded(*it); | ||||
|         m_unfinishedSections.clear(); | ||||
|     } | ||||
|  | ||||
|     IResultCapture& getResultCapture() { | ||||
|         if (auto* capture = getCurrentContext().getResultCapture()) | ||||
|             return *capture; | ||||
|         else | ||||
|             CATCH_INTERNAL_ERROR("No result capture instance"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										146
									
								
								include/internal/catch_run_context.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								include/internal/catch_run_context.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
|  /* | ||||
|  *  Created by Phil on 22/10/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_RUNNER_IMPL_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_interfaces_runner.h" | ||||
| #include "catch_interfaces_reporter.h" | ||||
| #include "catch_interfaces_exception.h" | ||||
| #include "catch_config.hpp" | ||||
| #include "catch_test_registry.h" | ||||
| #include "catch_test_case_info.h" | ||||
| #include "catch_capture.hpp" | ||||
| #include "catch_totals.h" | ||||
| #include "catch_test_spec.h" | ||||
| #include "catch_test_case_tracker.h" | ||||
| #include "catch_timer.h" | ||||
| #include "catch_assertionhandler.h" | ||||
| #include "catch_fatal_condition.h" | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct IMutableContext; | ||||
|  | ||||
|     class StreamRedirect { | ||||
|  | ||||
|     public: | ||||
|         StreamRedirect(std::ostream& stream, std::string& targetString); | ||||
|  | ||||
|         ~StreamRedirect(); | ||||
|  | ||||
|     private: | ||||
|         std::ostream& m_stream; | ||||
|         std::streambuf* m_prevBuf; | ||||
|         std::ostringstream m_oss; | ||||
|         std::string& m_targetString; | ||||
|     }; | ||||
|  | ||||
|     // StdErr has two constituent streams in C++, std::cerr and std::clog | ||||
|     // This means that we need to redirect 2 streams into 1 to keep proper | ||||
|     // order of writes and cannot use StreamRedirect on its own | ||||
|     class StdErrRedirect { | ||||
|     public: | ||||
|         StdErrRedirect(std::string& targetString); | ||||
|         ~StdErrRedirect(); | ||||
|     private: | ||||
|         std::streambuf* m_cerrBuf; | ||||
|         std::streambuf* m_clogBuf; | ||||
|         std::ostringstream m_oss; | ||||
|         std::string& m_targetString; | ||||
|     }; | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|     class RunContext : public IResultCapture, public IRunner { | ||||
|  | ||||
|     public: | ||||
|         RunContext( RunContext const& ) = delete; | ||||
|         RunContext& operator =( RunContext const& ) = delete; | ||||
|  | ||||
|         explicit RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter); | ||||
|  | ||||
|         virtual ~RunContext(); | ||||
|  | ||||
|         void testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount); | ||||
|         void testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount); | ||||
|  | ||||
|         Totals runTest(TestCase const& testCase); | ||||
|  | ||||
|         IConfigPtr config() const; | ||||
|         IStreamingReporter& reporter() const; | ||||
|  | ||||
|     private: // IResultCapture | ||||
|  | ||||
|  | ||||
|         void assertionStarting(AssertionInfo const& info) override; | ||||
|         void assertionEnded(AssertionResult const& result) override; | ||||
|  | ||||
|         bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override; | ||||
|         bool testForMissingAssertions(Counts& assertions); | ||||
|  | ||||
|         void sectionEnded(SectionEndInfo const& endInfo) override; | ||||
|         void sectionEndedEarly(SectionEndInfo const& endInfo) override; | ||||
|  | ||||
|         void benchmarkStarting( BenchmarkInfo const& info ) override; | ||||
|         void benchmarkEnded( BenchmarkStats const& stats ) override; | ||||
|  | ||||
|         void pushScopedMessage(MessageInfo const& message) override; | ||||
|         void popScopedMessage(MessageInfo const& message) override; | ||||
|  | ||||
|         std::string getCurrentTestName() const override; | ||||
|  | ||||
|         const AssertionResult* getLastResult() const override; | ||||
|  | ||||
|         void exceptionEarlyReported() override; | ||||
|  | ||||
|         void handleFatalErrorCondition( StringRef message ) override; | ||||
|  | ||||
|         bool lastAssertionPassed() override; | ||||
|  | ||||
|         void assertionPassed() override; | ||||
|  | ||||
|         void assertionRun() override; | ||||
|  | ||||
|     public: | ||||
|         // !TBD We need to do this another way! | ||||
|         bool aborting() const override; | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void runCurrentTest(std::string& redirectedCout, std::string& redirectedCerr); | ||||
|         void invokeActiveTestCase(); | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void handleUnfinishedSections(); | ||||
|  | ||||
|         TestRunInfo m_runInfo; | ||||
|         IMutableContext& m_context; | ||||
|         TestCase const* m_activeTestCase = nullptr; | ||||
|         ITracker* m_testCaseTracker; | ||||
|         Option<AssertionResult> m_lastResult; | ||||
|  | ||||
|         IConfigPtr m_config; | ||||
|         Totals m_totals; | ||||
|         IStreamingReporterPtr m_reporter; | ||||
|         std::vector<MessageInfo> m_messages; | ||||
|         AssertionInfo m_lastAssertionInfo; | ||||
|         std::vector<SectionEndInfo> m_unfinishedSections; | ||||
|         std::vector<ITracker*> m_activeSections; | ||||
|         TrackerContext m_trackerContext; | ||||
|         std::size_t m_prevPassed = 0; | ||||
|         bool m_shouldReportUnexpected = true; | ||||
|     }; | ||||
|  | ||||
|     IResultCapture& getResultCapture(); | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED | ||||
| @@ -5,24 +5,12 @@ | ||||
|  *  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_SECTION_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED | ||||
| 
 | ||||
| #include "catch_section.h" | ||||
| #include "catch_capture.hpp" | ||||
| #include "catch_compiler_capabilities.h" | ||||
| 
 | ||||
| namespace Catch { | ||||
| 
 | ||||
|     SectionInfo::SectionInfo | ||||
|         (   SourceLineInfo const& _lineInfo, | ||||
|             std::string const& _name, | ||||
|             std::string const& _description ) | ||||
|     :   name( _name ), | ||||
|         description( _description ), | ||||
|         lineInfo( _lineInfo ) | ||||
|     {} | ||||
| 
 | ||||
|     Section::Section( SectionInfo const& info ) | ||||
|     :   m_info( info ), | ||||
|         m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) | ||||
| @@ -54,5 +42,3 @@ namespace Catch { | ||||
| 
 | ||||
| 
 | ||||
| } // end namespace Catch
 | ||||
| 
 | ||||
| #endif // TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
 | ||||
| @@ -9,7 +9,7 @@ | ||||
| #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED | ||||
|  | ||||
| #include "catch_section_info.h" | ||||
| #include "catch_totals.hpp" | ||||
| #include "catch_totals.h" | ||||
| #include "catch_timer.h" | ||||
|  | ||||
| #include <string> | ||||
| @@ -22,7 +22,7 @@ namespace Catch { | ||||
|         ~Section(); | ||||
|  | ||||
|         // This indicates whether the section should be executed or not | ||||
|         operator bool() const; | ||||
|         explicit operator bool() const; | ||||
|  | ||||
|     private: | ||||
|         SectionInfo m_info; | ||||
| @@ -35,12 +35,7 @@ namespace Catch { | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #ifdef CATCH_CONFIG_VARIADIC_MACROS | ||||
|     #define INTERNAL_CATCH_SECTION( ... ) \ | ||||
|         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) | ||||
| #else | ||||
|     #define INTERNAL_CATCH_SECTION( name, desc ) \ | ||||
|         if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash