mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 21:36:11 +01:00
Removed all (well, most) of the redundant, ResultBuilder-based, code
This commit is contained in:
parent
7df290dfc1
commit
8c95a81448
@ -138,9 +138,7 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_default_main.hpp
|
||||
${HEADER_DIR}/internal/catch_enforce.h
|
||||
${HEADER_DIR}/internal/catch_errno_guard.h
|
||||
${HEADER_DIR}/internal/catch_evaluate.hpp
|
||||
${HEADER_DIR}/internal/catch_exception_translator_registry.h
|
||||
${HEADER_DIR}/internal/catch_expression_lhs.hpp
|
||||
${HEADER_DIR}/internal/catch_fatal_condition.h
|
||||
${HEADER_DIR}/internal/catch_impl.hpp
|
||||
${HEADER_DIR}/internal/catch_interfaces_capture.h
|
||||
@ -165,7 +163,6 @@ set(INTERNAL_HEADERS
|
||||
${HEADER_DIR}/internal/catch_reenable_warnings.h
|
||||
${HEADER_DIR}/internal/catch_reporter_registrars.hpp
|
||||
${HEADER_DIR}/internal/catch_reporter_registry.hpp
|
||||
${HEADER_DIR}/internal/catch_result_builder.h
|
||||
${HEADER_DIR}/internal/catch_result_type.h
|
||||
${HEADER_DIR}/internal/catch_run_context.hpp
|
||||
${HEADER_DIR}/internal/catch_benchmark.h
|
||||
@ -212,7 +209,6 @@ set(IMPL_SOURCES
|
||||
${HEADER_DIR}/internal/catch_debugger.cpp
|
||||
${HEADER_DIR}/internal/catch_decomposer.cpp
|
||||
${HEADER_DIR}/internal/catch_errno_guard.cpp
|
||||
${HEADER_DIR}/internal/catch_evaluate.cpp
|
||||
${HEADER_DIR}/internal/catch_exception_translator_registry.cpp
|
||||
${HEADER_DIR}/internal/catch_fatal_condition.cpp
|
||||
${HEADER_DIR}/internal/catch_list.cpp
|
||||
@ -223,7 +219,6 @@ set(IMPL_SOURCES
|
||||
${HEADER_DIR}/internal/catch_notimplemented_exception.cpp
|
||||
${HEADER_DIR}/internal/catch_registry_hub.cpp
|
||||
${HEADER_DIR}/internal/catch_interfaces_reporter.cpp
|
||||
${HEADER_DIR}/internal/catch_result_builder.cpp
|
||||
${HEADER_DIR}/internal/catch_result_type.cpp
|
||||
${HEADER_DIR}/internal/catch_run_context.cpp
|
||||
${HEADER_DIR}/internal/catch_section.cpp
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user