Added support for dereferencing in mock::equal

This commit is contained in:
Mathieu Champlon 2018-01-17 10:31:53 +01:00
parent a2d36e961a
commit 5d11db0f52
10 changed files with 117 additions and 12 deletions

View file

@ -15,6 +15,7 @@ Not yet released
* Added [@https://github.com/philsquared/Catch Catch] integration
* Fixed move-only type argument in actions
* Fixed move-only type support in constraints
* Added support for dereferencing in mock::equal
[endsect]

View file

@ -22,6 +22,7 @@ namespace
{}
int data_;
};
std::ostream& operator<<( std::ostream& os, const my_class& c ) // my_class is serializable to an std::ostream
{
return os << "my_class( " << c.data_ << " )";
@ -37,7 +38,7 @@ namespace
//[ quick_constraint_solution
#include <boost/lexical_cast.hpp>
namespace mock // it could also be in the namespace of 'my_class'
namespace // in the same namespace as 'my_class'
{
bool operator==( const my_class& actual, const std::string& expected ) // the first part of the trick is to compare to a string
{

View file

@ -384,7 +384,11 @@ Constraints :
calls ['expected] as a functor returning a ['bool], throws std::invalid_argument if ! ['expected]
compares ['actual] to ['expected] using operator ==]]
[[mock::equal( ['expected] )] [['actual] == ['expected]] [compares ['actual] to ['expected] using operator ==]]
[[mock::equal( ['expected] )] [['actual] == ['expected]
['actual] && *['actual] == ['expected]] [compares ['actual] to ['expected] using operator ==
compares ['actual] content to ['expected] using operator ==]]
[[mock::less( ['expected] )] [['actual] < ['expected]] [compares ['actual] to ['expected] using operator <]]
[[mock::greater( ['expected] )] [['actual] > ['expected]] [compares ['actual] to ['expected] using operator >]]
[[mock::less_equal( ['expected] )] [['actual] <= ['expected]] [compares ['actual] to ['expected] using operator <=]]

View file

@ -70,6 +70,12 @@
# endif
#endif
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
# ifndef MOCK_NO_HDR_FUNCTIONAL
# define MOCK_HDR_FUNCTIONAL
# endif
#endif
#if !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX)
# ifndef MOCK_NO_HDR_MUTEX
# define MOCK_HDR_MUTEX

View file

@ -158,8 +158,7 @@ namespace detail
Expected_##n expected##n;
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
typename \
const boost::unwrap_reference< Expected_##n >::type& \
const typename boost::unwrap_reference< Expected_##n >::type& \
BOOST_PP_ARRAY_ELEM(n, Args)
#define MOCK_CONSTRAINT_ARG(z, n, Args) \

View file

@ -17,6 +17,7 @@
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/common_type.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/has_equal_to.hpp>
#include <boost/test/floating_point_comparison.hpp>
namespace mock
@ -26,7 +27,6 @@ namespace mock
MOCK_UNARY_CONSTRAINT( negate, 0,, ! actual )
MOCK_UNARY_CONSTRAINT( evaluate, 0,, actual() )
MOCK_NARY_CONSTRAINT( equal, 1, ( expected ), actual == expected )
MOCK_NARY_CONSTRAINT( less, 1, ( expected ), actual < expected )
MOCK_NARY_CONSTRAINT( greater, 1, ( expected ), actual > expected )
MOCK_NARY_CONSTRAINT( less_equal, 1, ( expected ), actual <= expected )
@ -107,6 +107,43 @@ namespace detail
namespace detail
{
template< typename Expected >
struct equal
{
explicit equal( Expected expected )
: expected_( expected )
{}
template< typename Actual >
bool operator()( const Actual& actual,
typename boost::enable_if<
boost::has_equal_to<
Actual,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{
return actual == boost::unwrap_ref( expected_ );
}
template< typename Actual >
bool operator()( const Actual& actual,
typename boost::disable_if<
boost::has_equal_to<
Actual,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{
return actual && *actual == boost::unwrap_ref( expected_ );
}
friend std::ostream& operator<<( std::ostream& s, const equal& e )
{
return s << "equal( " << mock::format( e.expected_ ) << " )";
}
Expected expected_;
};
template< typename Expected >
struct same
{
@ -187,6 +224,8 @@ namespace detail
>
>::type* = 0 ) const
{
if( ! actual )
return false;
*actual = boost::unwrap_ref( expected_ );
return true;
}
@ -216,6 +255,12 @@ namespace detail
};
}
template< typename T >
constraint< detail::equal< T > > equal( BOOST_FWD_REF(T) t )
{
return detail::equal< T >( boost::forward< T >( t ) );
}
template< typename T >
constraint< detail::same< T > > same( T& t )
{

View file

@ -27,8 +27,13 @@ namespace detail
class action_base
{
private:
#ifdef MOCK_HDR_FUNCTIONAL
typedef std::function< Signature > functor_type;
typedef std::function< Result() > action_type;
#else
typedef boost::function< Signature > functor_type;
typedef boost::function< Result() > action_type;
#endif
public:
const functor_type& functor() const

View file

@ -11,7 +11,7 @@
#include "config.hpp"
#include "log.hpp"
#include "constraint.hpp"
#include "constraints.hpp"
#include "detail/is_functor.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/ref.hpp>
@ -26,9 +26,10 @@ namespace mock
explicit matcher( Expected expected )
: expected_( expected )
{}
bool operator()( Actual actual )
bool operator()( const Actual& actual )
{
return actual == boost::unwrap_ref( expected_ );
return mock::equal(
boost::unwrap_ref( expected_ ) ).c_( actual );
}
friend std::ostream& operator<<(
std::ostream& s, const matcher& m )
@ -66,7 +67,7 @@ namespace mock
explicit matcher( const constraint< Constraint >& c )
: c_( c.c_ )
{}
bool operator()( Actual actual )
bool operator()( const Actual& actual )
{
return c_( actual );
}
@ -90,7 +91,7 @@ namespace mock
explicit matcher( const Functor& f )
: c_( f )
{}
bool operator()( Actual actual )
bool operator()( const Actual& actual )
{
return c_( actual );
}

View file

@ -63,6 +63,27 @@ BOOST_AUTO_TEST_CASE( equal_constraint )
#endif
}
BOOST_AUTO_TEST_CASE( equal_constraint_deref )
{
{
int i = 3;
BOOST_CHECK( mock::equal( 3 ).c_( &i ) );
BOOST_CHECK( ! mock::equal( 7 ).c_( &i ) );
}
{
int* i = 0;
BOOST_CHECK( ! mock::equal( 3 ).c_( i ) );
}
#ifdef MOCK_SMART_PTR
{
std::unique_ptr< int > j( new int( 3 ) );
BOOST_CHECK( mock::equal( 3 ).c_( j ) );
std::unique_ptr< int > i;
BOOST_CHECK( ! mock::equal( 3 ).c_( i ) );
}
#endif // MOCK_SMART_PTR
}
BOOST_AUTO_TEST_CASE( same_constraint )
{
{
@ -110,6 +131,12 @@ BOOST_AUTO_TEST_CASE( assign_constraint )
BOOST_CHECK( mock::assign( &j ).c_( i ) );
BOOST_CHECK_EQUAL( &j, i );
}
{
int* i = 0;
const int j = 1;
BOOST_CHECK( ! mock::assign( j ).c_( i ) );
BOOST_CHECK( ! i );
}
{
int i = 0;
int j = 1;

View file

@ -705,4 +705,20 @@ BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_action, mock_er
CHECK_CALLS( 1 );
}
BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_equal_constraint, mock_error_fixture )
{
{
MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) );
MOCK_EXPECT( f ).once().with( mock::equal( 7 ) );
f( std::unique_ptr< int >( new int( 7 ) ) );
CHECK_CALLS( 1 );
}
{
MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) );
MOCK_EXPECT( f ).once().with( 7 );
f( std::unique_ptr< int >( new int( 7 ) ) );
CHECK_CALLS( 1 );
}
}
#endif