mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-26 15:26: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_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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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"
|
||||||
|
@ -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)
|
* 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"
|
||||||
|
@ -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_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>
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user