mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Merge pull request #35 from mat007/support-move-only-types-as-arguments
Support move only types as arguments
This commit is contained in:
commit
176b9bdc01
16 changed files with 250 additions and 62 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
|
.vscode
|
||||||
bin
|
bin
|
||||||
out
|
out
|
||||||
build/xsl
|
build/xsl
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ Not yet released
|
||||||
* Fixed mocking of a function returning a reference for gcc 4.1
|
* Fixed mocking of a function returning a reference for gcc 4.1
|
||||||
* Added MOCK_NO_AUTO_PTR to deactivate std::auto_ptr support
|
* Added MOCK_NO_AUTO_PTR to deactivate std::auto_ptr support
|
||||||
* Added [@https://github.com/philsquared/Catch Catch] integration
|
* 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
|
||||||
|
* Added support for movable objects in mock::retrieve
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ namespace
|
||||||
{}
|
{}
|
||||||
int data_;
|
int data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<( std::ostream& os, const my_class& c ) // my_class is serializable to an std::ostream
|
std::ostream& operator<<( std::ostream& os, const my_class& c ) // my_class is serializable to an std::ostream
|
||||||
{
|
{
|
||||||
return os << "my_class( " << c.data_ << " )";
|
return os << "my_class( " << c.data_ << " )";
|
||||||
|
|
@ -37,7 +38,7 @@ namespace
|
||||||
//[ quick_constraint_solution
|
//[ quick_constraint_solution
|
||||||
#include <boost/lexical_cast.hpp>
|
#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
|
bool operator==( const my_class& actual, const std::string& expected ) // the first part of the trick is to compare to a string
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -384,7 +384,11 @@ Constraints :
|
||||||
calls ['expected] as a functor returning a ['bool], throws std::invalid_argument if ! ['expected]
|
calls ['expected] as a functor returning a ['bool], throws std::invalid_argument if ! ['expected]
|
||||||
|
|
||||||
compares ['actual] to ['expected] using operator ==]]
|
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::less( ['expected] )] [['actual] < ['expected]] [compares ['actual] to ['expected] using operator <]]
|
||||||
[[mock::greater( ['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 <=]]
|
[[mock::less_equal( ['expected] )] [['actual] <= ['expected]] [compares ['actual] to ['expected] using operator <=]]
|
||||||
|
|
@ -406,9 +410,9 @@ Constraints :
|
||||||
|
|
||||||
retrieves ['actual] address into ['expected] using operator =]]
|
retrieves ['actual] address into ['expected] using operator =]]
|
||||||
[[mock::contain( ['expected] )] [['actual].find( ['expected] ) != std::string::npos] [checks whether ['expected] is contained in the std::string ['actual]]]
|
[[mock::contain( ['expected] )] [['actual].find( ['expected] ) != std::string::npos] [checks whether ['expected] is contained in the std::string ['actual]]]
|
||||||
[[mock::affirm] [['actual]] [uses ['actual] as a boolean]]
|
[[mock::affirm] [['actual]] [uses ['actual] as a ['bool]]]
|
||||||
[[mock::negate] [! ['actual]] [negates ['actual] using operator !]]
|
[[mock::negate] [! ['actual]] [negates ['actual] using operator !]]
|
||||||
[[mock::evaluate] [['actual]()] [evaluates ['actual] as a functor returning a bool and taking no argument]]
|
[[mock::evaluate] [['actual]()] [evaluates ['actual] as a functor returning a ['bool] and taking no argument]]
|
||||||
]
|
]
|
||||||
|
|
||||||
[important When passing ['expected] directly as a shortcut mock::call is implied for a function, a function pointer, an instance of a type with a result_type member typedef (support for standard library, [@http://www.boost.org/libs/bind/bind.html Boost.Bind], [@http://www.boost.org/libs/function Boost.Function] functors), an instance of a type with a sig member (support for [@http://www.boost.org/libs/lambda Boost.Lambda] functors), an instance of a type with a result member (support for [@http://www.boost.org/libs/phoenix Boost.Phoenix] functors); mock::equal is implied for anything else.]
|
[important When passing ['expected] directly as a shortcut mock::call is implied for a function, a function pointer, an instance of a type with a result_type member typedef (support for standard library, [@http://www.boost.org/libs/bind/bind.html Boost.Bind], [@http://www.boost.org/libs/function Boost.Function] functors), an instance of a type with a sig member (support for [@http://www.boost.org/libs/lambda Boost.Lambda] functors), an instance of a type with a result member (support for [@http://www.boost.org/libs/phoenix Boost.Phoenix] functors); mock::equal is implied for anything else.]
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,12 @@
|
||||||
# endif
|
# endif
|
||||||
#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)
|
#if !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX)
|
||||||
# ifndef MOCK_NO_HDR_MUTEX
|
# ifndef MOCK_NO_HDR_MUTEX
|
||||||
# define MOCK_HDR_MUTEX
|
# define MOCK_HDR_MUTEX
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||||
#include <boost/preprocessor/repetition/enum.hpp>
|
#include <boost/preprocessor/repetition/enum.hpp>
|
||||||
#include <boost/preprocessor/array.hpp>
|
#include <boost/preprocessor/array.hpp>
|
||||||
|
#include <boost/move/move.hpp>
|
||||||
|
|
||||||
namespace mock
|
namespace mock
|
||||||
{
|
{
|
||||||
|
|
@ -157,12 +158,14 @@ namespace detail
|
||||||
Expected_##n expected##n;
|
Expected_##n expected##n;
|
||||||
|
|
||||||
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
|
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
|
||||||
typename \
|
const typename boost::unwrap_reference< Expected_##n >::type& \
|
||||||
boost::unwrap_reference< Expected_##n >::type \
|
|
||||||
BOOST_PP_ARRAY_ELEM(n, Args)
|
BOOST_PP_ARRAY_ELEM(n, Args)
|
||||||
|
|
||||||
|
#define MOCK_CONSTRAINT_ARG(z, n, Args) \
|
||||||
|
BOOST_FWD_REF(T##n) BOOST_PP_ARRAY_ELEM(n, Args)
|
||||||
|
|
||||||
#define MOCK_CONSTRAINT_PARAM(z, n, Args) \
|
#define MOCK_CONSTRAINT_PARAM(z, n, Args) \
|
||||||
T##n BOOST_PP_ARRAY_ELEM(n, Args)
|
boost::forward< T##n >( BOOST_PP_ARRAY_ELEM(n, Args) )
|
||||||
|
|
||||||
#define MOCK_NARY_CONSTRAINT(Name, n, Args, Expr) \
|
#define MOCK_NARY_CONSTRAINT(Name, n, Args, Expr) \
|
||||||
namespace detail \
|
namespace detail \
|
||||||
|
|
@ -171,7 +174,7 @@ namespace detail
|
||||||
struct Name \
|
struct Name \
|
||||||
{ \
|
{ \
|
||||||
explicit Name( \
|
explicit Name( \
|
||||||
BOOST_PP_ENUM_BINARY_PARAMS(n, const Expected_, & e) ) \
|
BOOST_PP_ENUM_BINARY_PARAMS(n, Expected_, e) ) \
|
||||||
: BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, _) \
|
: BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, _) \
|
||||||
{} \
|
{} \
|
||||||
template< typename Actual > \
|
template< typename Actual > \
|
||||||
|
|
@ -199,9 +202,10 @@ namespace detail
|
||||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
template< BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
||||||
mock::constraint< \
|
mock::constraint< \
|
||||||
detail::Name< BOOST_PP_ENUM_PARAMS(n, T) > \
|
detail::Name< BOOST_PP_ENUM_PARAMS(n, T) > \
|
||||||
> Name( BOOST_PP_ENUM(n, MOCK_CONSTRAINT_PARAM, (n, Args)) ) \
|
> Name( BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARG, (n, Args)) ) \
|
||||||
{ \
|
{ \
|
||||||
return detail::Name< BOOST_PP_ENUM_PARAMS(n, T) > Args; \
|
return detail::Name< BOOST_PP_ENUM_PARAMS(n, T) >( \
|
||||||
|
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_PARAM, (n, Args)) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOCK_CONSTRAINT_EXT(Name, n, Args, Expr) \
|
#define MOCK_CONSTRAINT_EXT(Name, n, Args, Expr) \
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include <boost/utility/enable_if.hpp>
|
#include <boost/utility/enable_if.hpp>
|
||||||
#include <boost/type_traits/common_type.hpp>
|
#include <boost/type_traits/common_type.hpp>
|
||||||
#include <boost/type_traits/is_convertible.hpp>
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
#include <boost/type_traits/has_equal_to.hpp>
|
||||||
#include <boost/test/floating_point_comparison.hpp>
|
#include <boost/test/floating_point_comparison.hpp>
|
||||||
|
|
||||||
namespace mock
|
namespace mock
|
||||||
|
|
@ -26,7 +27,6 @@ namespace mock
|
||||||
MOCK_UNARY_CONSTRAINT( negate, 0,, ! actual )
|
MOCK_UNARY_CONSTRAINT( negate, 0,, ! actual )
|
||||||
MOCK_UNARY_CONSTRAINT( evaluate, 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( less, 1, ( expected ), actual < expected )
|
||||||
MOCK_NARY_CONSTRAINT( greater, 1, ( expected ), actual > expected )
|
MOCK_NARY_CONSTRAINT( greater, 1, ( expected ), actual > expected )
|
||||||
MOCK_NARY_CONSTRAINT( less_equal, 1, ( expected ), actual <= expected )
|
MOCK_NARY_CONSTRAINT( less_equal, 1, ( expected ), actual <= expected )
|
||||||
|
|
@ -107,6 +107,43 @@ namespace detail
|
||||||
|
|
||||||
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 >
|
template< typename Expected >
|
||||||
struct same
|
struct same
|
||||||
{
|
{
|
||||||
|
|
@ -146,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*,
|
||||||
|
|
@ -187,6 +237,8 @@ namespace detail
|
||||||
>
|
>
|
||||||
>::type* = 0 ) const
|
>::type* = 0 ) const
|
||||||
{
|
{
|
||||||
|
if( ! actual )
|
||||||
|
return false;
|
||||||
*actual = boost::unwrap_ref( expected_ );
|
*actual = boost::unwrap_ref( expected_ );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -216,6 +268,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 >
|
template< typename T >
|
||||||
constraint< detail::same< T > > same( T& t )
|
constraint< detail::same< T > > same( T& t )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,13 @@ namespace detail
|
||||||
class action_base
|
class action_base
|
||||||
{
|
{
|
||||||
private:
|
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< Signature > functor_type;
|
||||||
typedef boost::function< Result() > action_type;
|
typedef boost::function< Result() > action_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const functor_type& functor() const
|
const functor_type& functor() const
|
||||||
|
|
@ -100,11 +105,11 @@ namespace detail
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename Value >
|
template< typename Value >
|
||||||
void moves( BOOST_RV_REF( Value ) v )
|
void moves( BOOST_RV_REF(Value) v )
|
||||||
{
|
{
|
||||||
this->set(
|
this->set(
|
||||||
boost::bind(
|
boost::bind(
|
||||||
&boost::move< BOOST_RV_REF( Value ) >,
|
&boost::move< BOOST_RV_REF(Value) >,
|
||||||
boost::ref( store( boost::move( v ) ) ) ) );
|
boost::ref( store( boost::move( v ) ) ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +129,7 @@ namespace detail
|
||||||
>::type
|
>::type
|
||||||
>::type value_type;
|
>::type value_type;
|
||||||
|
|
||||||
value_imp( BOOST_RV_REF( value_type ) t )
|
value_imp( BOOST_RV_REF(value_type) t )
|
||||||
: t_( boost::move( t ) )
|
: t_( boost::move( t ) )
|
||||||
{}
|
{}
|
||||||
value_imp( const T& t )
|
value_imp( const T& t )
|
||||||
|
|
@ -138,7 +143,7 @@ namespace detail
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
T& store( BOOST_RV_REF( T ) t )
|
T& store( BOOST_RV_REF(T) t )
|
||||||
{
|
{
|
||||||
v_.reset( new value_imp< T >( boost::move( t ) ) );
|
v_.reset( new value_imp< T >( boost::move( t ) ) );
|
||||||
return static_cast< value_imp< T >& >( *v_ ).t_;
|
return static_cast< value_imp< T >& >( *v_ ).t_;
|
||||||
|
|
|
||||||
|
|
@ -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,6 +23,9 @@
|
||||||
#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_EXPECTATION_PARAM(z, n, Args) \
|
||||||
|
boost::forward< T##n >( a##n )
|
||||||
|
|
||||||
namespace mock
|
namespace mock
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
|
|
@ -91,7 +94,7 @@ namespace detail
|
||||||
template< typename F,
|
template< typename F,
|
||||||
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
|
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
|
||||||
class multi_matcher< F, void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
|
class multi_matcher< F, void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
|
||||||
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T) ) >
|
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
multi_matcher( const F& f )
|
multi_matcher( const F& f )
|
||||||
|
|
@ -100,9 +103,9 @@ namespace detail
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool operator()(
|
virtual bool operator()(
|
||||||
BOOST_PP_ENUM_BINARY_PARAMS( MOCK_NUM_ARGS, T, a ) )
|
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,7 +204,7 @@ namespace detail
|
||||||
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) 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
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include <boost/call_traits.hpp>
|
#include <boost/call_traits.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/move/move.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,7 @@ namespace detail
|
||||||
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) );
|
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MOCK_NUM_ARGS > 1
|
#if MOCK_NUM_ARGS > 1
|
||||||
template< typename Constraint >
|
template< typename Constraint >
|
||||||
wrapper with( const Constraint& c )
|
wrapper with( const Constraint& c )
|
||||||
|
|
@ -215,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() )
|
||||||
{
|
{
|
||||||
|
|
@ -234,7 +235,7 @@ namespace detail
|
||||||
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
|
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
|
||||||
if( it->functor() )
|
if( it->functor() )
|
||||||
return it->functor()(
|
return it->functor()(
|
||||||
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) );
|
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) );
|
||||||
return it->trigger();
|
return it->trigger();
|
||||||
}
|
}
|
||||||
error_type::fail( "unexpected call", MOCK_FUNCTION_CONTEXT );
|
error_type::fail( "unexpected call", MOCK_FUNCTION_CONTEXT );
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,8 @@
|
||||||
|
|
||||||
#include "function_impl_template.hpp"
|
#include "function_impl_template.hpp"
|
||||||
|
|
||||||
#define MOCK_FUNCTION_CALL(z, n, d ) \
|
#define MOCK_FORWARD(z, n, d) \
|
||||||
BOOST_PP_COMMA_IF(n) typename \
|
boost::forward< T##n >( t##n )
|
||||||
boost::call_traits< T##n >::param_type
|
|
||||||
|
|
||||||
#define MOCK_FUNCTION_PARAM(z, n, d) \
|
|
||||||
MOCK_FUNCTION_CALL(z, n, d) t##n
|
|
||||||
|
|
||||||
namespace mock
|
namespace mock
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +32,7 @@ namespace detail
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef function_impl<
|
typedef function_impl<
|
||||||
R ( BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FUNCTION_CALL, _) )
|
R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
||||||
> impl_type;
|
> impl_type;
|
||||||
typedef typename impl_type::wrapper_type expectation_type;
|
typedef typename impl_type::wrapper_type expectation_type;
|
||||||
typedef typename impl_type::error_type error_type;
|
typedef typename impl_type::error_type error_type;
|
||||||
|
|
@ -76,9 +72,9 @@ namespace detail
|
||||||
}
|
}
|
||||||
|
|
||||||
R operator()(
|
R operator()(
|
||||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FUNCTION_PARAM, _) ) const
|
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
|
||||||
{
|
{
|
||||||
return (*impl_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) );
|
return (*impl_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) );
|
||||||
}
|
}
|
||||||
|
|
||||||
friend std::ostream& operator<<( std::ostream& s, const function& f )
|
friend std::ostream& operator<<( std::ostream& s, const function& f )
|
||||||
|
|
@ -106,6 +102,3 @@ namespace detail
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} // mock
|
} // mock
|
||||||
|
|
||||||
#undef MOCK_FUNCTION_CALL
|
|
||||||
#undef MOCK_FUNCTION_PARAM
|
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,15 @@ namespace detail
|
||||||
template< typename Signature > class matcher_base;
|
template< typename Signature > class matcher_base;
|
||||||
|
|
||||||
template<
|
template<
|
||||||
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Actual_) >
|
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
|
||||||
class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Actual_) ) >
|
class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
|
||||||
: boost::noncopyable
|
: boost::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~matcher_base() {}
|
virtual ~matcher_base() {}
|
||||||
|
|
||||||
virtual bool operator()(
|
virtual bool operator()(
|
||||||
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Actual_, actual_) ) = 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 )
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "constraint.hpp"
|
#include "constraints.hpp"
|
||||||
#include "detail/is_functor.hpp"
|
#include "detail/is_functor.hpp"
|
||||||
#include <boost/utility/enable_if.hpp>
|
#include <boost/utility/enable_if.hpp>
|
||||||
#include <boost/ref.hpp>
|
#include <boost/ref.hpp>
|
||||||
|
|
@ -26,9 +26,10 @@ namespace mock
|
||||||
explicit matcher( Expected expected )
|
explicit matcher( Expected expected )
|
||||||
: 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<<(
|
friend std::ostream& operator<<(
|
||||||
std::ostream& s, const matcher& m )
|
std::ostream& s, const matcher& m )
|
||||||
|
|
@ -66,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()( 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 )
|
||||||
|
|
@ -90,9 +91,9 @@ namespace mock
|
||||||
explicit matcher( const Functor& f )
|
explicit matcher( const Functor& f )
|
||||||
: c_( f )
|
: c_( f )
|
||||||
{}
|
{}
|
||||||
bool operator()( 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 )
|
||||||
|
|
|
||||||
|
|
@ -47,14 +47,41 @@ BOOST_AUTO_TEST_CASE( equal_constraint )
|
||||||
BOOST_CHECK( ! mock::equal( std::string( "string" ) ).c_( "not string" ) );
|
BOOST_CHECK( ! mock::equal( std::string( "string" ) ).c_( "not string" ) );
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
mock::constraint<
|
auto c = mock::equal( boost::cref( s ) );
|
||||||
mock::detail::equal<
|
|
||||||
boost::reference_wrapper< const std::string >
|
|
||||||
>
|
|
||||||
> c = mock::equal( boost::cref( s ) );
|
|
||||||
s = "string";
|
s = "string";
|
||||||
BOOST_CHECK( c.c_( "string" ) );
|
BOOST_CHECK( c.c_( "string" ) );
|
||||||
}
|
}
|
||||||
|
#ifdef MOCK_SMART_PTR
|
||||||
|
{
|
||||||
|
std::unique_ptr< int > i;
|
||||||
|
std::unique_ptr< int > j( new int( 3 ) );
|
||||||
|
BOOST_CHECK( ! mock::equal( i ).c_( j ) );
|
||||||
|
BOOST_CHECK( ! mock::equal( j ).c_( i ) );
|
||||||
|
BOOST_CHECK( mock::equal( i ).c_( i ) );
|
||||||
|
BOOST_CHECK( mock::equal( j ).c_( j ) );
|
||||||
|
}
|
||||||
|
#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 )
|
BOOST_AUTO_TEST_CASE( same_constraint )
|
||||||
|
|
@ -104,6 +131,12 @@ BOOST_AUTO_TEST_CASE( assign_constraint )
|
||||||
BOOST_CHECK( mock::assign( &j ).c_( i ) );
|
BOOST_CHECK( mock::assign( &j ).c_( i ) );
|
||||||
BOOST_CHECK_EQUAL( &j, 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 i = 0;
|
||||||
int j = 1;
|
int j = 1;
|
||||||
|
|
@ -219,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
|
||||||
|
|
@ -244,10 +287,20 @@ BOOST_AUTO_TEST_CASE( retrieve_constraint_uses_assignment_operator )
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( affirm_constraint )
|
BOOST_AUTO_TEST_CASE( affirm_constraint )
|
||||||
{
|
{
|
||||||
|
{
|
||||||
int* i = 0;
|
int* i = 0;
|
||||||
int j;
|
int j;
|
||||||
BOOST_CHECK( ! mock::affirm.c_( i ) );
|
BOOST_CHECK( ! mock::affirm.c_( i ) );
|
||||||
BOOST_CHECK( mock::affirm.c_( &j ) );
|
BOOST_CHECK( mock::affirm.c_( &j ) );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
#ifdef MOCK_SMART_PTR
|
||||||
|
std::unique_ptr< int > i;
|
||||||
|
std::unique_ptr< int > j( new int( 3 ) );
|
||||||
|
BOOST_CHECK( ! mock::affirm.c_( i ) );
|
||||||
|
BOOST_CHECK( mock::affirm.c_( j ) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( negate_constraint )
|
BOOST_AUTO_TEST_CASE( negate_constraint )
|
||||||
|
|
|
||||||
|
|
@ -704,3 +704,56 @@ BOOST_FIXTURE_TEST_CASE( mock_method_accepts_polymorphic_multi_constraint, mock_
|
||||||
m.m2( 1, 2 );
|
m.m2( 1, 2 );
|
||||||
CHECK_CALLS( 1 );
|
CHECK_CALLS( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOCK_SMART_PTR
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_action, mock_error_fixture )
|
||||||
|
{
|
||||||
|
MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) );
|
||||||
|
std::unique_ptr< int > p;
|
||||||
|
MOCK_EXPECT( f ).once().calls(
|
||||||
|
[]( std::unique_ptr< int > )
|
||||||
|
{
|
||||||
|
} );
|
||||||
|
f( std::unique_ptr< int >( new int( 7 ) ) );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue