From 10eed34ad7dfb7ae7fa557d00ac870008eef8113 Mon Sep 17 00:00:00 2001 From: mat007 Date: Thu, 12 May 2011 20:00:52 +0000 Subject: [PATCH] Fixed a bug with const smart pointers as first argument to MOCK_EXPECT being invalid git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@327 860be788-9bd5-4423-9f1e-828f051e677b --- src/libraries/turtle/mock.hpp | 70 ++++++++------------- src/tests/turtle_test/mock_test.cpp | 94 ++++++++++++++++------------- 2 files changed, 79 insertions(+), 85 deletions(-) diff --git a/src/libraries/turtle/mock.hpp b/src/libraries/turtle/mock.hpp index 11f6661..4ff0b56 100644 --- a/src/libraries/turtle/mock.hpp +++ b/src/libraries/turtle/mock.hpp @@ -27,7 +27,6 @@ #include #define BOOST_TYPEOF_SILENT #include -#include #include namespace mock @@ -35,26 +34,33 @@ namespace mock namespace detail { template< typename T > - T& ref( T& t ) + T& deref( T& t ) { return t; } template< typename T > - T& ref( T* t ) + T& deref( T* t ) { if( ! t ) throw std::invalid_argument( "derefencing null pointer" ); return *t; } template< typename T > - T& ref( std::auto_ptr< T >& t ) + T& deref( std::auto_ptr< T >& t ) { if( ! t.get() ) throw std::invalid_argument( "derefencing null pointer" ); return *t; } template< typename T > - T& ref( boost::shared_ptr< T >& t ) + T& deref( const std::auto_ptr< T >& t ) + { + if( ! t.get() ) + throw std::invalid_argument( "derefencing null pointer" ); + return *t; + } + template< typename T > + T& deref( boost::shared_ptr< T > t ) { if( ! t.get() ) throw std::invalid_argument( "derefencing null pointer" ); @@ -97,45 +103,23 @@ namespace detail template< typename E > E& configure( BOOST_DEDUCED_TYPENAME E::function_tag, - const std::string& parent, const std::string& /*op*/, - const std::string& /*name*/, E& e ) + const std::string& parent, const std::string& /*name*/, E& e ) { if( parent != "?" || e.tag() == "?" ) e.tag( parent ); return e; } template< typename E, typename T > - E& configure( E& e, const std::string& parent, const std::string& op, + E& configure( E& e, const std::string& parent, const std::string& name, const T& t ) { if( parent != "?" || e.tag() == "?" ) mock::detail::set_parent( e, - parent + op + mock::detail::type_name( typeid( T ) ) + "::", + parent + " " + mock::detail::type_name( typeid( T ) ) + "::", name, t ); return e; } - template< typename T > - std::string op( T& ) - { - return "."; - } - template< typename T > - std::string op( T* ) - { - return "->"; - } - template< typename T > - std::string op( std::auto_ptr< T >& ) - { - return "->"; - } - template< typename T > - std::string op( boost::shared_ptr< T >& ) - { - return "->"; - } - template< typename T > struct base { @@ -169,14 +153,12 @@ namespace detail mock::function< S > #define MOCK_MOCKER(o, t) \ - mock::detail::configure( mock::detail::ref( o ).exp##t, \ - BOOST_PP_STRINGIZE(o), mock::detail::op( o ), \ - BOOST_PP_STRINGIZE(t), mock::detail::ref( o ) ) -#define MOCK_ANONYMOUS_MOCKER_EXT(o, M, t) \ - mock::detail::configure( mock::detail::ref( o ).exp##t, \ - "?", ".", BOOST_PP_STRINGIZE(M), mock::detail::ref( o ) ) -#define MOCK_ANONYMOUS_MOCKER(o, t) \ - MOCK_ANONYMOUS_MOCKER_EXT( o, t, t ) + mock::detail::configure( mock::detail::deref( o ).exp##t, \ + BOOST_PP_STRINGIZE(o), BOOST_PP_STRINGIZE(t), \ + mock::detail::deref( o ) ) +#define MOCK_ANONYMOUS_MOCKER(o, M, t) \ + mock::detail::configure( mock::detail::deref( o ).exp##t, \ + "?", BOOST_PP_STRINGIZE(M), mock::detail::deref( o ) ) #define MOCK_METHOD_EXPECTATION(S, t) \ mutable mock::function< S > exp##t; @@ -186,7 +168,7 @@ namespace detail #define MOCK_METHOD_STUB(M, n, S, t, c, tpn) \ MOCK_DECL(M, n, S, c, tpn) \ { \ - return mock::detail::call( MOCK_ANONYMOUS_MOCKER(this, t) \ + return mock::detail::call( MOCK_ANONYMOUS_MOCKER(this, t, t) \ BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, p) ); \ } @@ -215,18 +197,18 @@ namespace detail MOCK_METHOD_EXPECTATION(S, t) #define MOCK_DESTRUCTOR(T, t) \ - ~T() { MOCK_ANONYMOUS_MOCKER_EXT(this, ~T, t).test(); } \ + ~T() { MOCK_ANONYMOUS_MOCKER(this, ~T, t).test(); } \ MOCK_METHOD_EXPECTATION(void(), t) #define MOCK_CONST_CONVERSION_OPERATOR(T, t) \ - operator T() const { return MOCK_ANONYMOUS_MOCKER_EXT(this, operator T, t)(); } \ + operator T() const { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ MOCK_METHOD_EXPECTATION(T(), t) #define MOCK_NON_CONST_CONVERSION_OPERATOR(T, t) \ - operator T() { return MOCK_ANONYMOUS_MOCKER_EXT(this, operator T, t)(); } \ + operator T() { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ MOCK_METHOD_EXPECTATION(T(), t) #define MOCK_CONVERSION_OPERATOR(T, t) \ - operator T() const { return MOCK_ANONYMOUS_MOCKER_EXT(this, operator T, t)(); } \ - operator T() { return MOCK_ANONYMOUS_MOCKER_EXT(this, operator T, t)(); } \ + operator T() const { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ + operator T() { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ MOCK_METHOD_EXPECTATION(T(), t) #define MOCK_EXPECT(o,t) MOCK_MOCKER(o,t).expect( __FILE__, __LINE__ ) diff --git a/src/tests/turtle_test/mock_test.cpp b/src/tests/turtle_test/mock_test.cpp index 117b344..74f7103 100644 --- a/src/tests/turtle_test/mock_test.cpp +++ b/src/tests/turtle_test/mock_test.cpp @@ -34,24 +34,6 @@ namespace > )); } -BOOST_AUTO_TEST_CASE( ptr_uniformizes_reference_and_pointer ) -{ - int i = 0; - BOOST_CHECK_EQUAL( mock::detail::ref( i ), mock::detail::ref( &i ) ); -} - -BOOST_AUTO_TEST_CASE( ptr_accesses_inner_pointer_from_auto_ptr ) -{ - std::auto_ptr< int > i( new int( 0 ) ); - BOOST_CHECK_EQUAL( *i, mock::detail::ref( i ) ); -} - -BOOST_AUTO_TEST_CASE( ptr_accesses_inner_pointer_from_shared_ptr ) -{ - boost::shared_ptr< int > i( new int( 0 ) ); - BOOST_CHECK_EQUAL( *i, mock::detail::ref( i ) ); -} - namespace { template< typename T > @@ -180,24 +162,54 @@ namespace } } +#define MOCK_ANONYMOUS_MOCKER_EXT(o, t) \ + MOCK_ANONYMOUS_MOCKER( o, t, t ) + BOOST_AUTO_TEST_CASE( mock_object_is_named ) { my_mock m; - BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "?.my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) ); - BOOST_CHECK_EQUAL( "m.my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m.my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) ); - BOOST_CHECK_EQUAL( "m.my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m.my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); } -BOOST_AUTO_TEST_CASE( mock_object_pointer_is_named ) +BOOST_AUTO_TEST_CASE( mock_object_auto_pointer_is_named ) { std::auto_ptr< my_mock > m( new my_mock ); - BOOST_CHECK_EQUAL( "?.my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m->my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); +} + +BOOST_AUTO_TEST_CASE( mock_object_const_auto_pointer_is_named ) +{ + const std::auto_ptr< my_mock > m( new my_mock ); + BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); +} + +BOOST_AUTO_TEST_CASE( mock_object_shared_pointer_is_named ) +{ + boost::shared_ptr< my_mock > m( new my_mock ); + BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); +} + +BOOST_AUTO_TEST_CASE( mock_object_const_shared_pointer_is_named ) +{ + const boost::shared_ptr< my_mock > m( new my_mock ); + BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); } namespace @@ -212,12 +224,12 @@ namespace BOOST_AUTO_TEST_CASE( custom_mock_object_without_macros_and_without_inheriting_from_object_is_named ) { my_custom_mock m; - BOOST_CHECK_EQUAL( "?.my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "?.my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) ); - BOOST_CHECK_EQUAL( "m.my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "?.my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) ); - BOOST_CHECK_EQUAL( "m.my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m.my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); + BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); + BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); } namespace @@ -232,12 +244,12 @@ namespace BOOST_AUTO_TEST_CASE( custom_mock_object_without_macros_is_named ) { my_custom_mock_object m; - BOOST_CHECK_EQUAL( "?.my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "?.my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) ); - BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) ); - BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) ); - BOOST_CHECK_EQUAL( "m.my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "? my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); + BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); + BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); + BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); } BOOST_AUTO_TEST_CASE( mock_functor_is_named )