diff --git a/build/boost/doc/changelog.qbk b/build/boost/doc/changelog.qbk index 2978c5d..a540006 100644 --- a/build/boost/doc/changelog.qbk +++ b/build/boost/doc/changelog.qbk @@ -7,6 +7,7 @@ Not yet released * Return actions now accept by copy types derived from abstract base types * Officially documented MOCK_UNARY_CONSTRAINT and MOCK_BINARY_CONSTRAINT * Added support for several sequences in 'in' +* Added support for nullptr as constraint [endsect] diff --git a/build/boost/doc/limitations.qbk b/build/boost/doc/limitations.qbk index d8f095b..2d6efb7 100644 --- a/build/boost/doc/limitations.qbk +++ b/build/boost/doc/limitations.qbk @@ -39,6 +39,10 @@ However a somewhat better solution would be : MOCK_EXPECT( m.method ).with( mock::negate ); +or with C++11 nullptr support : + + MOCK_EXPECT( m.method ).with( nullptr ); + [endsect] [section Template methods cannot be mocked] diff --git a/build/vc100/turtle.vcxproj b/build/vc100/turtle.vcxproj index ca41443..b0f83df 100644 --- a/build/vc100/turtle.vcxproj +++ b/build/vc100/turtle.vcxproj @@ -23,6 +23,7 @@ + diff --git a/build/vc100/turtle.vcxproj.filters b/build/vc100/turtle.vcxproj.filters index 027d606..3b07c11 100644 --- a/build/vc100/turtle.vcxproj.filters +++ b/build/vc100/turtle.vcxproj.filters @@ -127,5 +127,8 @@ Source Files + + Source Files\detail + \ No newline at end of file diff --git a/test/detail/test_function.cpp b/test/detail/test_function.cpp index 4bb2559..c08cdf5 100644 --- a/test/detail/test_function.cpp +++ b/test/detail/test_function.cpp @@ -348,6 +348,18 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_failing_custom_constrain // 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 BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_no_return_set_calls_missing_action, error_fixture ) diff --git a/test/test_constraints.cpp b/test/test_constraints.cpp index 809b076..a433f0d 100644 --- a/test/test_constraints.cpp +++ b/test/test_constraints.cpp @@ -78,6 +78,12 @@ BOOST_AUTO_TEST_CASE( same ) BOOST_CHECK( ! c.c_( j ) ); 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 ) @@ -205,6 +211,14 @@ BOOST_AUTO_TEST_CASE( retrieve ) BOOST_CHECK( mock::retrieve( boost::ref( i ) ).c_( 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 diff --git a/test/test_log.cpp b/test/test_log.cpp index 6dfc946..0241539 100644 --- a/test/test_log.cpp +++ b/test/test_log.cpp @@ -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::_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 diff --git a/turtle/constraints.hpp b/turtle/constraints.hpp index 6feafed..111e461 100644 --- a/turtle/constraints.hpp +++ b/turtle/constraints.hpp @@ -11,6 +11,7 @@ #include "config.hpp" #include "constraint.hpp" +#include "detail/addressof.hpp" #include #include #include @@ -35,12 +36,12 @@ namespace detail struct same { explicit same( const Expected& expected ) - : expected_( boost::addressof( boost::unwrap_ref( expected ) ) ) + : expected_( detail::addressof( boost::unwrap_ref( expected ) ) ) {} template< typename Actual > 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 ) { @@ -54,7 +55,7 @@ namespace detail struct retrieve { explicit retrieve( Expected& expected ) - : expected_( boost::addressof( boost::unwrap_ref( expected ) ) ) + : expected_( detail::addressof( boost::unwrap_ref( expected ) ) ) {} template< typename Actual > bool operator()( const Actual& actual, @@ -78,7 +79,7 @@ namespace detail > >::type* = 0 ) const { - *expected_ = boost::addressof( actual ); + *expected_ = detail::addressof( actual ); return true; } friend std::ostream& operator<<( std::ostream& s, const retrieve& r ) diff --git a/turtle/detail/addressof.hpp b/turtle/detail/addressof.hpp new file mode 100644 index 0000000..66b54c1 --- /dev/null +++ b/turtle/detail/addressof.hpp @@ -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 + +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 diff --git a/turtle/detail/formatter.hpp b/turtle/detail/formatter.hpp index d8d8be8..78dddae 100644 --- a/turtle/detail/formatter.hpp +++ b/turtle/detail/formatter.hpp @@ -11,7 +11,7 @@ #include "../config.hpp" #include "../stream.hpp" -#include +#include "addressof.hpp" namespace mock { @@ -21,7 +21,7 @@ namespace detail struct formatter { explicit formatter( const T& t ) - : t_( boost::addressof( t ) ) + : t_( detail::addressof( t ) ) {} void serialize( stream& s ) const { diff --git a/turtle/log.hpp b/turtle/log.hpp index 86f13bd..c114c9f 100644 --- a/turtle/log.hpp +++ b/turtle/log.hpp @@ -137,6 +137,13 @@ namespace detail { 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 > BOOST_DEDUCED_TYPENAME boost::enable_if< boost::function_types::is_callable_builtin< T >, diff --git a/turtle/stream.hpp b/turtle/stream.hpp index 642013e..077507a 100644 --- a/turtle/stream.hpp +++ b/turtle/stream.hpp @@ -10,7 +10,6 @@ #define MOCK_STREAM_HPP_INCLUDED #include "config.hpp" -#include #include #include @@ -53,16 +52,16 @@ namespace conversion struct holder_imp : holder { explicit holder_imp( const T& t ) - : t_( boost::addressof( t ) ) + : t_( t ) {} virtual void serialize( std::ostream& s ) const { // if an error about an ambiguous conversion is generated by the // line below the solution is to add a serialization operator to a // mock::stream for T - s << *t_; + s << t_; } - const T* t_; + const T& t_; }; struct any : boost::noncopyable