First cut of Matcher support

This commit is contained in:
Phil Nash 2012-03-04 11:14:21 +00:00
parent 5ff4ab0a76
commit eca5637c58
5 changed files with 100 additions and 6 deletions

View File

@ -60,6 +60,9 @@
#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, false, "CHECK_THROWS_AS" )
#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, false, "CHECK_NOTHROW" )
#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, false, "CHECK_THAT" )
#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, true, "REQUIRE_THAT" )
#define INFO( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Info, false, "INFO" )
#define WARN( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::Warning, false, "WARN" )
#define FAIL( msg ) INTERNAL_CATCH_MSG( msg, Catch::ResultWas::ExplicitFailure, true, "FAIL" )

View File

@ -266,6 +266,33 @@ public:
m_line = line;
}
///////////////////////////////////////////////////////////////////////////
void setLhs
(
const std::string& lhs
)
{
m_lhs = lhs;
}
///////////////////////////////////////////////////////////////////////////
void setRhs
(
const std::string& rhs
)
{
m_rhs = rhs;
}
///////////////////////////////////////////////////////////////////////////
void setOp
(
const std::string& op
)
{
m_op = op;
}
///////////////////////////////////////////////////////////////////////////
template<typename RhsT>
STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator ||
@ -514,6 +541,7 @@ private:
const LhsT* m_lhs;
};
class ResultBuilder
{
public:
@ -599,6 +627,25 @@ public:
return *this;
}
///////////////////////////////////////////////////////////////////////////
template<typename MatcherT, typename ArgT>
ResultBuilder& acceptMatcher
(
const MatcherT& matcher,
const ArgT& arg,
const std::string& matcherCallAsString
)
{
std::string matcherAsString = Catch::toString( matcher );
if( matcherAsString == "{?}" )
matcherAsString = matcherCallAsString;
m_result.setLhs( Catch::toString( arg ) );
m_result.setRhs( matcherAsString );
m_result.setOp( "matches" );
m_result.setResultType( matcher( arg ) ? ResultWas::Ok : ResultWas::ExpressionFailed );
return *this;
}
///////////////////////////////////////////////////////////////////////////
ResultBuilder& setResultType
(
@ -749,4 +796,15 @@ inline bool isTrue
Catch::ScopedInfo INTERNAL_CATCH_UNIQUE_NAME( info ); \
INTERNAL_CATCH_UNIQUE_NAME( info ) << log
///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CHECK_THAT( arg, matcher, stopOnFailure, macroName ) \
do{ try{ \
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #arg " " #matcher, false ).acceptMatcher( matcher, arg, #matcher ) ), stopOnFailure ); \
}catch( Catch::TestFailureException& ){ \
throw; \
} catch( ... ){ \
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #arg " " #matcher ) << Catch::Hub::getExceptionTranslatorRegistry().translateActiveException() ).setResultType( Catch::ResultWas::ThrewException ), false ); \
throw; \
}}while( Catch::isTrue( false ) )
#endif // TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED

View File

@ -157,6 +157,8 @@ namespace Catch
{
if( m_op == "" || m_isNot )
return m_lhs.empty() ? m_expr : m_op + m_lhs;
else if( m_op == "matches" )
return m_lhs + " " + m_rhs;
else if( m_op != "!" )
return m_lhs + " " + m_op + " " + m_rhs;
else

View File

@ -185,3 +185,34 @@ TEST_CASE("./succeeding/atomic if", "")
else
REQUIRE(x == 0);
}
namespace Matchers
{
struct ContainsStdString
{
ContainsStdString( const std::string& substr ) : m_substr( substr ){}
bool operator()( const std::string& str ) const
{
return str.find( m_substr ) != std::string::npos;
}
friend std::ostream& operator<<( std::ostream& os, const ContainsStdString& matcher )
{
os << "contains: \"" << matcher.m_substr << "\"";
return os;
}
std::string m_substr;
};
}
inline Matchers::ContainsStdString Contains( const std::string& substr ){ return Matchers::ContainsStdString( substr ); }
TEST_CASE("./succeeding/matcher", "")
{
const char* actualStr = "this string contains 'abc' as a substring";
REQUIRE_THAT( actualStr, Contains( "string" ) );
CHECK_THAT( actualStr, Contains( "not there" ) );
CHECK_THAT( actualStr, Contains( "a2bc" ) );
}