Added support for nullptr as constraint

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@648 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2013-05-12 08:59:25 +00:00
parent 42c2c4e6a4
commit 1320a96179
12 changed files with 96 additions and 10 deletions

View file

@ -7,6 +7,7 @@ Not yet released
* Return actions now accept by copy types derived from abstract base types * Return actions now accept by copy types derived from abstract base types
* Officially documented MOCK_UNARY_CONSTRAINT and MOCK_BINARY_CONSTRAINT * Officially documented MOCK_UNARY_CONSTRAINT and MOCK_BINARY_CONSTRAINT
* Added support for several sequences in 'in' * Added support for several sequences in 'in'
* Added support for nullptr as constraint
[endsect] [endsect]

View file

@ -39,6 +39,10 @@ However a somewhat better solution would be :
MOCK_EXPECT( m.method ).with( mock::negate ); MOCK_EXPECT( m.method ).with( mock::negate );
or with C++11 nullptr support :
MOCK_EXPECT( m.method ).with( nullptr );
[endsect] [endsect]
[section Template methods cannot be mocked] [section Template methods cannot be mocked]

View file

@ -23,6 +23,7 @@
<ClInclude Include="..\..\turtle\constraint.hpp" /> <ClInclude Include="..\..\turtle\constraint.hpp" />
<ClInclude Include="..\..\turtle\constraints.hpp" /> <ClInclude Include="..\..\turtle\constraints.hpp" />
<ClInclude Include="..\..\turtle\detail\action.hpp" /> <ClInclude Include="..\..\turtle\detail\action.hpp" />
<ClInclude Include="..\..\turtle\detail\addressof.hpp" />
<ClInclude Include="..\..\turtle\detail\child.hpp" /> <ClInclude Include="..\..\turtle\detail\child.hpp" />
<ClInclude Include="..\..\turtle\detail\cleanup.hpp" /> <ClInclude Include="..\..\turtle\detail\cleanup.hpp" />
<ClInclude Include="..\..\turtle\detail\context.hpp" /> <ClInclude Include="..\..\turtle\detail\context.hpp" />

View file

@ -127,5 +127,8 @@
<ClInclude Include="..\..\turtle\exception.hpp"> <ClInclude Include="..\..\turtle\exception.hpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\turtle\detail\addressof.hpp">
<Filter>Source Files\detail</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -348,6 +348,18 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_failing_custom_constrain
// CHECK_CALLS( 1 ); // CHECK_CALLS( 1 );
//} //}
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
BOOST_FIXTURE_TEST_CASE( nullptr_can_be_used_in_place_of_null_pointers_in_constraints, error_fixture )
{
mock::detail::function< void( int* ) > f;
f.expect().with( nullptr );
f( 0 );
CHECK_CALLS( 1 );
}
#endif
// result handling // result handling
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_no_return_set_calls_missing_action, error_fixture ) BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_no_return_set_calls_missing_action, error_fixture )

View file

@ -78,6 +78,12 @@ BOOST_AUTO_TEST_CASE( same )
BOOST_CHECK( ! c.c_( j ) ); BOOST_CHECK( ! c.c_( j ) );
BOOST_CHECK( c.c_( i ) ); BOOST_CHECK( c.c_( i ) );
} }
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
{
std::nullptr_t p;
BOOST_CHECK( mock::same( p ).c_( p ) );
}
#endif
} }
BOOST_AUTO_TEST_CASE( assign ) BOOST_AUTO_TEST_CASE( assign )
@ -205,6 +211,14 @@ BOOST_AUTO_TEST_CASE( retrieve )
BOOST_CHECK( mock::retrieve( boost::ref( i ) ).c_( j ) ); BOOST_CHECK( mock::retrieve( boost::ref( i ) ).c_( j ) );
BOOST_CHECK_EQUAL( i, &j ); BOOST_CHECK_EQUAL( i, &j );
} }
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
{
std::nullptr_t* i = 0;
std::nullptr_t j;
BOOST_CHECK( mock::retrieve( i ).c_( j ) );
BOOST_CHECK_EQUAL( i, &j );
}
#endif
} }
namespace namespace

View file

@ -630,3 +630,12 @@ BOOST_AUTO_TEST_CASE( boost_lambda_functor_yields_question_mark_when_serialized
BOOST_CHECK_EQUAL( "?", to_string( boost::lambda::bind( &some_function ) ) ); BOOST_CHECK_EQUAL( "?", to_string( boost::lambda::bind( &some_function ) ) );
BOOST_CHECK_EQUAL( "?", to_string( boost::lambda::_1 < 42 ) ); BOOST_CHECK_EQUAL( "?", to_string( boost::lambda::_1 < 42 ) );
} }
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
BOOST_AUTO_TEST_CASE( nullptr_is_serialized )
{
BOOST_CHECK_EQUAL( "nullptr", to_string( nullptr ) );
}
#endif

View file

@ -11,6 +11,7 @@
#include "config.hpp" #include "config.hpp"
#include "constraint.hpp" #include "constraint.hpp"
#include "detail/addressof.hpp"
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/utility/addressof.hpp> #include <boost/utility/addressof.hpp>
@ -35,12 +36,12 @@ namespace detail
struct same struct same
{ {
explicit same( const Expected& expected ) explicit same( const Expected& expected )
: expected_( boost::addressof( boost::unwrap_ref( expected ) ) ) : expected_( detail::addressof( boost::unwrap_ref( expected ) ) )
{} {}
template< typename Actual > template< typename Actual >
bool operator()( const Actual& actual ) const bool operator()( const Actual& actual ) const
{ {
return boost::addressof( actual ) == expected_; return detail::addressof( actual ) == expected_;
} }
friend std::ostream& operator<<( std::ostream& os, const same& s ) friend std::ostream& operator<<( std::ostream& os, const same& s )
{ {
@ -54,7 +55,7 @@ namespace detail
struct retrieve struct retrieve
{ {
explicit retrieve( Expected& expected ) explicit retrieve( Expected& expected )
: expected_( boost::addressof( boost::unwrap_ref( expected ) ) ) : expected_( detail::addressof( boost::unwrap_ref( expected ) ) )
{} {}
template< typename Actual > template< typename Actual >
bool operator()( const Actual& actual, bool operator()( const Actual& actual,
@ -78,7 +79,7 @@ namespace detail
> >
>::type* = 0 ) const >::type* = 0 ) const
{ {
*expected_ = boost::addressof( actual ); *expected_ = detail::addressof( actual );
return true; return true;
} }
friend std::ostream& operator<<( std::ostream& s, const retrieve& r ) friend std::ostream& operator<<( std::ostream& s, const retrieve& r )

View file

@ -0,0 +1,35 @@
// 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)
#ifndef MOCK_ADDRESSOF_HPP_INCLUDED
#define MOCK_ADDRESSOF_HPP_INCLUDED
#include <boost/utility/addressof.hpp>
namespace mock
{
namespace detail
{
using boost::addressof;
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
inline const std::nullptr_t* addressof( const std::nullptr_t& p )
{
return &p;
}
inline std::nullptr_t* addressof( std::nullptr_t& p )
{
return &p;
}
#endif
}
} // mock
#endif // MOCK_ADDRESSOF_HPP_INCLUDED

View file

@ -11,7 +11,7 @@
#include "../config.hpp" #include "../config.hpp"
#include "../stream.hpp" #include "../stream.hpp"
#include <boost/utility/addressof.hpp> #include "addressof.hpp"
namespace mock namespace mock
{ {
@ -21,7 +21,7 @@ namespace detail
struct formatter struct formatter
{ {
explicit formatter( const T& t ) explicit formatter( const T& t )
: t_( boost::addressof( t ) ) : t_( detail::addressof( t ) )
{} {}
void serialize( stream& s ) const void serialize( stream& s ) const
{ {

View file

@ -137,6 +137,13 @@ namespace detail
{ {
return s << '?'; return s << '?';
} }
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
inline stream& operator<<( stream& s, std::nullptr_t )
{
return s << "nullptr";
}
#endif
template< typename T > template< typename T >
BOOST_DEDUCED_TYPENAME boost::enable_if< BOOST_DEDUCED_TYPENAME boost::enable_if<
boost::function_types::is_callable_builtin< T >, boost::function_types::is_callable_builtin< T >,

View file

@ -10,7 +10,6 @@
#define MOCK_STREAM_HPP_INCLUDED #define MOCK_STREAM_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include <boost/utility/addressof.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <ostream> #include <ostream>
@ -53,16 +52,16 @@ namespace conversion
struct holder_imp : holder struct holder_imp : holder
{ {
explicit holder_imp( const T& t ) explicit holder_imp( const T& t )
: t_( boost::addressof( t ) ) : t_( t )
{} {}
virtual void serialize( std::ostream& s ) const virtual void serialize( std::ostream& s ) const
{ {
// if an error about an ambiguous conversion is generated by the // if an error about an ambiguous conversion is generated by the
// line below the solution is to add a serialization operator to a // line below the solution is to add a serialization operator to a
// mock::stream for T // mock::stream for T
s << *t_; s << t_;
} }
const T* t_; const T& t_;
}; };
struct any : boost::noncopyable struct any : boost::noncopyable