Removed all (well, most) of the redundant, ResultBuilder-based, code

This commit is contained in:
Phil Nash 2017-08-09 09:08:33 +01:00
parent 7df290dfc1
commit 8c95a81448
12 changed files with 3 additions and 717 deletions

View File

@ -138,9 +138,7 @@ set(INTERNAL_HEADERS
${HEADER_DIR}/internal/catch_default_main.hpp ${HEADER_DIR}/internal/catch_default_main.hpp
${HEADER_DIR}/internal/catch_enforce.h ${HEADER_DIR}/internal/catch_enforce.h
${HEADER_DIR}/internal/catch_errno_guard.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_exception_translator_registry.h
${HEADER_DIR}/internal/catch_expression_lhs.hpp
${HEADER_DIR}/internal/catch_fatal_condition.h ${HEADER_DIR}/internal/catch_fatal_condition.h
${HEADER_DIR}/internal/catch_impl.hpp ${HEADER_DIR}/internal/catch_impl.hpp
${HEADER_DIR}/internal/catch_interfaces_capture.h ${HEADER_DIR}/internal/catch_interfaces_capture.h
@ -165,7 +163,6 @@ set(INTERNAL_HEADERS
${HEADER_DIR}/internal/catch_reenable_warnings.h ${HEADER_DIR}/internal/catch_reenable_warnings.h
${HEADER_DIR}/internal/catch_reporter_registrars.hpp ${HEADER_DIR}/internal/catch_reporter_registrars.hpp
${HEADER_DIR}/internal/catch_reporter_registry.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_result_type.h
${HEADER_DIR}/internal/catch_run_context.hpp ${HEADER_DIR}/internal/catch_run_context.hpp
${HEADER_DIR}/internal/catch_benchmark.h ${HEADER_DIR}/internal/catch_benchmark.h
@ -212,7 +209,6 @@ set(IMPL_SOURCES
${HEADER_DIR}/internal/catch_debugger.cpp ${HEADER_DIR}/internal/catch_debugger.cpp
${HEADER_DIR}/internal/catch_decomposer.cpp ${HEADER_DIR}/internal/catch_decomposer.cpp
${HEADER_DIR}/internal/catch_errno_guard.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_exception_translator_registry.cpp
${HEADER_DIR}/internal/catch_fatal_condition.cpp ${HEADER_DIR}/internal/catch_fatal_condition.cpp
${HEADER_DIR}/internal/catch_list.cpp ${HEADER_DIR}/internal/catch_list.cpp
@ -223,7 +219,6 @@ set(IMPL_SOURCES
${HEADER_DIR}/internal/catch_notimplemented_exception.cpp ${HEADER_DIR}/internal/catch_notimplemented_exception.cpp
${HEADER_DIR}/internal/catch_registry_hub.cpp ${HEADER_DIR}/internal/catch_registry_hub.cpp
${HEADER_DIR}/internal/catch_interfaces_reporter.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_result_type.cpp
${HEADER_DIR}/internal/catch_run_context.cpp ${HEADER_DIR}/internal/catch_run_context.cpp
${HEADER_DIR}/internal/catch_section.cpp ${HEADER_DIR}/internal/catch_section.cpp

View File

@ -10,44 +10,15 @@
namespace Catch { 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 { std::string AssertionResultData::reconstructExpression() const {
if( reconstructedExpression.empty() ) { if( reconstructedExpression.empty() ) {
// Try new LazyExpression first...
if( lazyExpression ) { if( lazyExpression ) {
// !TBD Use stringstream for now, but rework above to pass stream in // !TBD Use stringstream for now, but rework above to pass stream in
std::ostringstream oss; std::ostringstream oss;
oss << lazyExpression; oss << lazyExpression;
reconstructedExpression = oss.str(); 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; return reconstructedExpression;
} }
@ -115,12 +86,4 @@ namespace Catch {
return m_info.macroName.c_str(); return m_info.macroName.c_str();
} }
void AssertionResult::discardDecomposedExpression() const {
m_resultData.decomposedExpression = nullptr;
}
void AssertionResult::expandDecomposedExpression() const {
m_resultData.reconstructExpression();
}
} // end namespace Catch } // end namespace Catch

View File

@ -15,39 +15,12 @@
#include "catch_stringref.h" #include "catch_stringref.h"
#include "catch_assertionhandler.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 { namespace Catch {
struct AssertionResultData struct AssertionResultData
{ {
AssertionResultData() = delete; AssertionResultData() = delete;
// !TBD We won't need this constructor once the deprecated fields are removed
AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression ) AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression )
: resultType( _resultType ), : resultType( _resultType ),
lazyExpression( _lazyExpression ) lazyExpression( _lazyExpression )
@ -58,12 +31,7 @@ namespace Catch {
LazyExpression lazyExpression; LazyExpression lazyExpression;
// deprecated:
bool negated = false;
bool parenthesized = false;
void negate( bool parenthesize );
std::string reconstructExpression() const; std::string reconstructExpression() const;
mutable DecomposedExpression const* decomposedExpression = nullptr;
mutable std::string reconstructedExpression; mutable std::string reconstructedExpression;
}; };
@ -84,8 +52,6 @@ namespace Catch {
std::string getMessage() const; std::string getMessage() const;
SourceLineInfo getSourceInfo() const; SourceLineInfo getSourceInfo() const;
std::string getTestMacroName() const; std::string getTestMacroName() const;
void discardDecomposedExpression() const;
void expandDecomposedExpression() const;
//protected: //protected:
AssertionInfo m_info; AssertionInfo m_info;

View File

@ -9,7 +9,6 @@
#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
#include "catch_assertionhandler.h" #include "catch_assertionhandler.h"
#include "catch_result_builder.h"
#include "catch_message.h" #include "catch_message.h"
#include "catch_interfaces_capture.h" #include "catch_interfaces_capture.h"
#include "catch_debugger.h" #include "catch_debugger.h"

View File

@ -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

View File

@ -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

View File

@ -6,8 +6,8 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * 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_exception_translator_registry.h"
#include "catch_result_builder.h"
#ifdef __OBJC__ #ifdef __OBJC__
#import "Foundation/Foundation.h" #import "Foundation/Foundation.h"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -19,7 +19,7 @@
#include "catch_test_spec.hpp" #include "catch_test_spec.hpp"
#include "catch_test_case_tracker.hpp" #include "catch_test_case_tracker.hpp"
#include "catch_timer.h" #include "catch_timer.h"
#include "catch_result_builder.h" #include "catch_assertionhandler.h"
#include "catch_fatal_condition.h" #include "catch_fatal_condition.h"
#include <string> #include <string>

View File

@ -18,10 +18,7 @@
namespace Catch { namespace Catch {
void prepareExpandedExpression(AssertionResult& result) { void prepareExpandedExpression(AssertionResult& result) {
if (result.isOk()) result.getExpandedExpression();
result.discardDecomposedExpression();
else
result.expandDecomposedExpression();
} }
// Because formatting using c++ streams is stateful, drop down to C is required // Because formatting using c++ streams is stateful, drop down to C is required