mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 20:27:11 +01:00 
			
		
		
		
	Removed all (well, most) of the redundant, ResultBuilder-based, code
This commit is contained in:
		| @@ -10,44 +10,15 @@ | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|  | ||||
|     bool DecomposedExpression::isBinaryExpression() const { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     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 AssertionResultData::reconstructExpression() const { | ||||
|  | ||||
|         if( reconstructedExpression.empty() ) { | ||||
|  | ||||
|             // Try new LazyExpression first... | ||||
|             if( lazyExpression ) { | ||||
|                 // !TBD Use stringstream for now, but rework above to pass stream in | ||||
|                 std::ostringstream oss; | ||||
|                 oss << lazyExpression; | ||||
|                 reconstructedExpression = oss.str(); | ||||
|             } | ||||
|  | ||||
|             // ... if not, fall back to decomposedExpression | ||||
|             else 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; | ||||
|     } | ||||
| @@ -115,12 +86,4 @@ namespace Catch { | ||||
|         return m_info.macroName.c_str(); | ||||
|     } | ||||
|  | ||||
|     void AssertionResult::discardDecomposedExpression() const { | ||||
|         m_resultData.decomposedExpression = nullptr; | ||||
|     } | ||||
|  | ||||
|     void AssertionResult::expandDecomposedExpression() const { | ||||
|         m_resultData.reconstructExpression(); | ||||
|     } | ||||
|  | ||||
| } // end namespace Catch | ||||
|   | ||||
| @@ -15,39 +15,12 @@ | ||||
| #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& ); | ||||
|     }; | ||||
| } | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     struct AssertionResultData | ||||
|     { | ||||
|         AssertionResultData() = delete; | ||||
|  | ||||
|         // !TBD We won't need this constructor once the deprecated fields are removed | ||||
|         AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression ) | ||||
|         :   resultType( _resultType ), | ||||
|             lazyExpression( _lazyExpression ) | ||||
| @@ -58,12 +31,7 @@ namespace Catch { | ||||
|  | ||||
|         LazyExpression lazyExpression; | ||||
|  | ||||
|         // deprecated: | ||||
|         bool negated = false; | ||||
|         bool parenthesized = false; | ||||
|         void negate( bool parenthesize ); | ||||
|         std::string reconstructExpression() const; | ||||
|         mutable DecomposedExpression const* decomposedExpression = nullptr; | ||||
|         mutable std::string reconstructedExpression; | ||||
|     }; | ||||
|  | ||||
| @@ -84,8 +52,6 @@ namespace Catch { | ||||
|         std::string getMessage() const; | ||||
|         SourceLineInfo getSourceInfo() const; | ||||
|         std::string getTestMacroName() const; | ||||
|         void discardDecomposedExpression() const; | ||||
|         void expandDecomposedExpression() const; | ||||
|  | ||||
|     //protected: | ||||
|         AssertionInfo m_info; | ||||
|   | ||||
| @@ -9,7 +9,6 @@ | ||||
| #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED | ||||
|  | ||||
| #include "catch_assertionhandler.h" | ||||
| #include "catch_result_builder.h" | ||||
| #include "catch_message.h" | ||||
| #include "catch_interfaces_capture.h" | ||||
| #include "catch_debugger.h" | ||||
|   | ||||
| @@ -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 | ||||
| @@ -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_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(   StringRef macroName, | ||||
|                                     SourceLineInfo const& lineInfo, | ||||
|                                     StringRef capturedExpression, | ||||
|                                     ResultDisposition::Flags resultDisposition ) | ||||
|     :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }, | ||||
|         m_data( ResultWas::Unknown, LazyExpression( false ) ) | ||||
|     { | ||||
|         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.c_str(); | ||||
|  | ||||
|         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.c_str(); | ||||
|     } | ||||
|  | ||||
|     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_assertionresult.h" | ||||
| #include "catch_decomposer.h" | ||||
|  | ||||
| #include "catch_result_type.h" | ||||
| #include "catch_common.h" | ||||
| #include "catch_matchers.hpp" | ||||
|  | ||||
| #include <sstream> | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     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(  StringRef macroName, | ||||
|                         SourceLineInfo const& lineInfo, | ||||
|                         StringRef 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 | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash