mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Reworked MOCK_CONSTRAINT to be able to provide names to parameters
git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@667 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
parent
bd2fc97bb9
commit
8d08012cdf
10 changed files with 195 additions and 51 deletions
|
|
@ -1,5 +1,12 @@
|
|||
[section Changelog]
|
||||
|
||||
[section trunk]
|
||||
Not yet released
|
||||
|
||||
* Reworked MOCK_CONSTRAINT to be able to provide names to parameters
|
||||
|
||||
[endsect]
|
||||
|
||||
[section 1.2.3]
|
||||
Released 20 May 2013
|
||||
|
||||
|
|
|
|||
|
|
@ -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_constraint MOCK_CONSTRAINT] macro takes care of everything for simple cases.]
|
||||
[note The [link turtle.reference.constraint constraint helper macro] takes care of everything for simple cases.]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
|
|
|||
|
|
@ -759,8 +759,8 @@ BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_static_mock_method )
|
|||
namespace helpers_example_1
|
||||
{
|
||||
//[ helpers_example_1
|
||||
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
|
||||
MOCK_CONSTRAINT( any, true ) // this is how mock::any could be defined
|
||||
MOCK_CONSTRAINT( forty_two, actual == 42 ) // this defines a 'forty_two' constraint
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_0_arity )
|
||||
{
|
||||
|
|
@ -774,8 +774,8 @@ BOOST_AUTO_TEST_CASE( mock_constraint_0_arity )
|
|||
namespace helpers_example_2
|
||||
{
|
||||
//[ helpers_example_2
|
||||
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 )'
|
||||
MOCK_CONSTRAINT( equal, expected, actual == expected ) // this is how mock::equal could be defined
|
||||
MOCK_CONSTRAINT( near, expected, std::abs( actual - expected ) < 0.01 ) // this defines a 'near' constraint which can be used as 'near( 42 )'
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_1_arity )
|
||||
{
|
||||
|
|
@ -789,7 +789,50 @@ BOOST_AUTO_TEST_CASE( mock_constraint_1_arity )
|
|||
namespace helpers_example_3
|
||||
{
|
||||
//[ helpers_example_3
|
||||
MOCK_CONSTRAINT( 2, near, std::abs( actual - expected_0 ) < expected_1 ) // this is how mock::near is defined
|
||||
MOCK_CONSTRAINT( near, expected, tolerance, std::abs( actual - expected ) < tolerance ) // this is how mock::near could be defined
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
|
||||
{
|
||||
MOCK_FUNCTOR( f, void( int ) );
|
||||
MOCK_EXPECT( f ).with( near( 42, 0.001 ) );
|
||||
}
|
||||
//]
|
||||
}
|
||||
|
||||
namespace helpers_example_4
|
||||
{
|
||||
//[ helpers_example_4
|
||||
MOCK_CONSTRAINT_EXT( any, 0,, true ) // this is (almost) how mock::any is defined
|
||||
MOCK_CONSTRAINT_EXT( forty_two, 0,, 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_5
|
||||
{
|
||||
//[ helpers_example_5
|
||||
MOCK_CONSTRAINT_EXT( equal, 1, ( expected ), actual == expected ) // this is how mock::equal is defined
|
||||
MOCK_CONSTRAINT_EXT( near, 1, ( expected ), std::abs( actual - expected ) < 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_6
|
||||
{
|
||||
//[ helpers_example_6
|
||||
MOCK_CONSTRAINT_EXT( near, 2, ( expected, tolerance ), std::abs( actual - expected ) < tolerance ) // this is how mock::near is defined
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ Synopsis :
|
|||
|
||||
[note [link turtle.reference.creation.constructor Constructors], [link turtle.reference.creation.destructor destructors] and [link turtle.reference.creation.conversion_operator conversion operators] require special care.]
|
||||
|
||||
With a compiler without support for variadic macros the signature and the identifier cannot be specified, thus in case of ambiguity another set of macros must be used.
|
||||
For compilers without support for variadic macros the signature and the identifier cannot be specified, thus in case of ambiguity another set of macros must be used.
|
||||
|
||||
Synopsis :
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ Synopsis :
|
|||
|
||||
[note A static object is used behind the scene in order to keep track of the expectations of a mock static method, therefore to ensure all tests run in isolation it is strongly suggested to manually [link turtle.reference.verification verify] and [link turtle.reference.reset reset] the static method at the end of each test.]
|
||||
|
||||
[warning With a compiler without support for variadic macros the identifier cannot be ommitted and must be given explicitly.]
|
||||
[warning For compilers without support for variadic macros the identifier cannot be ommitted and must be given explicitly.]
|
||||
|
||||
Example :
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ Synopsis :
|
|||
|
||||
[note A static object is used behind the scene in order to keep track of the expectations of a mock function, therefore to ensure all tests run in isolation it is strongly suggested to manually [link turtle.reference.verification verify] and [link turtle.reference.reset reset] the mock function at the end of each test.]
|
||||
|
||||
[warning With a compiler without support for variadic macros the identifier cannot be ommitted and must be given explicitly.]
|
||||
[warning For compilers without support for variadic macros the identifier cannot be ommitted and must be given explicitly.]
|
||||
|
||||
Example :
|
||||
|
||||
|
|
@ -308,6 +308,8 @@ Synopsis :
|
|||
|
||||
MOCK_EXPECT( identifier ).with( constraint_1, constraint_2, ... );
|
||||
|
||||
The number of constraints must match the number of mocked parameters.
|
||||
|
||||
Constraints :
|
||||
|
||||
[table
|
||||
|
|
@ -395,7 +397,7 @@ A sequence enforces a given order between two or more expectations.
|
|||
|
||||
Synopsis :
|
||||
|
||||
MOCK_EXPECT( identifier_1 ).in( sequence_1 [, sequence_2 [, ...]] );
|
||||
MOCK_EXPECT( identifier_1 ).in( sequence_1, sequence_2, ... );
|
||||
|
||||
Each sequence is an instance of mock::sequence.
|
||||
|
||||
|
|
@ -488,33 +490,47 @@ Example :
|
|||
|
||||
[endsect]
|
||||
|
||||
[section Helpers]
|
||||
[section Constraint]
|
||||
|
||||
This section presents various useful tools.
|
||||
|
||||
[section MOCK_CONSTRAINT]
|
||||
This section presents a simple means of creating a new constraint.
|
||||
|
||||
Synopsis :
|
||||
|
||||
MOCK_CONSTRAINT( arity, name, expression ) // defines a constraint 'name' based on the given 'expression'
|
||||
MOCK_CONSTRAINT( name, expected_1, expected_2, ..., expression ) // defines a constraint 'name' based on the given 'expression'
|
||||
|
||||
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...
|
||||
The expression manipulates a received parameter ['actual] in order to implement the constraint, as well as extra optional arguments named ['expected_1], ['expected_2], ...
|
||||
|
||||
[note The type of all expected arguments must be copy-constructible and assignable.]
|
||||
For compilers without supporting variadic macros the alternate following macro must be used.
|
||||
|
||||
Synopsis :
|
||||
|
||||
MOCK_CONSTRAINT_EXT( name, arity, ( expected_1, expected_2, ... ), expression ) // defines a constraint 'name' based on the given 'expression'
|
||||
|
||||
Of course this macro is also available for compilers which support variadic macros.
|
||||
|
||||
Example without any extra argument :
|
||||
|
||||
[helpers_example_1]
|
||||
|
||||
or with the alternate more portable macro :
|
||||
|
||||
[helpers_example_4]
|
||||
|
||||
Example with one extra argument :
|
||||
|
||||
[helpers_example_2]
|
||||
|
||||
or with the alternate more portable macro :
|
||||
|
||||
[helpers_example_5]
|
||||
|
||||
Example with two extra arguments :
|
||||
|
||||
[helpers_example_3]
|
||||
|
||||
[endsect]
|
||||
or with the alternate more portable macro :
|
||||
|
||||
[helpers_example_6]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ rule run-test ( name )
|
|||
}
|
||||
|
||||
alias mock_tests :
|
||||
[ run-test test_constraint ]
|
||||
[ run-test test_constraints ]
|
||||
[ run-test test_error ]
|
||||
[ run-test test_integration ]
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
<ClCompile Include="..\..\test\detail\test_is_functor.cpp" />
|
||||
<ClCompile Include="..\..\test\detail\test_signature.cpp" />
|
||||
<ClCompile Include="..\..\test\detail\test_type_name.cpp" />
|
||||
<ClCompile Include="..\..\test\test_constraint.cpp" />
|
||||
<ClCompile Include="..\..\test\test_constraints.cpp" />
|
||||
<ClCompile Include="..\..\test\test_error.cpp" />
|
||||
<ClCompile Include="..\..\test\test_integration.cpp" />
|
||||
|
|
|
|||
|
|
@ -63,5 +63,8 @@
|
|||
<ClCompile Include="..\..\test\undefined.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\test\test_constraint.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
28
test/test_constraint.cpp
Normal file
28
test/test_constraint.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <turtle/constraint.hpp>
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
|
||||
#ifndef BOOST_NO_VARIADIC_MACROS
|
||||
|
||||
namespace
|
||||
{
|
||||
MOCK_CONSTRAINT( constraint_0, actual == 0 )
|
||||
MOCK_CONSTRAINT( constraint_1, expected, actual == expected )
|
||||
MOCK_CONSTRAINT( constraint_2, expected_0, expected_1, actual == expected_0 || actual == expected_1 )
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mock_constraint_is_supported_by_compilers_with_variadic_macros )
|
||||
{
|
||||
BOOST_CHECK( constraint_0.c_( 0 ) );
|
||||
BOOST_CHECK( constraint_1( 0 ).c_( 0 ) );
|
||||
BOOST_CHECK( constraint_2( 0, 0 ).c_( 0 ) );
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_VARIADIC_MACROS
|
||||
|
|
@ -11,12 +11,14 @@
|
|||
|
||||
#include "config.hpp"
|
||||
#include "log.hpp"
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/variadic/to_array.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>
|
||||
#include <boost/preprocessor/array.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
|
|
@ -124,7 +126,7 @@ namespace detail
|
|||
}
|
||||
} // mock
|
||||
|
||||
#define MOCK_UNARY_CONSTRAINT(n, Name, Expr) \
|
||||
#define MOCK_UNARY_CONSTRAINT(Name, n, Args, Expr) \
|
||||
namespace detail \
|
||||
{ \
|
||||
struct Name \
|
||||
|
|
@ -154,7 +156,15 @@ namespace detail
|
|||
#define MOCK_CONSTRAINT_MEMBER(z, n, d) \
|
||||
Expected_##n expected##n;
|
||||
|
||||
#define MOCK_NARY_CONSTRAINT(n, Name, Expr) \
|
||||
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
|
||||
BOOST_DEDUCED_TYPENAME \
|
||||
boost::unwrap_reference< Expected_##n >::type \
|
||||
BOOST_PP_ARRAY_ELEM(n, Args)
|
||||
|
||||
#define MOCK_CONSTRAINT_PARAM(z, n, Args) \
|
||||
T##n BOOST_PP_ARRAY_ELEM(n, Args)
|
||||
|
||||
#define MOCK_NARY_CONSTRAINT(Name, n, Args, Expr) \
|
||||
namespace detail \
|
||||
{ \
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename Expected_) > \
|
||||
|
|
@ -170,9 +180,10 @@ namespace detail
|
|||
return test( actual, \
|
||||
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_UNWRAP_REF, _) ); \
|
||||
} \
|
||||
template< typename Actual, BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
||||
template< typename Actual > \
|
||||
bool test( const Actual& actual, \
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(n, const T, & expected_ ) ) const \
|
||||
BOOST_PP_ENUM(n, \
|
||||
MOCK_CONSTRAINT_CREF_PARAM, (n, Args)) ) const \
|
||||
{ \
|
||||
return Expr; \
|
||||
} \
|
||||
|
|
@ -185,18 +196,52 @@ namespace detail
|
|||
BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_MEMBER, _) \
|
||||
}; \
|
||||
} \
|
||||
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_ ) ) \
|
||||
template< BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
||||
mock::constraint< \
|
||||
detail::Name< BOOST_PP_ENUM_PARAMS(n, T) > \
|
||||
> Name( BOOST_PP_ENUM(n, MOCK_CONSTRAINT_PARAM, (n, Args)) ) \
|
||||
{ \
|
||||
return detail::Name< BOOST_PP_ENUM_PARAMS(n, Expected_) >( \
|
||||
BOOST_PP_ENUM_PARAMS(n, expected_ ) ); \
|
||||
return detail::Name< BOOST_PP_ENUM_PARAMS(n, T) > Args; \
|
||||
}
|
||||
|
||||
#define MOCK_CONSTRAINT(n, Name, Expr) \
|
||||
#define MOCK_CONSTRAINT_EXT(Name, n, Args, Expr) \
|
||||
BOOST_PP_IF(n, \
|
||||
MOCK_NARY_CONSTRAINT, \
|
||||
MOCK_UNARY_CONSTRAINT)(n, Name, Expr)
|
||||
MOCK_UNARY_CONSTRAINT)(Name, n, Args, Expr)
|
||||
|
||||
#ifndef BOOST_NO_VARIADIC_MACROS
|
||||
|
||||
#if BOOST_MSVC
|
||||
# define MOCK_VARIADIC_SIZE(...) \
|
||||
BOOST_PP_CAT(MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \
|
||||
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \
|
||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),)
|
||||
#else // BOOST_MSVC
|
||||
# define MOCK_VARIADIC_SIZE(...) \
|
||||
MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \
|
||||
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \
|
||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
|
||||
#endif // BOOST_MSVC
|
||||
#define MOCK_VARIADIC_SIZE_I( \
|
||||
e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, \
|
||||
e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, \
|
||||
e25, e26, e27, e28, e29, e30, e31, size, ...) size
|
||||
|
||||
#define MOCK_CONSTRAINT_AUX_AUX(Name, n, Array) \
|
||||
MOCK_CONSTRAINT_EXT( \
|
||||
Name, n, \
|
||||
BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_POP_BACK(Array)), \
|
||||
BOOST_PP_ARRAY_ELEM(n, Array))
|
||||
|
||||
#define MOCK_CONSTRAINT_AUX(Name, Size, Tuple) \
|
||||
MOCK_CONSTRAINT_AUX_AUX(Name, BOOST_PP_DEC(Size), (Size,Tuple))
|
||||
|
||||
#define MOCK_CONSTRAINT(Name, ...) \
|
||||
MOCK_CONSTRAINT_AUX( \
|
||||
Name, MOCK_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))
|
||||
|
||||
#endif // BOOST_NO_VARIADIC_MACROS
|
||||
|
||||
#endif // MOCK_CONSTRAINT_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -19,28 +19,28 @@
|
|||
|
||||
namespace mock
|
||||
{
|
||||
MOCK_CONSTRAINT( 0, any, true && &actual )
|
||||
MOCK_CONSTRAINT( 0, affirm, !! actual )
|
||||
MOCK_CONSTRAINT( 0, negate, ! actual )
|
||||
MOCK_CONSTRAINT( 0, evaluate, actual() )
|
||||
MOCK_CONSTRAINT_EXT( any, 0,, true && &actual )
|
||||
MOCK_CONSTRAINT_EXT( affirm, 0,, !! actual )
|
||||
MOCK_CONSTRAINT_EXT( negate, 0,, ! actual )
|
||||
MOCK_CONSTRAINT_EXT( evaluate, 0,, actual() )
|
||||
|
||||
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_CONSTRAINT_EXT( equal, 1, ( expected ), actual == expected )
|
||||
MOCK_CONSTRAINT_EXT( less, 1, ( expected ), actual < expected )
|
||||
MOCK_CONSTRAINT_EXT( greater, 1, ( expected ), actual > expected )
|
||||
MOCK_CONSTRAINT_EXT( less_equal, 1, ( expected ), actual <= expected )
|
||||
MOCK_CONSTRAINT_EXT( greater_equal, 1, ( expected ), actual >= expected )
|
||||
|
||||
MOCK_CONSTRAINT( 1, small, \
|
||||
( boost::test_tools::check_is_small( actual, expected_0 ) ) )
|
||||
MOCK_CONSTRAINT( 2, close, \
|
||||
MOCK_CONSTRAINT_EXT( small, 1, ( expected ), \
|
||||
( boost::test_tools::check_is_small( actual, expected ) ) )
|
||||
MOCK_CONSTRAINT_EXT( close, 2, ( expected, tolerance ), \
|
||||
( boost::test_tools::check_is_close( \
|
||||
actual, expected_0, \
|
||||
boost::test_tools::percent_tolerance( expected_1 ) ) ) )
|
||||
MOCK_CONSTRAINT( 2, close_fraction, \
|
||||
actual, expected, \
|
||||
boost::test_tools::percent_tolerance( tolerance ) ) ) )
|
||||
MOCK_CONSTRAINT_EXT( close_fraction, 2, ( expected, tolerance ), \
|
||||
( boost::test_tools::check_is_close( \
|
||||
actual, expected_0, \
|
||||
boost::test_tools::fraction_tolerance( expected_1 ) ) ) )
|
||||
MOCK_CONSTRAINT( 2, near, std::abs( actual - expected_0 ) < expected_1 )
|
||||
actual, expected, \
|
||||
boost::test_tools::fraction_tolerance( tolerance ) ) ) )
|
||||
MOCK_CONSTRAINT_EXT( near, 2, ( expected, tolerance ), std::abs( actual - expected ) < tolerance )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue