mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Folded ExpressionResultBuilder into ResultBuilder
(even more SRP violations!)
This commit is contained in:
		| @@ -39,7 +39,7 @@ | |||||||
|             __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ |             __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ | ||||||
|         } \ |         } \ | ||||||
|         INTERNAL_CATCH_REACT( __catchResult ) \ |         INTERNAL_CATCH_REACT( __catchResult ) \ | ||||||
|     } while( Catch::alwaysFalse() && (expr) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look |     } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look | ||||||
|  |  | ||||||
| /////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////// | ||||||
| #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ | #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ | ||||||
| @@ -104,7 +104,7 @@ | |||||||
|     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ |     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ | ||||||
|         do { \ |         do { \ | ||||||
|             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ |             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ | ||||||
|             __catchResult.m_resultBuilder << __VA_ARGS__ + ::Catch::StreamEndStop(); \ |             __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ | ||||||
|             __catchResult.captureResult( messageType ); \ |             __catchResult.captureResult( messageType ); \ | ||||||
|             INTERNAL_CATCH_REACT( __catchResult ) \ |             INTERNAL_CATCH_REACT( __catchResult ) \ | ||||||
|         } while( Catch::alwaysFalse() ) |         } while( Catch::alwaysFalse() ) | ||||||
| @@ -112,7 +112,7 @@ | |||||||
|     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ |     #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ | ||||||
|         do { \ |         do { \ | ||||||
|             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ |             Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ | ||||||
|             __catchResult.m_resultBuilder << log + ::Catch::StreamEndStop(); \ |             __catchResult << log + ::Catch::StreamEndStop(); \ | ||||||
|             __catchResult.captureResult( messageType ); \ |             __catchResult.captureResult( messageType ); \ | ||||||
|             INTERNAL_CATCH_REACT( __catchResult ) \ |             INTERNAL_CATCH_REACT( __catchResult ) \ | ||||||
|         } while( Catch::alwaysFalse() ) |         } while( Catch::alwaysFalse() ) | ||||||
| @@ -128,7 +128,7 @@ | |||||||
|         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \ |         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \ | ||||||
|         try { \ |         try { \ | ||||||
|             std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \ |             std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \ | ||||||
|             __catchResult.m_resultBuilder \ |             __catchResult \ | ||||||
|                 .setLhs( Catch::toString( arg ) ) \ |                 .setLhs( Catch::toString( arg ) ) \ | ||||||
|                 .setRhs( matcherAsString == "{?}" ? #matcher : matcherAsString ) \ |                 .setRhs( matcherAsString == "{?}" ? #matcher : matcherAsString ) \ | ||||||
|                 .setOp( "matches" ) \ |                 .setOp( "matches" ) \ | ||||||
|   | |||||||
| @@ -9,20 +9,13 @@ | |||||||
| #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED | ||||||
|  |  | ||||||
| #include "catch_result_builder.h" | #include "catch_result_builder.h" | ||||||
| #include "catch_expressionresult_builder.h" |  | ||||||
| #include "catch_evaluate.hpp" | #include "catch_evaluate.hpp" | ||||||
| #include "catch_tostring.h" | #include "catch_tostring.h" | ||||||
|  |  | ||||||
| #include <assert.h> |  | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|  |  | ||||||
| struct ResultBuilder; |  | ||||||
|  |  | ||||||
| ExpressionResultBuilder& getResultBuilder( ResultBuilder* rb ); |  | ||||||
|  |  | ||||||
| // Wraps the LHS of an expression and captures the operator and RHS (if any) - | // Wraps the LHS of an expression and captures the operator and RHS (if any) - | ||||||
| // wrapping them all in an ExpressionResultBuilder object | // wrapping them all in a ResultBuilder object | ||||||
| template<typename T> | template<typename T> | ||||||
| class ExpressionLhs { | class ExpressionLhs { | ||||||
|     ExpressionLhs& operator = ( ExpressionLhs const& ); |     ExpressionLhs& operator = ( ExpressionLhs const& ); | ||||||
| @@ -31,54 +24,53 @@ class ExpressionLhs { | |||||||
| #  endif | #  endif | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( &rb ), m_lhs( lhs ) {} |     ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {} | ||||||
| #  ifdef CATCH_CPP11_OR_GREATER | #  ifdef CATCH_CPP11_OR_GREATER | ||||||
|     ExpressionLhs( ExpressionLhs const& ) = default; |     ExpressionLhs( ExpressionLhs const& ) = default; | ||||||
|     ExpressionLhs( ExpressionLhs && )     = default; |     ExpressionLhs( ExpressionLhs && )     = default; | ||||||
| #  endif | #  endif | ||||||
|  |  | ||||||
|     template<typename RhsT> |     template<typename RhsT> | ||||||
|     ExpressionResultBuilder& operator == ( RhsT const& rhs ) { |     ResultBuilder& operator == ( RhsT const& rhs ) { | ||||||
|         return captureExpression<Internal::IsEqualTo>( rhs ); |         return captureExpression<Internal::IsEqualTo>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename RhsT> |     template<typename RhsT> | ||||||
|     ExpressionResultBuilder& operator != ( RhsT const& rhs ) { |     ResultBuilder& operator != ( RhsT const& rhs ) { | ||||||
|         return captureExpression<Internal::IsNotEqualTo>( rhs ); |         return captureExpression<Internal::IsNotEqualTo>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename RhsT> |     template<typename RhsT> | ||||||
|     ExpressionResultBuilder& operator < ( RhsT const& rhs ) { |     ResultBuilder& operator < ( RhsT const& rhs ) { | ||||||
|         return captureExpression<Internal::IsLessThan>( rhs ); |         return captureExpression<Internal::IsLessThan>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename RhsT> |     template<typename RhsT> | ||||||
|     ExpressionResultBuilder& operator > ( RhsT const& rhs ) { |     ResultBuilder& operator > ( RhsT const& rhs ) { | ||||||
|         return captureExpression<Internal::IsGreaterThan>( rhs ); |         return captureExpression<Internal::IsGreaterThan>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename RhsT> |     template<typename RhsT> | ||||||
|     ExpressionResultBuilder& operator <= ( RhsT const& rhs ) { |     ResultBuilder& operator <= ( RhsT const& rhs ) { | ||||||
|         return captureExpression<Internal::IsLessThanOrEqualTo>( rhs ); |         return captureExpression<Internal::IsLessThanOrEqualTo>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template<typename RhsT> |     template<typename RhsT> | ||||||
|     ExpressionResultBuilder& operator >= ( RhsT const& rhs ) { |     ResultBuilder& operator >= ( RhsT const& rhs ) { | ||||||
|         return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs ); |         return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ExpressionResultBuilder& operator == ( bool rhs ) { |     ResultBuilder& operator == ( bool rhs ) { | ||||||
|         return captureExpression<Internal::IsEqualTo>( rhs ); |         return captureExpression<Internal::IsEqualTo>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ExpressionResultBuilder& operator != ( bool rhs ) { |     ResultBuilder& operator != ( bool rhs ) { | ||||||
|         return captureExpression<Internal::IsNotEqualTo>( rhs ); |         return captureExpression<Internal::IsNotEqualTo>( rhs ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void endExpression() { |     void endExpression() { | ||||||
|         assert( m_rb ); |  | ||||||
|         bool value = m_lhs ? true : false; |         bool value = m_lhs ? true : false; | ||||||
|         getResultBuilder( m_rb ) |         m_rb | ||||||
|             .setLhs( Catch::toString( value ) ) |             .setLhs( Catch::toString( value ) ) | ||||||
|             .setResultType( value ) |             .setResultType( value ) | ||||||
|             .endExpression(); |             .endExpression(); | ||||||
| @@ -95,9 +87,8 @@ public: | |||||||
|  |  | ||||||
| private: | private: | ||||||
|     template<Internal::Operator Op, typename RhsT> |     template<Internal::Operator Op, typename RhsT> | ||||||
|     ExpressionResultBuilder& captureExpression( RhsT const& rhs ) { |     ResultBuilder& captureExpression( RhsT const& rhs ) { | ||||||
|         assert( m_rb ); |         return m_rb | ||||||
|         return getResultBuilder( m_rb ) |  | ||||||
|             .setResultType( Internal::compare<Op>( m_lhs, rhs ) ) |             .setResultType( Internal::compare<Op>( m_lhs, rhs ) ) | ||||||
|             .setLhs( Catch::toString( m_lhs ) ) |             .setLhs( Catch::toString( m_lhs ) ) | ||||||
|             .setRhs( Catch::toString( rhs ) ) |             .setRhs( Catch::toString( rhs ) ) | ||||||
| @@ -105,7 +96,7 @@ private: | |||||||
|     } |     } | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     ResultBuilder* m_rb; |     ResultBuilder& m_rb; | ||||||
|     T m_lhs; |     T m_lhs; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,65 +0,0 @@ | |||||||
| /* |  | ||||||
|  *  Created by Phil on 8/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_ASSERTIONRESULT_BUILDER_H_INCLUDED |  | ||||||
| #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_BUILDER_H_INCLUDED |  | ||||||
|  |  | ||||||
| #include "catch_tostring.h" |  | ||||||
| #include "catch_assertionresult.h" |  | ||||||
| #include "catch_result_type.h" |  | ||||||
| #include "catch_evaluate.hpp" |  | ||||||
| #include "catch_common.h" |  | ||||||
|  |  | ||||||
| namespace Catch { |  | ||||||
|  |  | ||||||
| struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; |  | ||||||
| struct ResultBuilder; |  | ||||||
|  |  | ||||||
| // Wraps the (stringised versions of) the lhs, operator and rhs of an expression - as well as |  | ||||||
| // the result of evaluating it. This is used to build an AssertionResult object |  | ||||||
| class ExpressionResultBuilder { |  | ||||||
| public: |  | ||||||
|  |  | ||||||
|     ExpressionResultBuilder( ResultBuilder* rb, ResultWas::OfType resultType = ResultWas::Unknown ); |  | ||||||
|     ExpressionResultBuilder( ExpressionResultBuilder const& other ); |  | ||||||
|     ExpressionResultBuilder& operator=( ExpressionResultBuilder const& other ); |  | ||||||
|  |  | ||||||
|     ExpressionResultBuilder& setResultType( ResultWas::OfType result ); |  | ||||||
|     ExpressionResultBuilder& setResultType( bool result ); |  | ||||||
|     ExpressionResultBuilder& setLhs( std::string const& lhs ); |  | ||||||
|     ExpressionResultBuilder& setRhs( std::string const& rhs ); |  | ||||||
|     ExpressionResultBuilder& setOp( std::string const& op ); |  | ||||||
|  |  | ||||||
|     void endExpression(); |  | ||||||
|  |  | ||||||
|     template<typename T> |  | ||||||
|     ExpressionResultBuilder& operator << ( T const& value ) { |  | ||||||
|         m_stream << value; |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     std::string reconstructExpression( AssertionInfo const& info ) const; |  | ||||||
|  |  | ||||||
|     AssertionResult buildResult( AssertionInfo const& info ) const; |  | ||||||
|  |  | ||||||
|     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); |  | ||||||
|     template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); |  | ||||||
|  |  | ||||||
| private: |  | ||||||
|     ResultBuilder* m_rb; |  | ||||||
|     AssertionResultData m_data; |  | ||||||
|     struct ExprComponents { |  | ||||||
|         ExprComponents() : shouldNegate( false ) {} |  | ||||||
|         bool shouldNegate; |  | ||||||
|         std::string lhs, rhs, op; |  | ||||||
|     } m_exprComponents; |  | ||||||
|     std::ostringstream m_stream; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| } // end namespace Catch |  | ||||||
|  |  | ||||||
| #endif // TWOBLUECUBES_CATCH_ASSERTIONRESULT_BUILDER_H_INCLUDED |  | ||||||
| @@ -1,103 +0,0 @@ | |||||||
| /* |  | ||||||
|  *  Created by Phil on 8/8/2012. |  | ||||||
|  *  Copyright 2012 Two Blue Cubes Ltd. All rights reserved. |  | ||||||
|  * |  | ||||||
|  *  Distributed under the Boost Software License, Version 1.0. (See accompanying |  | ||||||
|  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |  | ||||||
|  */ |  | ||||||
| #ifndef TWOBLUECUBES_CATCH_EXPRESSIONRESULT_BUILDER_HPP_INCLUDED |  | ||||||
| #define TWOBLUECUBES_CATCH_EXPRESSIONRESULT_BUILDER_HPP_INCLUDED |  | ||||||
|  |  | ||||||
| #include "catch_expressionresult_builder.h" |  | ||||||
| #include "catch_result_builder.h" |  | ||||||
|  |  | ||||||
| #include <assert.h> |  | ||||||
|  |  | ||||||
| namespace Catch { |  | ||||||
|  |  | ||||||
|     ExpressionResultBuilder::ExpressionResultBuilder( ResultBuilder* rb, ResultWas::OfType resultType ) |  | ||||||
|     : m_rb( rb ) { |  | ||||||
|         m_data.resultType = resultType; |  | ||||||
|     } |  | ||||||
|     ExpressionResultBuilder::ExpressionResultBuilder( ExpressionResultBuilder const& other ) |  | ||||||
|     :   m_rb( other.m_rb ), |  | ||||||
|         m_data( other.m_data ), |  | ||||||
|         m_exprComponents( other.m_exprComponents ) |  | ||||||
|     { |  | ||||||
|         m_stream << other.m_stream.str(); |  | ||||||
|     } |  | ||||||
|     ExpressionResultBuilder& ExpressionResultBuilder::operator=(ExpressionResultBuilder const& other ) { |  | ||||||
|         m_rb = other.m_rb; |  | ||||||
|         m_data = other.m_data; |  | ||||||
|         m_exprComponents = other.m_exprComponents; |  | ||||||
|         m_stream.str(""); |  | ||||||
|         m_stream << other.m_stream.str(); |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
|     ExpressionResultBuilder& ExpressionResultBuilder::setResultType( ResultWas::OfType result ) { |  | ||||||
|         m_data.resultType = result; |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
|     ExpressionResultBuilder& ExpressionResultBuilder::setResultType( bool result ) { |  | ||||||
|         m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
|     void ExpressionResultBuilder::endExpression() { |  | ||||||
|         m_exprComponents.shouldNegate = shouldNegate( m_rb->m_assertionInfo.resultDisposition ); |  | ||||||
|         m_rb->captureExpression(); |  | ||||||
|     } |  | ||||||
|     ExpressionResultBuilder& ExpressionResultBuilder::setLhs( std::string const& lhs ) { |  | ||||||
|         m_exprComponents.lhs = lhs; |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
|     ExpressionResultBuilder& ExpressionResultBuilder::setRhs( std::string const& rhs ) { |  | ||||||
|         m_exprComponents.rhs = rhs; |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
|     ExpressionResultBuilder& ExpressionResultBuilder::setOp( std::string const& op ) { |  | ||||||
|         m_exprComponents.op = op; |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     AssertionResult ExpressionResultBuilder::buildResult( AssertionInfo const& info ) const |  | ||||||
|     { |  | ||||||
|         assert( m_data.resultType != ResultWas::Unknown ); |  | ||||||
|  |  | ||||||
|         AssertionResultData data = m_data; |  | ||||||
|  |  | ||||||
|         // Flip bool results if shouldNegate is set |  | ||||||
|         if( m_exprComponents.shouldNegate && data.resultType == ResultWas::Ok ) |  | ||||||
|             data.resultType = ResultWas::ExpressionFailed; |  | ||||||
|         else if( m_exprComponents.shouldNegate && data.resultType == ResultWas::ExpressionFailed ) |  | ||||||
|             data.resultType = ResultWas::Ok; |  | ||||||
|  |  | ||||||
|         data.message = m_stream.str(); |  | ||||||
|         data.reconstructedExpression = reconstructExpression( info ); |  | ||||||
|         if( m_exprComponents.shouldNegate ) { |  | ||||||
|             if( m_exprComponents.op == "" ) |  | ||||||
|                 data.reconstructedExpression = "!" + data.reconstructedExpression; |  | ||||||
|             else |  | ||||||
|                 data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; |  | ||||||
|         } |  | ||||||
|         return AssertionResult( info, data ); |  | ||||||
|     } |  | ||||||
|     std::string ExpressionResultBuilder::reconstructExpression( AssertionInfo const& info ) const { |  | ||||||
|         if( m_exprComponents.op == "" ) |  | ||||||
|             return m_exprComponents.lhs.empty() ? info.capturedExpression : m_exprComponents.op + m_exprComponents.lhs; |  | ||||||
|         else if( m_exprComponents.op == "matches" ) |  | ||||||
|             return m_exprComponents.lhs + " " + m_exprComponents.rhs; |  | ||||||
|         else if( m_exprComponents.op != "!" ) { |  | ||||||
|             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && |  | ||||||
|                 m_exprComponents.lhs.find("\n") == std::string::npos && |  | ||||||
|                 m_exprComponents.rhs.find("\n") == std::string::npos ) |  | ||||||
|                 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; |  | ||||||
|             else |  | ||||||
|                 return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; |  | ||||||
|         } |  | ||||||
|         else |  | ||||||
|             return "{can't expand - use " + info.macroName + "_FALSE( " + info.capturedExpression.substr(1) + " ) instead of " + info.macroName + "( " + info.capturedExpression + " ) for better diagnostics}"; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } // end namespace Catch |  | ||||||
|  |  | ||||||
| #endif // TWOBLUECUBES_CATCH_EXPRESSIONRESULT_BUILDER_HPP_INCLUDED |  | ||||||
| @@ -23,7 +23,6 @@ | |||||||
| #include "catch_console_colour_impl.hpp" | #include "catch_console_colour_impl.hpp" | ||||||
| #include "catch_generators_impl.hpp" | #include "catch_generators_impl.hpp" | ||||||
| #include "catch_assertionresult.hpp" | #include "catch_assertionresult.hpp" | ||||||
| #include "catch_expressionresult_builder.hpp" |  | ||||||
| #include "catch_test_case_info.hpp" | #include "catch_test_case_info.hpp" | ||||||
| #include "catch_test_spec.hpp" | #include "catch_test_spec.hpp" | ||||||
| #include "catch_version.hpp" | #include "catch_version.hpp" | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ | |||||||
| namespace Catch { | namespace Catch { | ||||||
|  |  | ||||||
|     class TestCase; |     class TestCase; | ||||||
|     class ExpressionResultBuilder; |  | ||||||
|     class AssertionResult; |     class AssertionResult; | ||||||
|     struct AssertionInfo; |     struct AssertionInfo; | ||||||
|     struct SectionInfo; |     struct SectionInfo; | ||||||
|   | |||||||
| @@ -46,10 +46,10 @@ namespace Catch | |||||||
|                     it != itEnd; |                     it != itEnd; | ||||||
|                     ++it ) { |                     ++it ) { | ||||||
|                 if( it->type == ResultWas::Info ) { |                 if( it->type == ResultWas::Info ) { | ||||||
|                     ExpressionResultBuilder expressionBuilder( NULL, it->type ); |                     ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); | ||||||
|                         expressionBuilder << it->message; |                     rb << it->message; | ||||||
|                     AssertionInfo info( it->macroName, it->lineInfo, "", ResultDisposition::Normal ); |                     rb.setResultType( ResultWas::Info ); | ||||||
|                     AssertionResult result = expressionBuilder.buildResult( info ); |                     AssertionResult result = rb.build(); | ||||||
|                     m_legacyReporter->Result( result ); |                     m_legacyReporter->Result( result ); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -8,28 +8,61 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | #ifndef TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | ||||||
|  |  | ||||||
| #include "catch_expression_lhs.hpp" | #include "catch_result_type.h" | ||||||
| #include "catch_expressionresult_builder.h" | #include "catch_assertionresult.h" | ||||||
| #include "catch_common.h" | #include "catch_common.h" | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|  |  | ||||||
|     struct TestFailureException{}; |     struct TestFailureException{}; | ||||||
|  |  | ||||||
|     struct ResultBuilder { |     template<typename T> class ExpressionLhs; | ||||||
|  |  | ||||||
|  |     struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; | ||||||
|  |  | ||||||
|  |     struct CopyableStream { | ||||||
|  |         CopyableStream() {} | ||||||
|  |         CopyableStream( CopyableStream const& other ) { | ||||||
|  |             oss << other.oss.str(); | ||||||
|  |         } | ||||||
|  |         CopyableStream& operator=( CopyableStream const& other ) { | ||||||
|  |             oss.str(""); | ||||||
|  |             oss << other.oss.str(); | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |         std::ostringstream oss; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     class ResultBuilder { | ||||||
|  |     public: | ||||||
|         ResultBuilder(  char const* macroName, |         ResultBuilder(  char const* macroName, | ||||||
|                         SourceLineInfo const& lineInfo, |                         SourceLineInfo const& lineInfo, | ||||||
|                         char const* capturedExpression, |                         char const* capturedExpression, | ||||||
|                         ResultDisposition::Flags resultDisposition ); |                         ResultDisposition::Flags resultDisposition ); | ||||||
|  |  | ||||||
|         template<typename T> |         template<typename T> | ||||||
|         ExpressionLhs<T const&> operator->* ( T const& operand ) { |         ExpressionLhs<T const&> operator->* ( T const& operand ); | ||||||
|             return ExpressionLhs<T const&>( *this, operand ); |         ExpressionLhs<bool> operator->* ( bool value ); | ||||||
|  |  | ||||||
|  |         template<typename T> | ||||||
|  |         ResultBuilder& operator << ( T const& value ) { | ||||||
|  |             m_stream.oss << value; | ||||||
|  |             return *this; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         ExpressionLhs<bool> operator->* ( bool value ) { |         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); | ||||||
|             return ExpressionLhs<bool>( *this, value ); |         template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); | ||||||
|         } |  | ||||||
|  |         ResultBuilder& setResultType( ResultWas::OfType result ); | ||||||
|  |         ResultBuilder& setResultType( bool result ); | ||||||
|  |         ResultBuilder& setLhs( std::string const& lhs ); | ||||||
|  |         ResultBuilder& setRhs( std::string const& rhs ); | ||||||
|  |         ResultBuilder& setOp( std::string const& op ); | ||||||
|  |  | ||||||
|  |         void endExpression(); | ||||||
|  |  | ||||||
|  |         std::string reconstructExpression() const; | ||||||
|  |         AssertionResult build() const; | ||||||
|  |  | ||||||
|         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); |         void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); | ||||||
|         void captureResult( ResultWas::OfType resultType ); |         void captureResult( ResultWas::OfType resultType ); | ||||||
| @@ -38,12 +71,36 @@ namespace Catch { | |||||||
|         bool shouldDebugBreak() const; |         bool shouldDebugBreak() const; | ||||||
|         bool allowThrows() const; |         bool allowThrows() const; | ||||||
|  |  | ||||||
|  |     private: | ||||||
|         AssertionInfo m_assertionInfo; |         AssertionInfo m_assertionInfo; | ||||||
|         ExpressionResultBuilder m_resultBuilder; |         AssertionResultData m_data; | ||||||
|  |         struct ExprComponents { | ||||||
|  |             ExprComponents() : testFalse( false ) {} | ||||||
|  |             bool testFalse; | ||||||
|  |             std::string lhs, rhs, op; | ||||||
|  |         } m_exprComponents; | ||||||
|  |         CopyableStream m_stream; | ||||||
|  |          | ||||||
|         bool m_shouldDebugBreak; |         bool m_shouldDebugBreak; | ||||||
|         bool m_shouldThrow; |         bool m_shouldThrow; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| } // end namespace Catch | } // namespace Catch | ||||||
|  |  | ||||||
|  | // Include after due to circular dependency: | ||||||
|  | #include "catch_expression_lhs.hpp" | ||||||
|  |  | ||||||
|  | namespace Catch { | ||||||
|  |  | ||||||
|  |     template<typename T> | ||||||
|  |     inline 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 ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } // namespace Catch | ||||||
|  |  | ||||||
| #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED | ||||||
|   | |||||||
| @@ -9,9 +9,7 @@ | |||||||
| #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED | ||||||
|  |  | ||||||
| #include "catch_result_builder.h" | #include "catch_result_builder.h" | ||||||
| #include "catch_expressionresult_builder.h" |  | ||||||
| #include "catch_context.h" | #include "catch_context.h" | ||||||
| #include "catch_common.h" |  | ||||||
| #include "catch_interfaces_config.h" | #include "catch_interfaces_config.h" | ||||||
| #include "catch_interfaces_runner.h" | #include "catch_interfaces_runner.h" | ||||||
| #include "catch_interfaces_capture.h" | #include "catch_interfaces_capture.h" | ||||||
| @@ -20,33 +18,58 @@ | |||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|  |  | ||||||
|     ExpressionResultBuilder& getResultBuilder( ResultBuilder* rb ) { |     inline bool isFalseTest( int flags ) { | ||||||
|         return rb->m_resultBuilder; |         return ( flags & ResultDisposition::NegateResult ) != 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ResultBuilder::ResultBuilder(   char const* macroName, |     ResultBuilder::ResultBuilder(   char const* macroName, | ||||||
|                                     SourceLineInfo const& lineInfo, |                                     SourceLineInfo const& lineInfo, | ||||||
|                                     char const* capturedExpression, |                                     char const* capturedExpression, | ||||||
|                                     ResultDisposition::Flags resultDisposition ) |                                     ResultDisposition::Flags resultDisposition ) | ||||||
|         :   m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ), |     :   m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ), | ||||||
|             m_resultBuilder( this ), |         m_shouldDebugBreak( false ), | ||||||
|             m_shouldDebugBreak( false ), |         m_shouldThrow( false ) | ||||||
|             m_shouldThrow( false ) |     {} | ||||||
|         {} |  | ||||||
|  |     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; | ||||||
|  |     } | ||||||
|  |     ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) { | ||||||
|  |         m_exprComponents.lhs = lhs; | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  |     ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) { | ||||||
|  |         m_exprComponents.rhs = rhs; | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  |     ResultBuilder& ResultBuilder::setOp( std::string const& op ) { | ||||||
|  |         m_exprComponents.op = op; | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void ResultBuilder::endExpression() { | ||||||
|  |         m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition ); | ||||||
|  |         captureExpression(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { |     void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { | ||||||
|         m_assertionInfo.resultDisposition = resultDisposition; |         m_assertionInfo.resultDisposition = resultDisposition; | ||||||
|         m_resultBuilder << Catch::translateActiveException(); |         m_stream.oss << Catch::translateActiveException(); | ||||||
|         captureResult( ResultWas::ThrewException ); |         captureResult( ResultWas::ThrewException ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void ResultBuilder::captureResult( ResultWas::OfType resultType ) { |     void ResultBuilder::captureResult( ResultWas::OfType resultType ) { | ||||||
|         m_resultBuilder.setResultType( resultType ); |         setResultType( resultType ); | ||||||
|         captureExpression(); |         captureExpression(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void ResultBuilder::captureExpression() { |     void ResultBuilder::captureExpression() { | ||||||
|         AssertionResult result = m_resultBuilder.buildResult( m_assertionInfo ); |         AssertionResult result = build(); | ||||||
|         getResultCapture().assertionEnded( result ); |         getResultCapture().assertionEnded( result ); | ||||||
|  |  | ||||||
|         if( !result.isOk() ) { |         if( !result.isOk() ) { | ||||||
| @@ -64,6 +87,45 @@ namespace Catch { | |||||||
|     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } |     bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } | ||||||
|     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } |     bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } | ||||||
|  |  | ||||||
|  |     AssertionResult ResultBuilder::build() const | ||||||
|  |     { | ||||||
|  |         assert( m_data.resultType != ResultWas::Unknown ); | ||||||
|  |  | ||||||
|  |         AssertionResultData data = m_data; | ||||||
|  |  | ||||||
|  |         // Flip bool results if testFalse is set | ||||||
|  |         if( m_exprComponents.testFalse && data.resultType == ResultWas::Ok ) | ||||||
|  |             data.resultType = ResultWas::ExpressionFailed; | ||||||
|  |         else if( m_exprComponents.testFalse && data.resultType == ResultWas::ExpressionFailed ) | ||||||
|  |             data.resultType = ResultWas::Ok; | ||||||
|  |  | ||||||
|  |         data.message = m_stream.oss.str(); | ||||||
|  |         data.reconstructedExpression = reconstructExpression(); | ||||||
|  |         if( m_exprComponents.testFalse ) { | ||||||
|  |             if( m_exprComponents.op == "" ) | ||||||
|  |                 data.reconstructedExpression = "!" + data.reconstructedExpression; | ||||||
|  |             else | ||||||
|  |                 data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; | ||||||
|  |         } | ||||||
|  |         return AssertionResult( m_assertionInfo, data ); | ||||||
|  |     } | ||||||
|  |     std::string ResultBuilder::reconstructExpression() const { | ||||||
|  |         if( m_exprComponents.op == "" ) | ||||||
|  |             return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs; | ||||||
|  |         else if( m_exprComponents.op == "matches" ) | ||||||
|  |             return m_exprComponents.lhs + " " + m_exprComponents.rhs; | ||||||
|  |         else if( m_exprComponents.op != "!" ) { | ||||||
|  |             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && | ||||||
|  |                 m_exprComponents.lhs.find("\n") == std::string::npos && | ||||||
|  |                 m_exprComponents.rhs.find("\n") == std::string::npos ) | ||||||
|  |                 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; | ||||||
|  |             else | ||||||
|  |                 return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |             return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}"; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } // end namespace Catch | } // end namespace Catch | ||||||
|  |  | ||||||
| #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED | #endif // TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED | ||||||
|   | |||||||
| @@ -158,8 +158,6 @@ | |||||||
| 		4A7DB2CD1652FE4B00FA6523 /* catch_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = catch_version.h; path = ../../../../include/internal/catch_version.h; sourceTree = "<group>"; }; | 		4A7DB2CD1652FE4B00FA6523 /* catch_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = catch_version.h; path = ../../../../include/internal/catch_version.h; sourceTree = "<group>"; }; | ||||||
| 		4A90B59B15D0F61A00EF71BC /* catch_interfaces_generators.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_generators.h; sourceTree = "<group>"; }; | 		4A90B59B15D0F61A00EF71BC /* catch_interfaces_generators.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_generators.h; sourceTree = "<group>"; }; | ||||||
| 		4A90B59D15D24FE900EF71BC /* catch_assertionresult.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_assertionresult.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; | 		4A90B59D15D24FE900EF71BC /* catch_assertionresult.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_assertionresult.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; | ||||||
| 		4A90B59E15D2521E00EF71BC /* catch_expressionresult_builder.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_expressionresult_builder.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; |  | ||||||
| 		4A9D84B315599AC900FBB209 /* catch_expressionresult_builder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = catch_expressionresult_builder.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; |  | ||||||
| 		4AA7B8B4165428BA003155F6 /* catch_version.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = catch_version.hpp; path = ../../../../include/internal/catch_version.hpp; sourceTree = "<group>"; }; | 		4AA7B8B4165428BA003155F6 /* catch_version.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = catch_version.hpp; path = ../../../../include/internal/catch_version.hpp; sourceTree = "<group>"; }; | ||||||
| 		4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_console_colour_impl.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; | 		4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_console_colour_impl.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; | ||||||
| 		4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_console_colour.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; | 		4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_console_colour.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; | ||||||
| @@ -340,7 +338,6 @@ | |||||||
| 				4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */, | 				4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */, | ||||||
| 				4A4B0F9B15CEF8C400AE2392 /* catch_notimplemented_exception.hpp */, | 				4A4B0F9B15CEF8C400AE2392 /* catch_notimplemented_exception.hpp */, | ||||||
| 				4A90B59D15D24FE900EF71BC /* catch_assertionresult.hpp */, | 				4A90B59D15D24FE900EF71BC /* catch_assertionresult.hpp */, | ||||||
| 				4A90B59E15D2521E00EF71BC /* catch_expressionresult_builder.hpp */, |  | ||||||
| 				4A084F1C15DACEEA0027E631 /* catch_test_case_info.hpp */, | 				4A084F1C15DACEEA0027E631 /* catch_test_case_info.hpp */, | ||||||
| 				26847E5C16BBACB60043B9C1 /* catch_message.hpp */, | 				26847E5C16BBACB60043B9C1 /* catch_message.hpp */, | ||||||
| 				2627F7061935B55F009BCE2D /* catch_result_builder.hpp */, | 				2627F7061935B55F009BCE2D /* catch_result_builder.hpp */, | ||||||
| @@ -357,7 +354,6 @@ | |||||||
| 				4A6D0C4F149B3E3D00DB3EAA /* catch_generators.hpp */, | 				4A6D0C4F149B3E3D00DB3EAA /* catch_generators.hpp */, | ||||||
| 				4A6D0C5C149B3E3D00DB3EAA /* catch_result_type.h */, | 				4A6D0C5C149B3E3D00DB3EAA /* catch_result_type.h */, | ||||||
| 				4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */, | 				4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */, | ||||||
| 				4A9D84B315599AC900FBB209 /* catch_expressionresult_builder.h */, |  | ||||||
| 				261488FE184DC32F0041FBEB /* catch_section.h */, | 				261488FE184DC32F0041FBEB /* catch_section.h */, | ||||||
| 				4A3D7DD01503869D005F9203 /* catch_matchers.hpp */, | 				4A3D7DD01503869D005F9203 /* catch_matchers.hpp */, | ||||||
| 				4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */, | 				4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash