Added support for move only types to constraints

Therefore mock::retrieve now supports std::unique_ptr.
This commit is contained in:
Mathieu Champlon 2018-03-12 08:26:18 +01:00
parent 5795f4be70
commit bccd3ff303
8 changed files with 60 additions and 19 deletions

View file

@ -16,6 +16,7 @@ Not yet released
* Fixed move-only type argument in actions * Fixed move-only type argument in actions
* Fixed move-only type support in constraints * Fixed move-only type support in constraints
* Added support for dereferencing in mock::equal * Added support for dereferencing in mock::equal
* Added support for movable objects in mock::retrieve
[endsect] [endsect]

View file

@ -183,6 +183,19 @@ namespace detail
return true; return true;
} }
template< typename Actual > template< typename Actual >
bool operator()( BOOST_RV_REF(Actual) actual,
typename boost::disable_if<
boost::is_convertible<
const Actual*,
typename
boost::unwrap_reference< Expected >::type
>
>::type* = 0 ) const
{
*expected_ = boost::move( actual );
return true;
}
template< typename Actual >
bool operator()( Actual& actual, bool operator()( Actual& actual,
typename boost::enable_if< typename boost::enable_if<
boost::is_convertible< Actual*, boost::is_convertible< Actual*,

View file

@ -15,7 +15,7 @@
matcher< T##n, Constraint_##n > c##n##_; matcher< T##n, Constraint_##n > c##n##_;
#define MOCK_EXPECTATION_IS_VALID(z, n, d) \ #define MOCK_EXPECTATION_IS_VALID(z, n, d) \
BOOST_PP_IF(n, &&,) c##n##_( a##n ) BOOST_PP_IF(n, &&,) c##n##_( boost::forward< T##n >( a##n ) )
#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \ #define MOCK_EXPECTATION_SERIALIZE(z, n, d) \
BOOST_PP_IF(n, << ", " <<,) c##n##_ BOOST_PP_IF(n, << ", " <<,) c##n##_
@ -23,8 +23,8 @@
#define MOCK_EXPECTATION_SERIALIZE_ANY(z, n, d) \ #define MOCK_EXPECTATION_SERIALIZE_ANY(z, n, d) \
BOOST_PP_IF(n, << ", " <<,) "any" BOOST_PP_IF(n, << ", " <<,) "any"
#define MOCK_CALL_PARAM_TYPE(z, n, d) \ #define MOCK_EXPECTATION_PARAM(z, n, Args) \
typename boost::call_traits< T##n >::param_type boost::forward< T##n >( a##n )
namespace mock namespace mock
{ {
@ -39,7 +39,7 @@ namespace detail
{ {
private: private:
virtual bool operator()( virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM_TYPE, _) ) BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
{ {
return true; return true;
} }
@ -73,7 +73,7 @@ namespace detail
private: private:
virtual bool operator()( virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) )
{ {
return BOOST_PP_REPEAT(MOCK_NUM_ARGS, return BOOST_PP_REPEAT(MOCK_NUM_ARGS,
MOCK_EXPECTATION_IS_VALID, _); MOCK_EXPECTATION_IS_VALID, _);
@ -103,9 +103,9 @@ namespace detail
private: private:
virtual bool operator()( virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) )
{ {
return f_( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) ); return f_( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) );
} }
virtual void serialize( std::ostream& s ) const virtual void serialize( std::ostream& s ) const
{ {
@ -201,10 +201,10 @@ namespace detail
} }
bool is_valid( bool is_valid(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) const BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const
{ {
return !invocation_->exhausted() return !invocation_->exhausted()
&& (*matcher_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) ); && (*matcher_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) );
} }
bool invoke() const bool invoke() const
@ -259,7 +259,6 @@ namespace detail
} }
} // mock } // mock
#undef MOCK_CALL_PARAM_TYPE
#undef MOCK_EXPECTATION_INITIALIZE #undef MOCK_EXPECTATION_INITIALIZE
#undef MOCK_EXPECTATION_MEMBER #undef MOCK_EXPECTATION_MEMBER
#undef MOCK_EXPECTATION_IS_VALID #undef MOCK_EXPECTATION_IS_VALID

View file

@ -216,7 +216,7 @@ namespace detail
for( expectations_cit it = expectations_.begin(); for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it ) it != expectations_.end(); ++it )
if( it->is_valid( if( it->is_valid(
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) ) ) BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ) )
{ {
if( ! it->invoke() ) if( ! it->invoke() )
{ {

View file

@ -6,9 +6,6 @@
// (See accompanying file LICENSE_1_0.txt or copy at // (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#define MOCK_CALL_PARAM(z, n, d) \
typename boost::call_traits< T##n >::param_type a##n
namespace mock namespace mock
{ {
namespace detail namespace detail
@ -24,7 +21,7 @@ namespace detail
virtual ~matcher_base() {} virtual ~matcher_base() {}
virtual bool operator()( virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_CALL_PARAM, _) ) = 0; BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) = 0;
friend std::ostream& operator<<( friend std::ostream& operator<<(
std::ostream& s, const matcher_base& m ) std::ostream& s, const matcher_base& m )

View file

@ -67,9 +67,9 @@ namespace mock
explicit matcher( const constraint< Constraint >& c ) explicit matcher( const constraint< Constraint >& c )
: c_( c.c_ ) : c_( c.c_ )
{} {}
bool operator()( const Actual& actual ) bool operator()( BOOST_RV_REF(Actual) actual )
{ {
return c_( actual ); return c_( boost::forward< Actual >( actual ) );
} }
friend std::ostream& operator<<( friend std::ostream& operator<<(
std::ostream& s, const matcher& m ) std::ostream& s, const matcher& m )
@ -91,9 +91,9 @@ namespace mock
explicit matcher( const Functor& f ) explicit matcher( const Functor& f )
: c_( f ) : c_( f )
{} {}
bool operator()( const Actual& actual ) bool operator()( BOOST_RV_REF(Actual) actual )
{ {
return c_( actual ); return c_( boost::forward< Actual >( actual ) );
} }
friend std::ostream& operator<<( friend std::ostream& operator<<(
std::ostream& s, const matcher& m ) std::ostream& s, const matcher& m )

View file

@ -252,6 +252,16 @@ BOOST_AUTO_TEST_CASE( retrieve_constraint )
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL( i, &j );
} }
#endif #endif
#ifdef MOCK_SMART_PTR
{
std::unique_ptr< int > i;
std::unique_ptr< int > j( new int( 3 ) );
BOOST_CHECK( mock::retrieve( i ).c_( boost::move( j ) ) );
BOOST_REQUIRE( i );
BOOST_CHECK_EQUAL( 3, *i );
BOOST_CHECK( !j );
}
#endif
} }
namespace namespace

View file

@ -721,4 +721,25 @@ BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_equal_constrain
} }
} }
BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_retrieve_constraint, mock_error_fixture )
{
{
MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) );
MOCK_EXPECT( f ).once().with( nullptr );
f( 0 );
CHECK_CALLS( 1 );
}
{
std::unique_ptr< int > i;
MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) );
MOCK_EXPECT( f ).once().with( mock::retrieve( i ) );
std::unique_ptr< int > j( new int( 7 ) );
f( std::move( j ) );
BOOST_CHECK( !j );
BOOST_REQUIRE( i );
BOOST_CHECK_EQUAL( 7, *i );
CHECK_CALLS( 1 );
}
}
#endif #endif