mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Generalized to MOCK_CONSTRAINT
git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@660 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
parent
8a6edd531e
commit
400aaddf9a
7 changed files with 108 additions and 123 deletions
|
|
@ -5,7 +5,7 @@ Not yet released
|
|||
|
||||
* Added support for C++11 lambdas as constraints
|
||||
* Return actions now accept by copy types derived from abstract base types
|
||||
* Officially documented MOCK_UNARY_CONSTRAINT and MOCK_BINARY_CONSTRAINT
|
||||
* Added MOCK_CONSTRAINT helper macro
|
||||
* Added support for several sequences in 'in'
|
||||
* Added support for nullptr as constraint
|
||||
* Added mock::close, mock::close_fraction, mock::small and mock::near constraints
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ Simple enough, however this constraint isn't serializable and thus yields a rath
|
|||
|
||||
Just like a parameter, a constraint can be displayed in a readable form using its serialization operator, see [link turtle.customization.logging logging].
|
||||
|
||||
Thus a widely used constraint (for instance one shipped with the code of a library) is likely better to be defined like this :
|
||||
Thus a widely used constraint (for instance one shipped with the code of a library) is likely better defined like this :
|
||||
|
||||
[custom_constraint_functor]
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ See [link turtle.reference.expectation.constraints constraints] for an explanati
|
|||
|
||||
For more information about the serialization operator and the use of mock::format, refer to [link turtle.customization.logging loggin].
|
||||
|
||||
[note The [link turtle.reference.helpers.mock_unary_constraint MOCK_UNARY_CONSTRAINT] and [link turtle.reference.helpers.mock_binary_constraint MOCK_BINARY_CONSTRAINT] macros replace the need to write the constraints explicitly for the most trivial cases.]
|
||||
[note The [link turtle.reference.helpers.mock_constraint MOCK_CONSTRAINT] macro takes care of everything for simple cases.]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
|
|
|||
|
|
@ -759,22 +759,42 @@ BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_static_mock_method )
|
|||
namespace helpers_example_1
|
||||
{
|
||||
//[ helpers_example_1
|
||||
MOCK_UNARY_CONSTRAINT( any, true ) // this is (almost) how mock::any is defined
|
||||
MOCK_UNARY_CONSTRAINT( forty_two, actual == 42 ) // this defines a 'forty_two' constraint
|
||||
MOCK_CONSTRAINT( 0, any, true ) // this is (almost) how mock::any is defined
|
||||
MOCK_CONSTRAINT( 0, forty_two, actual == 42 ) // this defines a 'forty_two' constraint
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_0_arity )
|
||||
{
|
||||
MOCK_FUNCTOR( f, void( int ) );
|
||||
MOCK_EXPECT( f ).with( forty_two );
|
||||
MOCK_EXPECT( f ).with( any );
|
||||
}
|
||||
//]
|
||||
}
|
||||
|
||||
namespace helpers_example_2
|
||||
{
|
||||
//[ helpers_example_2
|
||||
MOCK_BINARY_CONSTRAINT( equal, actual == expected ) // this is how mock::equal is defined
|
||||
MOCK_BINARY_CONSTRAINT( near, std::abs( actual - expected ) < 0.01 ) // this defines a 'near' constraint which can be used as 'near( 42 )'
|
||||
MOCK_CONSTRAINT( 1, equal, actual == expected_0 ) // this is how mock::equal is defined
|
||||
MOCK_CONSTRAINT( 1, near, std::abs( actual - expected_0 ) < 0.01 ) // this defines a 'near' constraint which can be used as 'near( 42 )'
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_1_arity )
|
||||
{
|
||||
MOCK_FUNCTOR( f, void( int ) );
|
||||
MOCK_EXPECT( f ).with( near( 42 ) );
|
||||
MOCK_EXPECT( f ).with( equal( 42 ) );
|
||||
}
|
||||
//]
|
||||
}
|
||||
|
||||
namespace helpers_example_3
|
||||
{
|
||||
//[ helpers_example_3
|
||||
MOCK_TERNARY_CONSTRAINT( near, std::abs( actual - expected ) < arg ) // this defines a 'near' constraint which can be used as 'near( 42, 0.01 )'
|
||||
MOCK_CONSTRAINT( 2, near, std::abs( actual - expected_0 ) < expected_1 ) // this is how mock::near is defined
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
|
||||
{
|
||||
MOCK_FUNCTOR( f, void( int ) );
|
||||
MOCK_EXPECT( f ).with( near( 42, 0.001 ) );
|
||||
}
|
||||
//]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,10 +323,10 @@ Constraints :
|
|||
[[mock::greater( ['expected] )] [['actual] > ['expected]] [compares ['actual] to ['expected] using operator >]]
|
||||
[[mock::less_equal( ['expected] )] [['actual] <= ['expected]] [compares ['actual] to ['expected] using operator <=]]
|
||||
[[mock::greater_equal( ['expected] )] [['actual] >= ['expected]] [compares ['actual] to ['expected] using operator >=]]
|
||||
[[mock::near] [std::abs( ['actual] - ['expected] ) < ['arg]] [checks whether ['actual] is near ['expected]]]
|
||||
[[mock::close] [boost::test_tools::check_is_close( ['actual], ['expected], boost::test_tools::percent_tolerance( ['arg] ) )] [checks whether ['actual] is close to ['expected], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
|
||||
[[mock::close_fraction] [boost::test_tools::check_is_close( ['actual], ['expected], boost::test_tools::fraction_tolerance( ['arg] ) )] [checks whether ['actual] is close to ['expected], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
|
||||
[[mock::small] [boost::test_tools::check_is_small( ['actual], ['expected] ) )] [checks whether ['actual] is small with a tolerance of ['expected], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
|
||||
[[mock::near( ['expected], ['tolerance] )] [std::abs( ['actual] - ['expected] ) < ['tolerance]] [checks whether ['actual] is near ['expected] within ['tolerance]]]
|
||||
[[mock::close( ['expected], ['tolerance] )] [boost::test_tools::check_is_close( ['actual], ['expected], boost::test_tools::percent_tolerance( ['arg] ) )] [checks whether ['actual] is close to ['expected], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
|
||||
[[mock::close_fraction( ['expected], ['tolerance] )] [boost::test_tools::check_is_close( ['actual], ['expected], boost::test_tools::fraction_tolerance( ['arg] ) )] [checks whether ['actual] is close to ['expected], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
|
||||
[[mock::small( ['tolerance] )] [boost::test_tools::check_is_small( ['actual], ['expected] ) )] [checks whether ['actual] is small within ['tolerance], see [@http://www.boost.org/libs/test/doc/html/utf/testing-tools/floating_point_comparison.html Floating-point comparison algorithms] ]]
|
||||
[[mock::call( ['expected] )] [['expected]( ['actual] )] [calls ['expected] as a functor returning a ['bool] and accepting ['actual] as parameter]]
|
||||
[[mock::same( ['expected] )] [&['actual] == &['expected]] [compares ['actual] to ['expected] by comparing their pointers]]
|
||||
[[mock::assign( ['expected] )] [['actual] = ['expected], true
|
||||
|
|
@ -490,49 +490,27 @@ Example :
|
|||
|
||||
[section Helpers]
|
||||
|
||||
This section presents macros used to help with defining custom constraints.
|
||||
This section presents various useful tools.
|
||||
|
||||
[section MOCK_UNARY_CONSTRAINT]
|
||||
[section MOCK_CONSTRAINT]
|
||||
|
||||
Synopsis :
|
||||
|
||||
MOCK_UNARY_CONSTRAINT( name, expression ) // defines a constraint 'name' based on the given 'expression'
|
||||
MOCK_CONSTRAINT( arity, name, expression ) // defines a constraint 'name' based on the given 'expression'
|
||||
|
||||
The expression manipulates the received parameter 'actual' in order to implement the constraint.
|
||||
The expression manipulates the received parameter ['actual] in order to implement the constraint, as well as ['arity] extra expected arguments ['expected_0], ['expected_1], etc...
|
||||
|
||||
Example :
|
||||
[note The type of all expected arguments must be copy-constructible and assignable.]
|
||||
|
||||
Example without any extra argument :
|
||||
|
||||
[helpers_example_1]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section MOCK_BINARY_CONSTRAINT]
|
||||
|
||||
Synopsis :
|
||||
|
||||
MOCK_BINARY_CONSTRAINT( name, expression ) // defines a constraint 'name' based on the given 'expression'
|
||||
|
||||
The expression manipulates the received parameter 'actual' as well as the passed argument 'expected' in order to implement the constraint.
|
||||
|
||||
[note The type of expected must be copy-constructible and assignable.]
|
||||
|
||||
Example :
|
||||
Example with one extra argument :
|
||||
|
||||
[helpers_example_2]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section MOCK_TERNARY_CONSTRAINT]
|
||||
|
||||
Synopsis :
|
||||
|
||||
MOCK_TERNARY_CONSTRAINT( name, expression ) // defines a constraint 'name' based on the given 'expression'
|
||||
|
||||
The expression manipulates the received parameter 'actual' as well as the passed arguments 'expected' and 'arg' in order to implement the constraint.
|
||||
|
||||
[note The types of expected and arg must be copy-constructible and assignable.]
|
||||
|
||||
Example :
|
||||
Example with two extra arguments :
|
||||
|
||||
[helpers_example_3]
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@
|
|||
#include "config.hpp"
|
||||
#include "log.hpp"
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
|
|
@ -119,94 +124,79 @@ namespace detail
|
|||
}
|
||||
} // mock
|
||||
|
||||
#define MOCK_UNARY_CONSTRAINT(N, Expr) \
|
||||
#define MOCK_UNARY_CONSTRAINT(n, Name, Expr) \
|
||||
namespace detail \
|
||||
{ \
|
||||
struct N \
|
||||
struct Name \
|
||||
{ \
|
||||
template< typename Actual > \
|
||||
bool operator()( const Actual& actual ) const \
|
||||
{ \
|
||||
return Expr; \
|
||||
} \
|
||||
friend std::ostream& operator<<( std::ostream& s, const N& ) \
|
||||
friend std::ostream& operator<<( std::ostream& s, const Name& ) \
|
||||
{ \
|
||||
return s << BOOST_STRINGIZE(N); \
|
||||
return s << BOOST_STRINGIZE(Name); \
|
||||
} \
|
||||
}; \
|
||||
} \
|
||||
const mock::constraint< detail::N > N;
|
||||
const mock::constraint< detail::Name > Name;
|
||||
|
||||
#define MOCK_BINARY_CONSTRAINT(N, Expr) \
|
||||
#define MOCK_CONSTRAINT_ASSIGN(z, n, d) \
|
||||
expected##n( e##n )
|
||||
|
||||
#define MOCK_CONSTRAINT_UNWRAP_REF(z, n, d) \
|
||||
boost::unwrap_ref( expected##n )
|
||||
|
||||
#define MOCK_CONSTRAINT_FORMAT(z, n, d) \
|
||||
BOOST_PP_IF(n, << ", " <<,) mock::format( c.expected##n )
|
||||
|
||||
#define MOCK_CONSTRAINT_MEMBER(z, n, d) \
|
||||
Expected_##n expected##n;
|
||||
|
||||
#define MOCK_NARY_CONSTRAINT(n, Name, Expr) \
|
||||
namespace detail \
|
||||
{ \
|
||||
template< typename Expected > \
|
||||
struct N \
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename Expected_) > \
|
||||
struct Name \
|
||||
{ \
|
||||
explicit N( const Expected& expected ) \
|
||||
: expected_( expected ) \
|
||||
explicit Name( \
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(n, const Expected_, & e ) ) \
|
||||
: BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, _) \
|
||||
{} \
|
||||
template< typename Actual > \
|
||||
bool operator()( const Actual& actual ) const \
|
||||
{ \
|
||||
return test( actual, boost::unwrap_ref( expected_ ) ); \
|
||||
return test( actual, \
|
||||
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_UNWRAP_REF, _ ) ); \
|
||||
} \
|
||||
template< typename Actual, typename T > \
|
||||
bool test( const Actual& actual, const T& expected ) const \
|
||||
{ \
|
||||
return Expr; \
|
||||
} \
|
||||
friend std::ostream& operator<<( std::ostream& s, const N& n ) \
|
||||
{ \
|
||||
return s << BOOST_STRINGIZE(N) \
|
||||
<< "( " << mock::format( n.expected_ ) << " )"; \
|
||||
} \
|
||||
Expected expected_; \
|
||||
}; \
|
||||
} \
|
||||
template< typename Expected > \
|
||||
mock::constraint< detail::N< Expected > > N( Expected expected ) \
|
||||
{ \
|
||||
return detail::N< Expected >( expected ); \
|
||||
}
|
||||
|
||||
#define MOCK_TERNARY_CONSTRAINT(N, Expr) \
|
||||
namespace detail \
|
||||
{ \
|
||||
template< typename Expected, typename Arg > \
|
||||
struct N \
|
||||
{ \
|
||||
explicit N( const Expected& expected, const Arg& arg ) \
|
||||
: expected_( expected ) \
|
||||
, arg_( arg ) \
|
||||
{} \
|
||||
template< typename Actual > \
|
||||
bool operator()( const Actual& actual ) const \
|
||||
{ \
|
||||
return test( actual, boost::unwrap_ref( expected_ ), \
|
||||
boost::unwrap_ref( arg_ ) ); \
|
||||
} \
|
||||
template< typename Actual, typename T1, typename T2 > \
|
||||
template< typename Actual, BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
||||
bool test( const Actual& actual, \
|
||||
const T1& expected, const T2& arg ) const \
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & expected_ ) ) const \
|
||||
{ \
|
||||
return Expr; \
|
||||
} \
|
||||
friend std::ostream& operator<<( std::ostream& s, const N& n ) \
|
||||
friend std::ostream& operator<<( std::ostream& s, const Name& c ) \
|
||||
{ \
|
||||
return s << BOOST_STRINGIZE(N) \
|
||||
<< "( " << mock::format( n.expected_ ) \
|
||||
<< ", " << mock::format( n.arg_ ) << " )"; \
|
||||
return s << BOOST_STRINGIZE(Name) << "( " \
|
||||
<< BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_FORMAT, _) \
|
||||
<< " )"; \
|
||||
} \
|
||||
Expected expected_; \
|
||||
Arg arg_; \
|
||||
BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_MEMBER, _) \
|
||||
}; \
|
||||
} \
|
||||
template< typename Expected, typename Arg > \
|
||||
mock::constraint< detail::N< Expected, Arg > > N( \
|
||||
Expected expected, Arg arg ) \
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename Expected_) > \
|
||||
mock::constraint< detail::Name< \
|
||||
BOOST_PP_ENUM_PARAMS(n, Expected_) > \
|
||||
> Name( BOOST_PP_ENUM_BINARY_PARAMS(n, Expected_, expected_ ) ) \
|
||||
{ \
|
||||
return detail::N< Expected, Arg >( expected, arg ); \
|
||||
return detail::Name< BOOST_PP_ENUM_PARAMS(n, Expected_) >( \
|
||||
BOOST_PP_ENUM_PARAMS(n, expected_ ) ); \
|
||||
}
|
||||
|
||||
#define MOCK_CONSTRAINT(n, Name, Expr) \
|
||||
BOOST_PP_IF(n, \
|
||||
MOCK_NARY_CONSTRAINT, \
|
||||
MOCK_UNARY_CONSTRAINT)(n, Name, Expr)
|
||||
|
||||
#endif // MOCK_CONSTRAINT_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -14,37 +14,33 @@
|
|||
#include "detail/addressof.hpp"
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/test/floating_point_comparison.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
MOCK_UNARY_CONSTRAINT( any, true && &actual )
|
||||
MOCK_UNARY_CONSTRAINT( affirm, !! actual )
|
||||
MOCK_UNARY_CONSTRAINT( negate, ! actual )
|
||||
MOCK_UNARY_CONSTRAINT( evaluate, actual() )
|
||||
MOCK_CONSTRAINT( 0, any, true && &actual )
|
||||
MOCK_CONSTRAINT( 0, affirm, !! actual )
|
||||
MOCK_CONSTRAINT( 0, negate, ! actual )
|
||||
MOCK_CONSTRAINT( 0, evaluate, actual() )
|
||||
|
||||
MOCK_BINARY_CONSTRAINT( equal, actual == expected )
|
||||
MOCK_BINARY_CONSTRAINT( less, actual < expected )
|
||||
MOCK_BINARY_CONSTRAINT( greater, actual > expected )
|
||||
MOCK_BINARY_CONSTRAINT( less_equal, actual <= expected )
|
||||
MOCK_BINARY_CONSTRAINT( greater_equal, actual >= expected )
|
||||
MOCK_CONSTRAINT( 1, equal, actual == expected_0 )
|
||||
MOCK_CONSTRAINT( 1, less, actual < expected_0 )
|
||||
MOCK_CONSTRAINT( 1, greater, actual > expected_0 )
|
||||
MOCK_CONSTRAINT( 1, less_equal, actual <= expected_0 )
|
||||
MOCK_CONSTRAINT( 1, greater_equal, actual >= expected_0 )
|
||||
|
||||
MOCK_BINARY_CONSTRAINT( small, \
|
||||
( boost::test_tools::check_is_small( actual, expected ) ) );
|
||||
|
||||
MOCK_TERNARY_CONSTRAINT( close, \
|
||||
MOCK_CONSTRAINT( 1, small, \
|
||||
( boost::test_tools::check_is_small( actual, expected_0 ) ) )
|
||||
MOCK_CONSTRAINT( 2, close, \
|
||||
( boost::test_tools::check_is_close( \
|
||||
actual, expected, \
|
||||
boost::test_tools::percent_tolerance( arg ) ) ) );
|
||||
|
||||
MOCK_TERNARY_CONSTRAINT( close_fraction, \
|
||||
actual, expected_0, \
|
||||
boost::test_tools::percent_tolerance( expected_1 ) ) ) )
|
||||
MOCK_CONSTRAINT( 2, close_fraction, \
|
||||
( boost::test_tools::check_is_close( \
|
||||
actual, expected, \
|
||||
boost::test_tools::fraction_tolerance( arg ) ) ) );
|
||||
|
||||
MOCK_TERNARY_CONSTRAINT( near, std::abs( actual - expected ) < arg );
|
||||
actual, expected_0, \
|
||||
boost::test_tools::fraction_tolerance( expected_1 ) ) ) )
|
||||
MOCK_CONSTRAINT( 2, near, std::abs( actual - expected_0 ) < expected_1 )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#define MOCK_EXPECTATION_IN_ADD(z, n, d ) \
|
||||
add( s##n.impl_ );
|
||||
|
||||
#define MOCK_EXPECTATION_IN(z, n, d) \
|
||||
expectation& in( BOOST_PP_ENUM_PARAMS(n, sequence& s) ) \
|
||||
{ \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue