mirror of
https://github.com/catchorg/Catch2.git
synced 2025-07-04 16:45:32 +02:00
Lazily stringify expressions (closes #556)
This commit is contained in:
parent
981347b6e4
commit
ebf172be0b
@ -133,7 +133,7 @@
|
|||||||
try { \
|
try { \
|
||||||
std::string matcherAsString = (matcher).toString(); \
|
std::string matcherAsString = (matcher).toString(); \
|
||||||
__catchResult \
|
__catchResult \
|
||||||
.setLhs( Catch::toString( arg ) ) \
|
.setLhs( arg ) \
|
||||||
.setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
|
.setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
|
||||||
.setOp( "matches" ) \
|
.setOp( "matches" ) \
|
||||||
.setResultType( (matcher).match( arg ) ); \
|
.setResultType( (matcher).match( arg ) ); \
|
||||||
|
@ -71,7 +71,7 @@ public:
|
|||||||
void endExpression() {
|
void endExpression() {
|
||||||
bool value = m_lhs ? true : false;
|
bool value = m_lhs ? true : false;
|
||||||
m_rb
|
m_rb
|
||||||
.setLhs( Catch::toString( value ) )
|
.setLhs( value )
|
||||||
.setResultType( value )
|
.setResultType( value )
|
||||||
.endExpression();
|
.endExpression();
|
||||||
}
|
}
|
||||||
@ -90,8 +90,8 @@ private:
|
|||||||
ResultBuilder& captureExpression( RhsT const& rhs ) {
|
ResultBuilder& captureExpression( RhsT const& rhs ) {
|
||||||
return m_rb
|
return m_rb
|
||||||
.setResultType( Internal::compare<Op>( m_lhs, rhs ) )
|
.setResultType( Internal::compare<Op>( m_lhs, rhs ) )
|
||||||
.setLhs( Catch::toString( m_lhs ) )
|
.setLhs( m_lhs )
|
||||||
.setRhs( Catch::toString( rhs ) )
|
.setRhs( rhs )
|
||||||
.setOp( Internal::OperatorTraits<Op>::getName() );
|
.setOp( Internal::OperatorTraits<Op>::getName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "catch_assertionresult.h"
|
#include "catch_assertionresult.h"
|
||||||
#include "catch_common.h"
|
#include "catch_common.h"
|
||||||
#include "catch_matchers.hpp"
|
#include "catch_matchers.hpp"
|
||||||
|
#include "catch_tostring.h"
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
@ -34,6 +35,17 @@ namespace Catch {
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AnyTypeHolderBase {
|
||||||
|
virtual std::string toString() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct AnyTypeHolder : AnyTypeHolderBase {
|
||||||
|
AnyTypeHolder( const T& value ) : value ( value ) {}
|
||||||
|
std::string toString() { return Catch::toString( value ); }
|
||||||
|
T value;
|
||||||
|
};
|
||||||
|
|
||||||
class ResultBuilder {
|
class ResultBuilder {
|
||||||
public:
|
public:
|
||||||
ResultBuilder( char const* macroName,
|
ResultBuilder( char const* macroName,
|
||||||
@ -57,8 +69,10 @@ namespace Catch {
|
|||||||
|
|
||||||
ResultBuilder& setResultType( ResultWas::OfType result );
|
ResultBuilder& setResultType( ResultWas::OfType result );
|
||||||
ResultBuilder& setResultType( bool result );
|
ResultBuilder& setResultType( bool result );
|
||||||
ResultBuilder& setLhs( std::string const& lhs );
|
template <typename T>
|
||||||
ResultBuilder& setRhs( std::string const& rhs );
|
ResultBuilder& setLhs( T const& lhs );
|
||||||
|
template <typename T>
|
||||||
|
ResultBuilder& setRhs( T const& rhs );
|
||||||
ResultBuilder& setOp( std::string const& op );
|
ResultBuilder& setOp( std::string const& op );
|
||||||
|
|
||||||
void endExpression();
|
void endExpression();
|
||||||
@ -80,9 +94,11 @@ namespace Catch {
|
|||||||
AssertionInfo m_assertionInfo;
|
AssertionInfo m_assertionInfo;
|
||||||
AssertionResultData m_data;
|
AssertionResultData m_data;
|
||||||
struct ExprComponents {
|
struct ExprComponents {
|
||||||
ExprComponents() : testFalse( false ) {}
|
ExprComponents() : testFalse( false ), lhs( NULL ), rhs( NULL ) {}
|
||||||
|
~ExprComponents() { delete lhs; delete rhs; }
|
||||||
bool testFalse;
|
bool testFalse;
|
||||||
std::string lhs, rhs, op;
|
std::string op;
|
||||||
|
AnyTypeHolderBase* lhs, *rhs;
|
||||||
} m_exprComponents;
|
} m_exprComponents;
|
||||||
CopyableStream m_stream;
|
CopyableStream m_stream;
|
||||||
|
|
||||||
|
@ -41,12 +41,14 @@ namespace Catch {
|
|||||||
m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
|
m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
|
template <typename T>
|
||||||
m_exprComponents.lhs = lhs;
|
ResultBuilder& ResultBuilder::setLhs( T const& lhs ) {
|
||||||
|
m_exprComponents.lhs = new AnyTypeHolder<T>( lhs );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
|
template <typename T>
|
||||||
m_exprComponents.rhs = rhs;
|
ResultBuilder& ResultBuilder::setRhs( T const& rhs ) {
|
||||||
|
m_exprComponents.rhs = new AnyTypeHolder<T>( rhs );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
|
ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
|
||||||
@ -130,27 +132,31 @@ namespace Catch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.message = m_stream.oss.str();
|
data.message = m_stream.oss.str();
|
||||||
data.reconstructedExpression = reconstructExpression();
|
if( data.resultType == ResultWas::ExpressionFailed ) {
|
||||||
if( m_exprComponents.testFalse ) {
|
data.reconstructedExpression = reconstructExpression();
|
||||||
if( m_exprComponents.op == "" )
|
if( m_exprComponents.testFalse ) {
|
||||||
data.reconstructedExpression = "!" + data.reconstructedExpression;
|
if( m_exprComponents.op == "" )
|
||||||
else
|
data.reconstructedExpression = "!" + data.reconstructedExpression;
|
||||||
data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
|
else
|
||||||
|
data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return AssertionResult( m_assertionInfo, data );
|
return AssertionResult( m_assertionInfo, data );
|
||||||
}
|
}
|
||||||
std::string ResultBuilder::reconstructExpression() const {
|
std::string ResultBuilder::reconstructExpression() const {
|
||||||
|
std::string lhs = m_exprComponents.lhs->toString(),
|
||||||
|
rhs = m_exprComponents.rhs->toString();
|
||||||
if( m_exprComponents.op == "" )
|
if( m_exprComponents.op == "" )
|
||||||
return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
|
return lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + lhs;
|
||||||
else if( m_exprComponents.op == "matches" )
|
else if( m_exprComponents.op == "matches" )
|
||||||
return m_exprComponents.lhs + " " + m_exprComponents.rhs;
|
return lhs + " " + rhs;
|
||||||
else if( m_exprComponents.op != "!" ) {
|
else if( m_exprComponents.op != "!" ) {
|
||||||
if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
|
if( lhs.size() + rhs.size() < 40 &&
|
||||||
m_exprComponents.lhs.find("\n") == std::string::npos &&
|
lhs.find("\n") == std::string::npos &&
|
||||||
m_exprComponents.rhs.find("\n") == std::string::npos )
|
rhs.find("\n") == std::string::npos )
|
||||||
return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
|
return lhs + " " + m_exprComponents.op + " " + rhs;
|
||||||
else
|
else
|
||||||
return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
|
return lhs + "\n" + m_exprComponents.op + "\n" + rhs;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
|
return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user