mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Merge branch 'reevaluate' into dev-modernize
This commit is contained in:
		@@ -122,8 +122,11 @@ CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external)
 | 
			
		||||
# Please keep these ordered alphabetically
 | 
			
		||||
set(INTERNAL_HEADERS
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_approx.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_assertionhandler.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_assertioninfo.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_assertionresult.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_capture.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_capture_matchers.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_clara.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_commandline.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_common.h
 | 
			
		||||
@@ -132,12 +135,11 @@ set(INTERNAL_HEADERS
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_console_colour.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_context.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_debugger.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_decomposer.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_default_main.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_enforce.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_errno_guard.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_evaluate.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_exception_translator_registry.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_expression_lhs.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_fatal_condition.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_impl.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_interfaces_capture.h
 | 
			
		||||
@@ -162,7 +164,6 @@ set(INTERNAL_HEADERS
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_reenable_warnings.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_reporter_registrars.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_reporter_registry.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_result_builder.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_result_type.h
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_run_context.hpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_benchmark.h
 | 
			
		||||
@@ -197,16 +198,18 @@ set(INTERNAL_HEADERS
 | 
			
		||||
        )
 | 
			
		||||
set(IMPL_SOURCES
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_approx.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_assertionhandler.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_assertionresult.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_benchmark.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_capture_matchers.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_commandline.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_common.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_config.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_console_colour.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_context.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_debugger.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_decomposer.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_errno_guard.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_evaluate.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_fatal_condition.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_list.cpp
 | 
			
		||||
@@ -217,7 +220,6 @@ set(IMPL_SOURCES
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_notimplemented_exception.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_registry_hub.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_result_builder.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_result_type.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_run_context.cpp
 | 
			
		||||
        ${HEADER_DIR}/internal/catch_section.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,10 @@
 | 
			
		||||
#include "internal/catch_compiler_capabilities.h"
 | 
			
		||||
#include "internal/catch_interfaces_tag_alias_registry.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
 | 
			
		||||
#include "internal/catch_test_case_info.h"
 | 
			
		||||
@@ -72,8 +76,8 @@
 | 
			
		||||
 | 
			
		||||
#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 )
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
#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__ )
 | 
			
		||||
@@ -86,8 +90,8 @@
 | 
			
		||||
 | 
			
		||||
#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 )
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
#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__ )
 | 
			
		||||
@@ -132,8 +136,8 @@
 | 
			
		||||
 | 
			
		||||
#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 )
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
#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__ )
 | 
			
		||||
@@ -146,8 +150,8 @@
 | 
			
		||||
 | 
			
		||||
#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 )
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
#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__ )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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.c_str();
 | 
			
		||||
        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().c_str() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
@@ -10,54 +10,24 @@
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
    std::string AssertionResultData::reconstructExpression() const {
 | 
			
		||||
 | 
			
		||||
    bool DecomposedExpression::isBinaryExpression() const {
 | 
			
		||||
        return false;
 | 
			
		||||
        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();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
    AssertionInfo::AssertionInfo(   char const * _macroName,
 | 
			
		||||
                                    SourceLineInfo const& _lineInfo,
 | 
			
		||||
                                    char const * _capturedExpression,
 | 
			
		||||
                                    ResultDisposition::Flags _resultDisposition)
 | 
			
		||||
    :   macroName( _macroName ),
 | 
			
		||||
        lineInfo( _lineInfo ),
 | 
			
		||||
        capturedExpression( _capturedExpression ),
 | 
			
		||||
        resultDisposition( _resultDisposition )
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    void AssertionResultData::negate( bool parenthesize ) {
 | 
			
		||||
        negated = !negated;
 | 
			
		||||
        parenthesized = parenthesize;
 | 
			
		||||
        if( resultType == ResultWas::Ok )
 | 
			
		||||
            resultType = ResultWas::ExpressionFailed;
 | 
			
		||||
        else if( resultType == ResultWas::ExpressionFailed )
 | 
			
		||||
            resultType = ResultWas::Ok;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string const& AssertionResultData::reconstructExpression() const {
 | 
			
		||||
        if( decomposedExpression != nullptr ) {
 | 
			
		||||
            decomposedExpression->reconstructExpression( reconstructedExpression );
 | 
			
		||||
            if( parenthesized ) {
 | 
			
		||||
                reconstructedExpression.insert( 0, 1, '(' );
 | 
			
		||||
                reconstructedExpression.append( 1, ')' );
 | 
			
		||||
            }
 | 
			
		||||
            if( negated ) {
 | 
			
		||||
                reconstructedExpression.insert( 0, 1, '!' );
 | 
			
		||||
            }
 | 
			
		||||
            decomposedExpression = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        return reconstructedExpression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AssertionResult::AssertionResult() {}
 | 
			
		||||
 | 
			
		||||
    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
 | 
			
		||||
    :   m_info( info ),
 | 
			
		||||
        m_resultData( data )
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    AssertionResult::~AssertionResult() {}
 | 
			
		||||
 | 
			
		||||
    // Result was a success
 | 
			
		||||
    bool AssertionResult::succeeded() const {
 | 
			
		||||
        return Catch::isOk( m_resultData.resultType );
 | 
			
		||||
@@ -82,16 +52,16 @@ namespace Catch {
 | 
			
		||||
 | 
			
		||||
    std::string AssertionResult::getExpression() const {
 | 
			
		||||
        if (isFalseTest(m_info.resultDisposition))
 | 
			
		||||
            return '!' + std::string(m_info.capturedExpression);
 | 
			
		||||
            return '!' + std::string(m_info.capturedExpression.c_str());
 | 
			
		||||
        else
 | 
			
		||||
            return std::string(m_info.capturedExpression);
 | 
			
		||||
            return std::string(m_info.capturedExpression.c_str());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string AssertionResult::getExpressionInMacro() const {
 | 
			
		||||
        if( m_info.macroName[0] == 0 )
 | 
			
		||||
            return std::string(m_info.capturedExpression);
 | 
			
		||||
            return std::string(m_info.capturedExpression.c_str());
 | 
			
		||||
        else
 | 
			
		||||
            return std::string(m_info.macroName) + "( " + m_info.capturedExpression + " )";
 | 
			
		||||
            return std::string(m_info.macroName.c_str()) + "( " + m_info.capturedExpression.c_str() + " )";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool AssertionResult::hasExpandedExpression() const {
 | 
			
		||||
@@ -99,7 +69,10 @@ namespace Catch {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string AssertionResult::getExpandedExpression() const {
 | 
			
		||||
        return m_resultData.reconstructExpression();
 | 
			
		||||
        std::string expr = m_resultData.reconstructExpression();
 | 
			
		||||
        return expr.empty()
 | 
			
		||||
                ? getExpression()
 | 
			
		||||
                : expr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string AssertionResult::getMessage() const {
 | 
			
		||||
@@ -110,15 +83,7 @@ namespace Catch {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string AssertionResult::getTestMacroName() const {
 | 
			
		||||
        return m_info.macroName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AssertionResult::discardDecomposedExpression() const {
 | 
			
		||||
        m_resultData.decomposedExpression = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void AssertionResult::expandDecomposedExpression() const {
 | 
			
		||||
        m_resultData.reconstructExpression();
 | 
			
		||||
        return m_info.macroName.c_str();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
} // end namespace Catch
 | 
			
		||||
 
 | 
			
		||||
@@ -9,71 +9,36 @@
 | 
			
		||||
#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
 | 
			
		||||
    {
 | 
			
		||||
        DecomposedExpression() = default;
 | 
			
		||||
        DecomposedExpression( DecomposedExpression const& ) = default;
 | 
			
		||||
        DecomposedExpression& operator = ( DecomposedExpression const& ) = delete;
 | 
			
		||||
 | 
			
		||||
        virtual ~DecomposedExpression() = default;
 | 
			
		||||
        virtual bool isBinaryExpression() const;
 | 
			
		||||
        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& );
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct AssertionInfo
 | 
			
		||||
    {
 | 
			
		||||
        AssertionInfo() = default;
 | 
			
		||||
        AssertionInfo(  char const * _macroName,
 | 
			
		||||
                        SourceLineInfo const& _lineInfo,
 | 
			
		||||
                        char const * _capturedExpression,
 | 
			
		||||
                        ResultDisposition::Flags _resultDisposition);
 | 
			
		||||
 | 
			
		||||
        char const * macroName = nullptr;
 | 
			
		||||
        SourceLineInfo lineInfo;
 | 
			
		||||
        char const * capturedExpression = nullptr;
 | 
			
		||||
        ResultDisposition::Flags resultDisposition = ResultDisposition::Normal;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct AssertionResultData
 | 
			
		||||
    {
 | 
			
		||||
        void negate( bool parenthesize );
 | 
			
		||||
        std::string const& reconstructExpression() const;
 | 
			
		||||
        AssertionResultData() = delete;
 | 
			
		||||
 | 
			
		||||
        AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression )
 | 
			
		||||
        :   resultType( _resultType ),
 | 
			
		||||
            lazyExpression( _lazyExpression )
 | 
			
		||||
        {}
 | 
			
		||||
 | 
			
		||||
        mutable DecomposedExpression const* decomposedExpression = nullptr;
 | 
			
		||||
        mutable std::string reconstructedExpression;
 | 
			
		||||
        std::string message;
 | 
			
		||||
        ResultWas::OfType resultType = ResultWas::Unknown;
 | 
			
		||||
        bool negated = false;
 | 
			
		||||
        bool parenthesized = false;
 | 
			
		||||
        std::string message;
 | 
			
		||||
 | 
			
		||||
        LazyExpression lazyExpression;
 | 
			
		||||
 | 
			
		||||
        std::string reconstructExpression() const;
 | 
			
		||||
        mutable std::string reconstructedExpression;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class AssertionResult {
 | 
			
		||||
    public:
 | 
			
		||||
        AssertionResult();
 | 
			
		||||
        AssertionResult() = delete;
 | 
			
		||||
        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
 | 
			
		||||
        ~AssertionResult();
 | 
			
		||||
 | 
			
		||||
        AssertionResult( AssertionResult const& )              = default;
 | 
			
		||||
        AssertionResult( AssertionResult && )                  = default;
 | 
			
		||||
        AssertionResult& operator = ( AssertionResult const& ) = default;
 | 
			
		||||
        AssertionResult& operator = ( AssertionResult && )     = default;
 | 
			
		||||
 | 
			
		||||
        bool isOk() const;
 | 
			
		||||
        bool succeeded() const;
 | 
			
		||||
@@ -87,10 +52,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;
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@
 | 
			
		||||
 | 
			
		||||
#include "catch_benchmark.h"
 | 
			
		||||
#include "catch_capture.hpp"
 | 
			
		||||
#include "catch_interfaces_reporter.h"
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,14 +8,9 @@
 | 
			
		||||
#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_FAST_COMPILE)
 | 
			
		||||
@@ -23,43 +18,45 @@
 | 
			
		||||
// 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_TRY
 | 
			
		||||
#define INTERNAL_CATCH_CATCH( capturer, disposition )
 | 
			
		||||
#define INTERNAL_CATCH_TRY( capturer ) capturer.setExceptionGuard();
 | 
			
		||||
#define INTERNAL_CATCH_CATCH( capturer ) capturer.unsetExceptionGuard();
 | 
			
		||||
 | 
			
		||||
#else // CATCH_CONFIG_FAST_COMPILE
 | 
			
		||||
 | 
			
		||||
#include "catch_debugger.h"
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// 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 try
 | 
			
		||||
#define INTERNAL_CATCH_CATCH( capturer, disposition ) catch(...) { capturer.useActiveException( disposition ); }
 | 
			
		||||
#define INTERNAL_CATCH_TRY( capturer ) try
 | 
			
		||||
#define INTERNAL_CATCH_CATCH( capturer ) catch(...) { capturer.useActiveException(); }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \
 | 
			
		||||
    do { \
 | 
			
		||||
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__, resultDisposition ); \
 | 
			
		||||
        INTERNAL_CATCH_TRY { \
 | 
			
		||||
        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__, resultDisposition ); \
 | 
			
		||||
        INTERNAL_CATCH_TRY( catchAssertionHandler ) { \
 | 
			
		||||
            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \
 | 
			
		||||
            ( __catchResult <= __VA_ARGS__ ).endExpression(); \
 | 
			
		||||
            catchAssertionHandler.handle( Catch::Decomposer() <= __VA_ARGS__ ); \
 | 
			
		||||
            CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \
 | 
			
		||||
        } INTERNAL_CATCH_CATCH( __catchResult, resultDisposition ) \
 | 
			
		||||
        INTERNAL_CATCH_REACT( __catchResult ) \
 | 
			
		||||
        } 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 &&.
 | 
			
		||||
 | 
			
		||||
@@ -76,117 +73,84 @@
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \
 | 
			
		||||
    do { \
 | 
			
		||||
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__, resultDisposition ); \
 | 
			
		||||
        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__, resultDisposition ); \
 | 
			
		||||
        try { \
 | 
			
		||||
            static_cast<void>(__VA_ARGS__); \
 | 
			
		||||
            __catchResult.captureResult( Catch::ResultWas::Ok ); \
 | 
			
		||||
            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, ... ) \
 | 
			
		||||
    do { \
 | 
			
		||||
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__, resultDisposition); \
 | 
			
		||||
        if( __catchResult.allowThrows() ) \
 | 
			
		||||
        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__, resultDisposition); \
 | 
			
		||||
        if( catchAssertionHandler.allowThrows() ) \
 | 
			
		||||
            try { \
 | 
			
		||||
                static_cast<void>(__VA_ARGS__); \
 | 
			
		||||
                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
 | 
			
		||||
                catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
 | 
			
		||||
            } \
 | 
			
		||||
            catch( ... ) { \
 | 
			
		||||
                __catchResult.captureExpectedException( "" ); \
 | 
			
		||||
                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, #expr ", " #exceptionType, resultDisposition ); \
 | 
			
		||||
        if( __catchResult.allowThrows() ) \
 | 
			
		||||
        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType, resultDisposition ); \
 | 
			
		||||
        if( catchAssertionHandler.allowThrows() ) \
 | 
			
		||||
            try { \
 | 
			
		||||
                static_cast<void>(expr); \
 | 
			
		||||
                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
 | 
			
		||||
                catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
 | 
			
		||||
            } \
 | 
			
		||||
            catch( exceptionType const& ) { \
 | 
			
		||||
                __catchResult.captureResult( Catch::ResultWas::Ok ); \
 | 
			
		||||
                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() )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#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 ) \
 | 
			
		||||
        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
 | 
			
		||||
        catchAssertionHandler.handle( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str().c_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;
 | 
			
		||||
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \
 | 
			
		||||
    do { \
 | 
			
		||||
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
 | 
			
		||||
        INTERNAL_CATCH_TRY { \
 | 
			
		||||
            __catchResult.captureMatch( arg, matcher, #matcher ); \
 | 
			
		||||
        } INTERNAL_CATCH_CATCH( __catchResult, resultDisposition ) \
 | 
			
		||||
        INTERNAL_CATCH_REACT( __catchResult ) \
 | 
			
		||||
    } while( Catch::alwaysFalse() )
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// 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, #__VA_ARGS__ ", " #matcher, resultDisposition); \
 | 
			
		||||
        if( __catchResult.allowThrows() ) \
 | 
			
		||||
        Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, #__VA_ARGS__ ", " #matcher, resultDisposition ); \
 | 
			
		||||
        if( catchAssertionHandler.allowThrows() ) \
 | 
			
		||||
            try { \
 | 
			
		||||
                static_cast<void>(__VA_ARGS__); \
 | 
			
		||||
                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
 | 
			
		||||
                catchAssertionHandler.handle( Catch::ResultWas::DidntThrowException ); \
 | 
			
		||||
            } \
 | 
			
		||||
            catch( ... ) { \
 | 
			
		||||
                __catchResult.captureExpectedException( matcher ); \
 | 
			
		||||
                handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \
 | 
			
		||||
            } \
 | 
			
		||||
        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_MATCHES( macroName, exceptionType, resultDisposition, matcher, expr ) \
 | 
			
		||||
    do { \
 | 
			
		||||
        Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr ", " #exceptionType ", " #matcher, resultDisposition ); \
 | 
			
		||||
        if( __catchResult.allowThrows() ) \
 | 
			
		||||
            try { \
 | 
			
		||||
                static_cast<void>(expr); \
 | 
			
		||||
                __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
 | 
			
		||||
            } \
 | 
			
		||||
            catch( exceptionType const& ex ) { \
 | 
			
		||||
                __catchResult.captureMatch( ex, matcher, #matcher ); \
 | 
			
		||||
            } \
 | 
			
		||||
            catch( ... ) { \
 | 
			
		||||
                __catchResult.useActiveException( resultDisposition ); \
 | 
			
		||||
            } \
 | 
			
		||||
        else \
 | 
			
		||||
            __catchResult.captureResult( Catch::ResultWas::Ok ); \
 | 
			
		||||
        INTERNAL_CATCH_REACT( __catchResult ) \
 | 
			
		||||
    } while( Catch::alwaysFalse() )
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								include/internal/catch_capture_matchers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								include/internal/catch_capture_matchers.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  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  ) {
 | 
			
		||||
        MatchExpr<std::string, StringMatcher const&> expr( Catch::translateActiveException(), matcher, matcherString );
 | 
			
		||||
        handler.handle( expr );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
							
								
								
									
										87
									
								
								include/internal/catch_capture_matchers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								include/internal/catch_capture_matchers.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  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.hpp"
 | 
			
		||||
#include "catch_matchers_string.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.c_str();
 | 
			
		||||
            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, #arg ", " #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, #__VA_ARGS__ ", " #exceptionType ", " #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
 | 
			
		||||
@@ -15,7 +15,6 @@
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
    SourceLineInfo::SourceLineInfo() noexcept : file(""), line( 0 ){}
 | 
			
		||||
    SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) noexcept
 | 
			
		||||
    :   file( _file ),
 | 
			
		||||
        line( _line )
 | 
			
		||||
 
 | 
			
		||||
@@ -47,10 +47,10 @@ namespace Catch {
 | 
			
		||||
 | 
			
		||||
    struct SourceLineInfo {
 | 
			
		||||
 | 
			
		||||
        SourceLineInfo() noexcept;
 | 
			
		||||
        SourceLineInfo() = delete;
 | 
			
		||||
        SourceLineInfo( char const* _file, std::size_t _line ) noexcept;
 | 
			
		||||
 | 
			
		||||
        SourceLineInfo(SourceLineInfo const& other)          = default;
 | 
			
		||||
        SourceLineInfo( SourceLineInfo const& other )        = default;
 | 
			
		||||
        SourceLineInfo( SourceLineInfo && )                  = default;
 | 
			
		||||
        SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
 | 
			
		||||
        SourceLineInfo& operator = ( SourceLineInfo && )     = default;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								include/internal/catch_decomposer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								include/internal/catch_decomposer.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  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 {
 | 
			
		||||
 | 
			
		||||
    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, std::string const& 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										164
									
								
								include/internal/catch_decomposer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								include/internal/catch_decomposer.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  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)
 | 
			
		||||
#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() = default;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, std::string const& op, std::string const& rhs );
 | 
			
		||||
 | 
			
		||||
    template<typename LhsT, typename RhsT>
 | 
			
		||||
    class BinaryExpr  : public ITransientExpression {
 | 
			
		||||
        bool m_result;
 | 
			
		||||
        LhsT m_lhs;
 | 
			
		||||
        std::string 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 comparisionResult, LhsT lhs, StringRef op, RhsT rhs )
 | 
			
		||||
        :   m_result( comparisionResult ),
 | 
			
		||||
            m_lhs( lhs ),
 | 
			
		||||
            m_op( op.c_str() ),
 | 
			
		||||
            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 lhs, RhsT&& 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( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; };
 | 
			
		||||
 | 
			
		||||
    template<typename LhsT, typename RhsT>
 | 
			
		||||
    auto compareNotEqual( LhsT 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( int 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&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
 | 
			
		||||
            return BinaryExpr<LhsT, RhsT&>( 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&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
 | 
			
		||||
            return BinaryExpr<LhsT, RhsT&>( 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&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
 | 
			
		||||
            return BinaryExpr<LhsT, RhsT&>( m_lhs > rhs, m_lhs, ">", rhs );
 | 
			
		||||
        }
 | 
			
		||||
        template<typename RhsT>
 | 
			
		||||
        auto operator < ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
 | 
			
		||||
            return BinaryExpr<LhsT, RhsT&>( m_lhs < rhs, m_lhs, "<", rhs );
 | 
			
		||||
        }
 | 
			
		||||
        template<typename RhsT>
 | 
			
		||||
        auto operator >= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
 | 
			
		||||
            return BinaryExpr<LhsT, RhsT&>( m_lhs >= rhs, m_lhs, ">=", rhs );
 | 
			
		||||
        }
 | 
			
		||||
        template<typename RhsT>
 | 
			
		||||
        auto operator <= ( RhsT&& rhs ) -> BinaryExpr<LhsT, RhsT&> const {
 | 
			
		||||
            return BinaryExpr<LhsT, RhsT&>( 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& lhs ) -> ExprLhs<T&> {
 | 
			
		||||
            return ExprLhs<T&>( lhs );
 | 
			
		||||
        }
 | 
			
		||||
        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
 | 
			
		||||
@@ -1,38 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  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)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "catch_evaluate.hpp"
 | 
			
		||||
 | 
			
		||||
#include "catch_enforce.h"
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
namespace Internal {
 | 
			
		||||
 | 
			
		||||
    const char* operatorName(Operator op) {
 | 
			
		||||
        switch (op) {
 | 
			
		||||
            case IsEqualTo:
 | 
			
		||||
                return "==";
 | 
			
		||||
            case IsNotEqualTo:
 | 
			
		||||
                return "!=";
 | 
			
		||||
            case IsLessThan:
 | 
			
		||||
                return "<";
 | 
			
		||||
            case IsGreaterThan:
 | 
			
		||||
                return ">";
 | 
			
		||||
            case IsLessThanOrEqualTo:
 | 
			
		||||
                return "<=";
 | 
			
		||||
            case IsGreaterThanOrEqualTo:
 | 
			
		||||
                return ">=";
 | 
			
		||||
            default:
 | 
			
		||||
                CATCH_ERROR("Attempting to translate unknown operator!");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // nullptr_t support based on pull request #154 from Konstantin Baumann
 | 
			
		||||
    std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
 | 
			
		||||
 | 
			
		||||
} // end of namespace Internal
 | 
			
		||||
} // end of namespace Catch
 | 
			
		||||
@@ -1,109 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  Created by Phil on 04/03/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_EVALUATE_HPP_INCLUDED
 | 
			
		||||
#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
namespace Internal {
 | 
			
		||||
 | 
			
		||||
    enum Operator {
 | 
			
		||||
        IsEqualTo,
 | 
			
		||||
        IsNotEqualTo,
 | 
			
		||||
        IsLessThan,
 | 
			
		||||
        IsGreaterThan,
 | 
			
		||||
        IsLessThanOrEqualTo,
 | 
			
		||||
        IsGreaterThanOrEqualTo
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const char* operatorName(Operator op);
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    T& removeConst(T const &t) { return const_cast<T&>(t); }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // So the compare overloads can be operator agnostic we convey the operator as a template
 | 
			
		||||
    // enum, which is used to specialise an Evaluator for doing the comparison.
 | 
			
		||||
    template<Operator Op>
 | 
			
		||||
    struct Evaluator{};
 | 
			
		||||
 | 
			
		||||
    template<>
 | 
			
		||||
    struct Evaluator<IsEqualTo> {
 | 
			
		||||
        template<typename T1, typename T2>
 | 
			
		||||
        static bool evaluate( T1 const& lhs, T2 const& rhs) {
 | 
			
		||||
            return bool(removeConst(lhs) == removeConst(rhs) );
 | 
			
		||||
        }
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        static bool evaluate( int lhs, T* rhs) {
 | 
			
		||||
            return reinterpret_cast<void const*>( lhs ) ==  rhs;
 | 
			
		||||
        }
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        static bool evaluate( T* lhs, int rhs) {
 | 
			
		||||
            return lhs == reinterpret_cast<void const*>( rhs );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    template<>
 | 
			
		||||
    struct Evaluator<IsNotEqualTo> {
 | 
			
		||||
        template<typename T1, typename T2>
 | 
			
		||||
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
 | 
			
		||||
            return bool(removeConst(lhs) != removeConst(rhs) );
 | 
			
		||||
        }
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        static bool evaluate( int lhs, T* rhs) {
 | 
			
		||||
            return reinterpret_cast<void const*>( lhs ) !=  rhs;
 | 
			
		||||
        }
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        static bool evaluate( T* lhs, int rhs) {
 | 
			
		||||
            return lhs != reinterpret_cast<void const*>( rhs );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    template<>
 | 
			
		||||
    struct Evaluator<IsLessThan> {
 | 
			
		||||
        template<typename T1, typename T2>
 | 
			
		||||
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
 | 
			
		||||
            return bool(removeConst(lhs) < removeConst(rhs) );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    template<>
 | 
			
		||||
    struct Evaluator<IsGreaterThan> {
 | 
			
		||||
        template<typename T1, typename T2>
 | 
			
		||||
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
 | 
			
		||||
            return bool(removeConst(lhs) > removeConst(rhs) );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    template<>
 | 
			
		||||
    struct Evaluator<IsGreaterThanOrEqualTo> {
 | 
			
		||||
        template<typename T1, typename T2>
 | 
			
		||||
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
 | 
			
		||||
            return bool(removeConst(lhs) >= removeConst(rhs) );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    template<>
 | 
			
		||||
    struct Evaluator<IsLessThanOrEqualTo> {
 | 
			
		||||
        template<typename T1, typename T2>
 | 
			
		||||
        static bool evaluate( T1 const& lhs, T2 const& rhs ) {
 | 
			
		||||
            return bool(removeConst(lhs) <= removeConst(rhs) );
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
} // end of namespace Internal
 | 
			
		||||
} // end of namespace Catch
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
 | 
			
		||||
@@ -6,8 +6,8 @@
 | 
			
		||||
 *  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"
 | 
			
		||||
#include "catch_result_builder.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __OBJC__
 | 
			
		||||
#import "Foundation/Foundation.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,176 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  Created by Phil on 11/5/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_EXPRESSION_LHS_HPP_INCLUDED
 | 
			
		||||
#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include "catch_result_builder.h"
 | 
			
		||||
#include "catch_evaluate.hpp"
 | 
			
		||||
#include "catch_tostring.h"
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
template<typename LhsT, Internal::Operator Op, typename RhsT>
 | 
			
		||||
class BinaryExpression;
 | 
			
		||||
 | 
			
		||||
template<typename ArgT, typename MatcherT>
 | 
			
		||||
class MatchExpression;
 | 
			
		||||
 | 
			
		||||
// Wraps the LHS of an expression and overloads comparison operators
 | 
			
		||||
// for also capturing those and RHS (if any)
 | 
			
		||||
template<typename T>
 | 
			
		||||
class ExpressionLhs : public DecomposedExpression {
 | 
			
		||||
public:
 | 
			
		||||
    ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
 | 
			
		||||
 | 
			
		||||
    ExpressionLhs( ExpressionLhs const& ) = default;
 | 
			
		||||
    ExpressionLhs& operator = ( const ExpressionLhs& ) = delete;
 | 
			
		||||
 | 
			
		||||
    template<typename RhsT>
 | 
			
		||||
    BinaryExpression<T, Internal::IsEqualTo, RhsT const&>
 | 
			
		||||
    operator == ( RhsT const& rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsEqualTo>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename RhsT>
 | 
			
		||||
    BinaryExpression<T, Internal::IsNotEqualTo, RhsT const&>
 | 
			
		||||
    operator != ( RhsT const& rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsNotEqualTo>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename RhsT>
 | 
			
		||||
    BinaryExpression<T, Internal::IsLessThan, RhsT const&>
 | 
			
		||||
    operator < ( RhsT const& rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsLessThan>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename RhsT>
 | 
			
		||||
    BinaryExpression<T, Internal::IsGreaterThan, RhsT const&>
 | 
			
		||||
    operator > ( RhsT const& rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsGreaterThan>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename RhsT>
 | 
			
		||||
    BinaryExpression<T, Internal::IsLessThanOrEqualTo, RhsT const&>
 | 
			
		||||
    operator <= ( RhsT const& rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename RhsT>
 | 
			
		||||
    BinaryExpression<T, Internal::IsGreaterThanOrEqualTo, RhsT const&>
 | 
			
		||||
    operator >= ( RhsT const& rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BinaryExpression<T, Internal::IsEqualTo, bool> operator == ( bool rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsEqualTo>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    BinaryExpression<T, Internal::IsNotEqualTo, bool> operator != ( bool rhs ) {
 | 
			
		||||
        return captureExpression<Internal::IsNotEqualTo>( rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void endExpression() {
 | 
			
		||||
        m_truthy = m_lhs ? true : false;
 | 
			
		||||
        m_rb
 | 
			
		||||
            .setResultType( m_truthy )
 | 
			
		||||
            .endExpression( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reconstructExpression( std::string& dest ) const override {
 | 
			
		||||
        dest = ::Catch::Detail::stringify( m_lhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    template<Internal::Operator Op, typename RhsT>
 | 
			
		||||
    BinaryExpression<T, Op, RhsT&> captureExpression( RhsT& rhs ) const {
 | 
			
		||||
        return BinaryExpression<T, Op, RhsT&>( m_rb, m_lhs, rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<Internal::Operator Op>
 | 
			
		||||
    BinaryExpression<T, Op, bool> captureExpression( bool rhs ) const {
 | 
			
		||||
        return BinaryExpression<T, Op, bool>( m_rb, m_lhs, rhs );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    ResultBuilder& m_rb;
 | 
			
		||||
    T m_lhs;
 | 
			
		||||
    bool m_truthy = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename LhsT, Internal::Operator Op, typename RhsT>
 | 
			
		||||
class BinaryExpression : public DecomposedExpression {
 | 
			
		||||
public:
 | 
			
		||||
    BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs )
 | 
			
		||||
        : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {}
 | 
			
		||||
 | 
			
		||||
    BinaryExpression( BinaryExpression const& ) = default;
 | 
			
		||||
    BinaryExpression& operator = ( BinaryExpression const& ) = delete;
 | 
			
		||||
 | 
			
		||||
    void endExpression() const {
 | 
			
		||||
        m_rb
 | 
			
		||||
            .setResultType(  Internal::Evaluator<Op>::evaluate( m_lhs, m_rhs ) )
 | 
			
		||||
            .endExpression( *this );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool isBinaryExpression() const override {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reconstructExpression( std::string& dest ) const override {
 | 
			
		||||
        std::string lhs = ::Catch::Detail::stringify( m_lhs );
 | 
			
		||||
        std::string rhs = ::Catch::Detail::stringify( m_rhs );
 | 
			
		||||
        char delim = lhs.size() + rhs.size() < 40 &&
 | 
			
		||||
                     lhs.find('\n') == std::string::npos &&
 | 
			
		||||
                     rhs.find('\n') == std::string::npos ? ' ' : '\n';
 | 
			
		||||
        dest.reserve( 7 + lhs.size() + rhs.size() );
 | 
			
		||||
                   // 2 for spaces around operator
 | 
			
		||||
                   // 2 for operator
 | 
			
		||||
                   // 2 for parentheses (conditionally added later)
 | 
			
		||||
                   // 1 for negation (conditionally added later)
 | 
			
		||||
        dest = lhs;
 | 
			
		||||
        dest += delim;
 | 
			
		||||
        dest += Internal::operatorName(Op);
 | 
			
		||||
        dest += delim;
 | 
			
		||||
        dest += rhs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    ResultBuilder& m_rb;
 | 
			
		||||
    LhsT m_lhs;
 | 
			
		||||
    RhsT m_rhs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename ArgT, typename MatcherT>
 | 
			
		||||
class MatchExpression : public DecomposedExpression {
 | 
			
		||||
public:
 | 
			
		||||
    MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString )
 | 
			
		||||
        : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {}
 | 
			
		||||
 | 
			
		||||
    bool isBinaryExpression() const override {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reconstructExpression( std::string& dest ) const override {
 | 
			
		||||
        std::string matcherAsString = m_matcher.toString();
 | 
			
		||||
        dest = ::Catch::Detail::stringify( m_arg );
 | 
			
		||||
        dest += ' ';
 | 
			
		||||
        if( matcherAsString == Detail::unprintableString )
 | 
			
		||||
            dest += m_matcherString;
 | 
			
		||||
        else
 | 
			
		||||
            dest += matcherAsString;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    ArgT m_arg;
 | 
			
		||||
    MatcherT m_matcher;
 | 
			
		||||
    char const* m_matcherString;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // end namespace Catch
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
 | 
			
		||||
@@ -9,9 +9,6 @@
 | 
			
		||||
#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "catch_result_type.h"
 | 
			
		||||
#include "catch_common.h"
 | 
			
		||||
#include "catch_interfaces_reporter.h"
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
@@ -23,6 +20,8 @@ namespace Catch {
 | 
			
		||||
    struct MessageInfo;
 | 
			
		||||
    class ScopedMessageBuilder;
 | 
			
		||||
    struct Counts;
 | 
			
		||||
    struct BenchmarkInfo;
 | 
			
		||||
    struct BenchmarkStats;
 | 
			
		||||
 | 
			
		||||
    struct IResultCapture {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,10 +37,12 @@ namespace Catch {
 | 
			
		||||
        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() );
 | 
			
		||||
            MessageBuilder builder( assertionResult.getTestMacroName().c_str(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
 | 
			
		||||
            builder << assertionResult.getMessage();
 | 
			
		||||
            builder.m_info.message = builder.m_stream.str();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,6 @@
 | 
			
		||||
 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
 | 
			
		||||
#include "catch_matchers.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
@@ -26,5 +24,3 @@ using namespace Matchers;
 | 
			
		||||
using Matchers::Impl::MatcherBase;
 | 
			
		||||
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
@@ -8,8 +8,6 @@
 | 
			
		||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
 | 
			
		||||
#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
 | 
			
		||||
#include "catch_common.h"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
@@ -182,6 +180,4 @@ using Matchers::Impl::MatcherBase;
 | 
			
		||||
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,6 @@
 | 
			
		||||
 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
 | 
			
		||||
#include "catch_matchers_string.h"
 | 
			
		||||
#include "catch_string_manip.h"
 | 
			
		||||
 | 
			
		||||
@@ -94,5 +92,3 @@ namespace Matchers {
 | 
			
		||||
 | 
			
		||||
} // namespace Matchers
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 
 | 
			
		||||
@@ -8,8 +8,6 @@
 | 
			
		||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
 | 
			
		||||
#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
 | 
			
		||||
#include "catch_matchers.hpp"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
@@ -68,6 +66,4 @@ namespace Matchers {
 | 
			
		||||
} // namespace Matchers
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,6 @@
 | 
			
		||||
#ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
 | 
			
		||||
#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "catch_matchers.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
@@ -115,6 +112,4 @@ namespace Matchers {
 | 
			
		||||
} // namespace Matchers
 | 
			
		||||
} // namespace Catch
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,19 @@ namespace Catch {
 | 
			
		||||
        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 );
 | 
			
		||||
@@ -44,7 +56,6 @@ namespace Catch {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        MessageInfo m_info;
 | 
			
		||||
        std::ostringstream m_stream;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class ScopedMessage {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,7 @@
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
    NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
 | 
			
		||||
    :   m_lineInfo( lineInfo ) {
 | 
			
		||||
    NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) {
 | 
			
		||||
        std::ostringstream oss;
 | 
			
		||||
        oss << lineInfo << ": function ";
 | 
			
		||||
        oss << "not implemented";
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,6 @@ namespace Catch {
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        std::string m_what;
 | 
			
		||||
        SourceLineInfo m_lineInfo;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
} // end namespace Catch
 | 
			
		||||
 
 | 
			
		||||
@@ -1,193 +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)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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_matchers_string.h"
 | 
			
		||||
#include "catch_wildcard_pattern.hpp"
 | 
			
		||||
#include "catch_debugger.h"
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
    CopyableStream::CopyableStream( CopyableStream const& other ) {
 | 
			
		||||
        oss << other.oss.str();
 | 
			
		||||
    }
 | 
			
		||||
    CopyableStream& CopyableStream::operator=( CopyableStream const& other ) {
 | 
			
		||||
        oss.str(std::string());
 | 
			
		||||
        oss << other.oss.str();
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ResultBuilder::ResultBuilder(   char const* macroName,
 | 
			
		||||
                                    SourceLineInfo const& lineInfo,
 | 
			
		||||
                                    char const* capturedExpression,
 | 
			
		||||
                                    ResultDisposition::Flags resultDisposition )
 | 
			
		||||
    :   m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition)
 | 
			
		||||
    {
 | 
			
		||||
        getCurrentContext().getResultCapture()->assertionStarting( m_assertionInfo );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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();
 | 
			
		||||
    }
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
    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 = m_assertionInfo.capturedExpression;
 | 
			
		||||
 | 
			
		||||
        std::string actualMessage = Catch::translateActiveException();
 | 
			
		||||
        if( !matcher.match( actualMessage ) ) {
 | 
			
		||||
            data.resultType = ResultWas::ExpressionFailed;
 | 
			
		||||
            data.reconstructedExpression = std::move(actualMessage);
 | 
			
		||||
        }
 | 
			
		||||
        AssertionResult result( m_assertionInfo, data );
 | 
			
		||||
        handleResult( result );
 | 
			
		||||
    }
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
    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 = s_stream().oss.str();
 | 
			
		||||
        data.decomposedExpression = &expr; // for lazy reconstruction
 | 
			
		||||
        return AssertionResult( m_assertionInfo, data );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ResultBuilder::reconstructExpression( std::string& dest ) const {
 | 
			
		||||
        dest = m_assertionInfo.capturedExpression;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ResultBuilder::setExceptionGuard() {
 | 
			
		||||
        m_guardException = true;
 | 
			
		||||
    }
 | 
			
		||||
    void ResultBuilder::unsetExceptionGuard() {
 | 
			
		||||
        m_guardException = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CopyableStream& ResultBuilder::stream() {
 | 
			
		||||
        if( !m_usedStream ) {
 | 
			
		||||
            m_usedStream = true;
 | 
			
		||||
            s_stream().oss.str("");
 | 
			
		||||
        }
 | 
			
		||||
        return s_stream();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CopyableStream& ResultBuilder::s_stream() {
 | 
			
		||||
        static CopyableStream s;
 | 
			
		||||
        return s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace Catch
 | 
			
		||||
@@ -1,118 +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"
 | 
			
		||||
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
 | 
			
		||||
    struct TestFailureException{};
 | 
			
		||||
 | 
			
		||||
    template<typename T> class ExpressionLhs;
 | 
			
		||||
 | 
			
		||||
    struct CopyableStream {
 | 
			
		||||
        CopyableStream() = default;
 | 
			
		||||
        CopyableStream( CopyableStream const& other );
 | 
			
		||||
        CopyableStream& operator=( CopyableStream const& other );
 | 
			
		||||
 | 
			
		||||
        std::ostringstream oss;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class ResultBuilder : public DecomposedExpression {
 | 
			
		||||
    public:
 | 
			
		||||
        ResultBuilder(  char const* macroName,
 | 
			
		||||
                        SourceLineInfo const& lineInfo,
 | 
			
		||||
                        char const* capturedExpression,
 | 
			
		||||
                        ResultDisposition::Flags resultDisposition);
 | 
			
		||||
        ~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 );
 | 
			
		||||
 | 
			
		||||
        void reconstructExpression( std::string& dest ) const override;
 | 
			
		||||
 | 
			
		||||
        AssertionResult build() const;
 | 
			
		||||
        AssertionResult build( DecomposedExpression const& expr ) const;
 | 
			
		||||
 | 
			
		||||
        void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
 | 
			
		||||
        void captureResult( ResultWas::OfType resultType );
 | 
			
		||||
        void captureExpression();
 | 
			
		||||
#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)
 | 
			
		||||
        void captureExpectedException( std::string const& expectedMessage );
 | 
			
		||||
        void captureExpectedException( Matchers::Impl::MatcherBase<std::string> const& matcher );
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
        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();
 | 
			
		||||
        static CopyableStream& s_stream();
 | 
			
		||||
 | 
			
		||||
        bool m_shouldDebugBreak = false;
 | 
			
		||||
        bool m_shouldThrow = false;
 | 
			
		||||
        bool m_guardException = false;
 | 
			
		||||
        bool m_usedStream = false;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
} // 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
 | 
			
		||||
@@ -35,7 +35,9 @@ namespace Catch {
 | 
			
		||||
    :   m_runInfo(_config->name()),
 | 
			
		||||
        m_context(getCurrentMutableContext()),
 | 
			
		||||
        m_config(_config),
 | 
			
		||||
        m_reporter(std::move(reporter)) {
 | 
			
		||||
        m_reporter(std::move(reporter)),
 | 
			
		||||
        m_lastAssertionInfo{ "", SourceLineInfo("",0), "", ResultDisposition::Normal }
 | 
			
		||||
    {
 | 
			
		||||
        m_context.setRunner(this);
 | 
			
		||||
        m_context.setConfig(m_config);
 | 
			
		||||
        m_context.setResultCapture(this);
 | 
			
		||||
@@ -118,7 +120,7 @@ namespace Catch {
 | 
			
		||||
        static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));
 | 
			
		||||
 | 
			
		||||
        // Reset working state
 | 
			
		||||
        m_lastAssertionInfo = AssertionInfo("", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}", m_lastAssertionInfo.resultDisposition);
 | 
			
		||||
        m_lastAssertionInfo = { "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}", m_lastAssertionInfo.resultDisposition };
 | 
			
		||||
        m_lastResult = result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -193,7 +195,7 @@ namespace Catch {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const AssertionResult * RunContext::getLastResult() const {
 | 
			
		||||
        return &m_lastResult;
 | 
			
		||||
        return &(*m_lastResult);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void RunContext::exceptionEarlyReported() {
 | 
			
		||||
@@ -203,7 +205,7 @@ namespace Catch {
 | 
			
		||||
    void RunContext::handleFatalErrorCondition(std::string const & message) {
 | 
			
		||||
        // Don't rebuild the result -- the stringification itself can cause more fatal errors
 | 
			
		||||
        // Instead, fake a result data.
 | 
			
		||||
        AssertionResultData tempResult;
 | 
			
		||||
        AssertionResultData tempResult( ResultWas::Unknown, { false } );
 | 
			
		||||
        tempResult.resultType = ResultWas::FatalErrorCondition;
 | 
			
		||||
        tempResult.message = message;
 | 
			
		||||
        AssertionResult result(m_lastAssertionInfo, tempResult);
 | 
			
		||||
@@ -261,7 +263,7 @@ namespace Catch {
 | 
			
		||||
        double duration = 0;
 | 
			
		||||
        m_shouldReportUnexpected = true;
 | 
			
		||||
        try {
 | 
			
		||||
            m_lastAssertionInfo = AssertionInfo("TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal);
 | 
			
		||||
            m_lastAssertionInfo = { "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal };
 | 
			
		||||
 | 
			
		||||
            seedRng(*m_config);
 | 
			
		||||
 | 
			
		||||
@@ -281,7 +283,11 @@ namespace Catch {
 | 
			
		||||
            // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions
 | 
			
		||||
            // are reported without translation at the point of origin.
 | 
			
		||||
            if (m_shouldReportUnexpected) {
 | 
			
		||||
                makeUnexpectedResultBuilder().useActiveException();
 | 
			
		||||
                AssertionHandler
 | 
			
		||||
                    ( m_lastAssertionInfo.macroName,
 | 
			
		||||
                      m_lastAssertionInfo.lineInfo,
 | 
			
		||||
                      m_lastAssertionInfo.capturedExpression,
 | 
			
		||||
                      m_lastAssertionInfo.resultDisposition ).useActiveException();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        m_testCaseTracker->close();
 | 
			
		||||
@@ -307,13 +313,6 @@ namespace Catch {
 | 
			
		||||
        fatalConditionHandler.reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ResultBuilder RunContext::makeUnexpectedResultBuilder() const {
 | 
			
		||||
        return ResultBuilder(m_lastAssertionInfo.macroName,
 | 
			
		||||
                             m_lastAssertionInfo.lineInfo,
 | 
			
		||||
                             m_lastAssertionInfo.capturedExpression,
 | 
			
		||||
                             m_lastAssertionInfo.resultDisposition);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
#include "catch_test_spec.hpp"
 | 
			
		||||
#include "catch_test_case_tracker.hpp"
 | 
			
		||||
#include "catch_timer.h"
 | 
			
		||||
#include "catch_result_builder.h"
 | 
			
		||||
#include "catch_assertionhandler.h"
 | 
			
		||||
#include "catch_fatal_condition.h"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
@@ -117,15 +117,13 @@ namespace Catch {
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        ResultBuilder makeUnexpectedResultBuilder() const;
 | 
			
		||||
 | 
			
		||||
        void handleUnfinishedSections();
 | 
			
		||||
 | 
			
		||||
        TestRunInfo m_runInfo;
 | 
			
		||||
        IMutableContext& m_context;
 | 
			
		||||
        TestCase const* m_activeTestCase = nullptr;
 | 
			
		||||
        ITracker* m_testCaseTracker;
 | 
			
		||||
        AssertionResult m_lastResult;
 | 
			
		||||
        Option<AssertionResult> m_lastResult;
 | 
			
		||||
 | 
			
		||||
        IConfigPtr m_config;
 | 
			
		||||
        Totals m_totals;
 | 
			
		||||
 
 | 
			
		||||
@@ -18,10 +18,7 @@
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
    void prepareExpandedExpression(AssertionResult& result) {
 | 
			
		||||
        if (result.isOk())
 | 
			
		||||
            result.discardDecomposedExpression();
 | 
			
		||||
        else
 | 
			
		||||
            result.expandDecomposedExpression();
 | 
			
		||||
        result.getExpandedExpression();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Because formatting using c++ streams is stateful, drop down to C is required
 | 
			
		||||
 
 | 
			
		||||
@@ -193,14 +193,14 @@ namespace Catch {
 | 
			
		||||
 | 
			
		||||
        bool assertionEnded(AssertionStats const& assertionStats) override {
 | 
			
		||||
            assert(!m_sectionStack.empty());
 | 
			
		||||
            SectionNode& sectionNode = *m_sectionStack.back();
 | 
			
		||||
            sectionNode.assertions.push_back(assertionStats);
 | 
			
		||||
            // AssertionResult holds a pointer to a temporary DecomposedExpression,
 | 
			
		||||
            // which getExpandedExpression() calls to build the expression string.
 | 
			
		||||
            // Our section stack copy of the assertionResult will likely outlive the
 | 
			
		||||
            // temporary, so it must be expanded or discarded now to avoid calling
 | 
			
		||||
            // a destroyed object later.
 | 
			
		||||
            prepareExpandedExpression(sectionNode.assertions.back().assertionResult);
 | 
			
		||||
            prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );
 | 
			
		||||
            SectionNode& sectionNode = *m_sectionStack.back();
 | 
			
		||||
            sectionNode.assertions.push_back(assertionStats);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        void sectionEnded(SectionStats const& sectionStats) override {
 | 
			
		||||
 
 | 
			
		||||
@@ -499,7 +499,7 @@ ExceptionTests.cpp:<line number>
 | 
			
		||||
ExceptionTests.cpp:<line number>: FAILED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
 | 
			
		||||
with expansion:
 | 
			
		||||
  expected exception
 | 
			
		||||
  "expected exception" equals: "should fail"
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nice descriptive name
 | 
			
		||||
 
 | 
			
		||||
@@ -1428,6 +1428,8 @@ ExceptionTests.cpp:<line number>
 | 
			
		||||
ExceptionTests.cpp:<line number>:
 | 
			
		||||
PASSED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), "expected exception" )
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" equals: "expected exception"
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Exception messages can be tested for
 | 
			
		||||
@@ -1439,6 +1441,8 @@ ExceptionTests.cpp:<line number>
 | 
			
		||||
ExceptionTests.cpp:<line number>:
 | 
			
		||||
PASSED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) )
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" equals: "expected exception" (case insensitive)
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Exception messages can be tested for
 | 
			
		||||
@@ -1450,18 +1454,26 @@ ExceptionTests.cpp:<line number>
 | 
			
		||||
ExceptionTests.cpp:<line number>:
 | 
			
		||||
PASSED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), StartsWith( "expected" ) )
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" starts with: "expected"
 | 
			
		||||
 | 
			
		||||
ExceptionTests.cpp:<line number>:
 | 
			
		||||
PASSED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), EndsWith( "exception" ) )
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" ends with: "exception"
 | 
			
		||||
 | 
			
		||||
ExceptionTests.cpp:<line number>:
 | 
			
		||||
PASSED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), Contains( "except" ) )
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" contains: "except"
 | 
			
		||||
 | 
			
		||||
ExceptionTests.cpp:<line number>:
 | 
			
		||||
PASSED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) )
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" contains: "except" (case insensitive)
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Expected exceptions that don't throw or unexpected exceptions fail the test
 | 
			
		||||
@@ -1986,11 +1998,13 @@ ExceptionTests.cpp:<line number>
 | 
			
		||||
ExceptionTests.cpp:<line number>:
 | 
			
		||||
PASSED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), "expected exception" )
 | 
			
		||||
with expansion:
 | 
			
		||||
  "expected exception" equals: "expected exception"
 | 
			
		||||
 | 
			
		||||
ExceptionTests.cpp:<line number>: FAILED:
 | 
			
		||||
  REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
 | 
			
		||||
with expansion:
 | 
			
		||||
  expected exception
 | 
			
		||||
  "expected exception" equals: "should fail"
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
Nice descriptive name
 | 
			
		||||
 
 | 
			
		||||
@@ -311,7 +311,7 @@ MatchersTests.cpp:<line number>
 | 
			
		||||
      </failure>
 | 
			
		||||
    </testcase>
 | 
			
		||||
    <testcase classname="<exe-name>.global" name="Mismatching exception messages failing the test" time="{duration}">
 | 
			
		||||
      <failure message="expected exception" type="REQUIRE_THROWS_WITH">
 | 
			
		||||
      <failure message=""expected exception" equals: "should fail"" type="REQUIRE_THROWS_WITH">
 | 
			
		||||
ExceptionTests.cpp:<line number>
 | 
			
		||||
      </failure>
 | 
			
		||||
    </testcase>
 | 
			
		||||
 
 | 
			
		||||
@@ -1646,7 +1646,7 @@
 | 
			
		||||
            thisThrows(), "expected exception"
 | 
			
		||||
          </Original>
 | 
			
		||||
          <Expanded>
 | 
			
		||||
            thisThrows(), "expected exception"
 | 
			
		||||
            "expected exception" equals: "expected exception"
 | 
			
		||||
          </Expanded>
 | 
			
		||||
        </Expression>
 | 
			
		||||
        <OverallResults successes="1" failures="0" expectedFailures="0"/>
 | 
			
		||||
@@ -1657,7 +1657,7 @@
 | 
			
		||||
            thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No )
 | 
			
		||||
          </Original>
 | 
			
		||||
          <Expanded>
 | 
			
		||||
            thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No )
 | 
			
		||||
            "expected exception" equals: "expected exception" (case insensitive)
 | 
			
		||||
          </Expanded>
 | 
			
		||||
        </Expression>
 | 
			
		||||
        <OverallResults successes="1" failures="0" expectedFailures="0"/>
 | 
			
		||||
@@ -1668,7 +1668,7 @@
 | 
			
		||||
            thisThrows(), StartsWith( "expected" )
 | 
			
		||||
          </Original>
 | 
			
		||||
          <Expanded>
 | 
			
		||||
            thisThrows(), StartsWith( "expected" )
 | 
			
		||||
            "expected exception" starts with: "expected"
 | 
			
		||||
          </Expanded>
 | 
			
		||||
        </Expression>
 | 
			
		||||
        <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/<exe-name>/ExceptionTests.cpp" >
 | 
			
		||||
@@ -1676,7 +1676,7 @@
 | 
			
		||||
            thisThrows(), EndsWith( "exception" )
 | 
			
		||||
          </Original>
 | 
			
		||||
          <Expanded>
 | 
			
		||||
            thisThrows(), EndsWith( "exception" )
 | 
			
		||||
            "expected exception" ends with: "exception"
 | 
			
		||||
          </Expanded>
 | 
			
		||||
        </Expression>
 | 
			
		||||
        <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/<exe-name>/ExceptionTests.cpp" >
 | 
			
		||||
@@ -1684,7 +1684,7 @@
 | 
			
		||||
            thisThrows(), Contains( "except" )
 | 
			
		||||
          </Original>
 | 
			
		||||
          <Expanded>
 | 
			
		||||
            thisThrows(), Contains( "except" )
 | 
			
		||||
            "expected exception" contains: "except"
 | 
			
		||||
          </Expanded>
 | 
			
		||||
        </Expression>
 | 
			
		||||
        <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/<exe-name>/ExceptionTests.cpp" >
 | 
			
		||||
@@ -1692,7 +1692,7 @@
 | 
			
		||||
            thisThrows(), Contains( "exCept", Catch::CaseSensitive::No )
 | 
			
		||||
          </Original>
 | 
			
		||||
          <Expanded>
 | 
			
		||||
            thisThrows(), Contains( "exCept", Catch::CaseSensitive::No )
 | 
			
		||||
            "expected exception" contains: "except" (case insensitive)
 | 
			
		||||
          </Expanded>
 | 
			
		||||
        </Expression>
 | 
			
		||||
        <OverallResults successes="4" failures="0" expectedFailures="0"/>
 | 
			
		||||
@@ -2172,7 +2172,7 @@
 | 
			
		||||
          thisThrows(), "expected exception"
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          thisThrows(), "expected exception"
 | 
			
		||||
          "expected exception" equals: "expected exception"
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <Expression success="false" type="REQUIRE_THROWS_WITH" filename="projects/<exe-name>/ExceptionTests.cpp" >
 | 
			
		||||
@@ -2180,7 +2180,7 @@
 | 
			
		||||
          thisThrows(), "should fail"
 | 
			
		||||
        </Original>
 | 
			
		||||
        <Expanded>
 | 
			
		||||
          expected exception
 | 
			
		||||
          "expected exception" equals: "should fail"
 | 
			
		||||
        </Expanded>
 | 
			
		||||
      </Expression>
 | 
			
		||||
      <OverallResult success="false"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,9 @@ bool templated_tests(T t) {
 | 
			
		||||
    REQUIRE_THROWS(throws_int(true));
 | 
			
		||||
    CHECK_THROWS_AS(throws_int(true), int);
 | 
			
		||||
    REQUIRE_NOTHROW(throws_int(false));
 | 
			
		||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
    REQUIRE_THAT("aaa", Catch::EndsWith("aaa"));
 | 
			
		||||
#endif
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -181,6 +181,8 @@ TEST_CASE( "Unexpected exceptions can be translated", "[.][failing][!throws]"  )
 | 
			
		||||
        throw double( 3.14 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 | 
			
		||||
TEST_CASE( "Exception messages can be tested for", "[!throws]" ) {
 | 
			
		||||
    using namespace Catch::Matchers;
 | 
			
		||||
    SECTION( "exact match" )
 | 
			
		||||
@@ -195,6 +197,8 @@ TEST_CASE( "Exception messages can be tested for", "[!throws]" ) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
TEST_CASE( "Mismatching exception messages failing the test", "[.][failing][!throws]" ) {
 | 
			
		||||
    REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
 | 
			
		||||
    REQUIRE_THROWS_WITH( thisThrows(), "should fail" );
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,8 @@
 | 
			
		||||
 | 
			
		||||
#include "catch.hpp"
 | 
			
		||||
 | 
			
		||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 | 
			
		||||
inline const char* testStringForMatching()
 | 
			
		||||
{
 | 
			
		||||
    return "this string contains 'abc' as a substring";
 | 
			
		||||
@@ -223,3 +225,5 @@ TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.fail
 | 
			
		||||
        REQUIRE_THROWS_MATCHES(throws(4), SpecialException, ExceptionMatcher{ 1 });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ using namespace Catch;
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
Catch::TestCaseTracking::NameAndLocation makeNAL( std::string const& name ) {
 | 
			
		||||
    return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo() );
 | 
			
		||||
    return Catch::TestCaseTracking::NameAndLocation( name, Catch::SourceLineInfo("",0) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_CASE( "Tracker" ) {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,6 @@
 | 
			
		||||
 | 
			
		||||
TEST_CASE( "Tag alias can be registered against tag patterns" ) {
 | 
			
		||||
 | 
			
		||||
    using namespace Catch::Matchers;
 | 
			
		||||
 | 
			
		||||
    Catch::TagAliasRegistry registry;
 | 
			
		||||
 | 
			
		||||
    registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 2 ) );
 | 
			
		||||
@@ -24,11 +22,14 @@ TEST_CASE( "Tag alias can be registered against tag patterns" ) {
 | 
			
		||||
            FAIL( "expected exception" );
 | 
			
		||||
        }
 | 
			
		||||
        catch( std::exception& ex ) {
 | 
			
		||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
            std::string what = ex.what();
 | 
			
		||||
            using namespace Catch::Matchers;
 | 
			
		||||
            CHECK_THAT( what, Contains( "[@zzz]" ) );
 | 
			
		||||
            CHECK_THAT( what, Contains( "file" ) );
 | 
			
		||||
            CHECK_THAT( what, Contains( "2" ) );
 | 
			
		||||
            CHECK_THAT( what, Contains( "10" ) );
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,9 @@ inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){
 | 
			
		||||
 | 
			
		||||
TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) {
 | 
			
		||||
 | 
			
		||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
    using namespace Catch::Matchers;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    Catch::ConfigData config;
 | 
			
		||||
    auto cli = Catch::makeCommandLineParser(config);
 | 
			
		||||
@@ -153,7 +155,9 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
 | 
			
		||||
            auto result = cli.parse({"test", "-x", "oops"});
 | 
			
		||||
            CHECK(!result);
 | 
			
		||||
 | 
			
		||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
            REQUIRE_THAT(result.errorMessage(), Contains("convert") && Contains("oops"));
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -225,7 +229,9 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
 | 
			
		||||
        SECTION( "error" ) {
 | 
			
		||||
            auto result = cli.parse({"test", "--use-colour", "wrong"});
 | 
			
		||||
            CHECK( !result );
 | 
			
		||||
#ifndef CATCH_CONFIG_DISABLE_MATCHERS
 | 
			
		||||
            CHECK_THAT( result.errorMessage(), Contains( "colour mode must be one of" ) );
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user