From 860e07243930a0b74e49b0aa00c3b85c0df43dc9 Mon Sep 17 00:00:00 2001 From: Mathieu Champlon Date: Sat, 17 Mar 2018 22:20:04 +0100 Subject: [PATCH] Fixed perfect forwarding bug --- .../turtle/detail/expectation_template.hpp | 14 +++++-- .../turtle/detail/matcher_base_template.hpp | 5 ++- test/detail/test_function.cpp | 39 ++++++++++++++++++- test/test_integration.cpp | 13 +++++++ 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/include/turtle/detail/expectation_template.hpp b/include/turtle/detail/expectation_template.hpp index e404460..9fde37a 100644 --- a/include/turtle/detail/expectation_template.hpp +++ b/include/turtle/detail/expectation_template.hpp @@ -26,6 +26,9 @@ #define MOCK_EXPECTATION_PARAM(z, n, Args) \ boost::forward< T##n >( a##n ) +#define MOCK_RV_REF_ARG(z, n, d) \ + BOOST_RV_REF(T##n) a##n + namespace mock { namespace detail @@ -39,7 +42,7 @@ namespace detail { private: virtual bool operator()( - BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF, _) ) { return true; } @@ -73,7 +76,7 @@ namespace detail private: virtual bool operator()( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF_ARG, _) ) { return BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_IS_VALID, _); @@ -103,7 +106,7 @@ namespace detail private: virtual bool operator()( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF_ARG, _) ) { return f_( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) ); } @@ -201,7 +204,7 @@ namespace detail } bool is_valid( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF_ARG, _) ) const { return !invocation_->exhausted() && (*matcher_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) ); @@ -264,3 +267,6 @@ namespace detail #undef MOCK_EXPECTATION_IS_VALID #undef MOCK_EXPECTATION_SERIALIZE #undef MOCK_EXPECTATION_SERIALIZE_ANY +#undef MOCK_EXPECTATION_PARAM +#undef MOCK_RV_REF_ARG +#undef MOCK_RV_REF diff --git a/include/turtle/detail/matcher_base_template.hpp b/include/turtle/detail/matcher_base_template.hpp index c1f1fa7..f8b64ee 100644 --- a/include/turtle/detail/matcher_base_template.hpp +++ b/include/turtle/detail/matcher_base_template.hpp @@ -6,6 +6,9 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) +#define MOCK_RV_REF(z, n, d) \ + BOOST_RV_REF(T##n) + namespace mock { namespace detail @@ -21,7 +24,7 @@ namespace detail virtual ~matcher_base() {} virtual bool operator()( - BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) = 0; + BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_RV_REF, _) ) = 0; friend std::ostream& operator<<( std::ostream& s, const matcher_base& m ) diff --git a/test/detail/test_function.cpp b/test/detail/test_function.cpp index e31235a..682840a 100644 --- a/test/detail/test_function.cpp +++ b/test/detail/test_function.cpp @@ -84,11 +84,46 @@ BOOST_FIXTURE_TEST_CASE( triggering_an_unlimited_expectation_is_valid, mock_erro f(); CHECK_CALLS( 2 ); } + { + mock::detail::function< void( int, std::string ) > f; + f.expect(); + f( 1, "s1" ); + f( 2, "s2" ); + CHECK_CALLS( 2 ); + } { mock::detail::function< void( int, const std::string& ) > f; f.expect(); - f( 1, "s" ); - f( 1, "s" ); + f( 1, "s1" ); + f( 2, "s2" ); + CHECK_CALLS( 2 ); + } +} + +BOOST_FIXTURE_TEST_CASE( triggering_several_once_expectations_is_valid, mock_error_fixture ) +{ + { + mock::detail::function< void() > f; + f.expect().once(); + f.expect().once(); + f(); + f(); + CHECK_CALLS( 2 ); + } + { + mock::detail::function< void( int, std::string ) > f; + f.expect().once().with( 1, "s1" ); + f.expect().once().with( 2, "s2" ); + f( 1, "s1" ); + f( 2, "s2" ); + CHECK_CALLS( 2 ); + } + { + mock::detail::function< void( int, const std::string& ) > f; + f.expect().once().with( 1, "s1" ); + f.expect().once().with( 2, "s2" ); + f( 1, "s1" ); + f( 2, "s2" ); CHECK_CALLS( 2 ); } } diff --git a/test/test_integration.cpp b/test/test_integration.cpp index e3bef9e..7636e47 100644 --- a/test/test_integration.cpp +++ b/test/test_integration.cpp @@ -754,6 +754,19 @@ BOOST_FIXTURE_TEST_CASE( std_unique_ptr_argument_is_supported_in_retrieve_constr BOOST_CHECK_EQUAL( 7, *i ); CHECK_CALLS( 1 ); } + { + std::unique_ptr< int > i; + MOCK_FUNCTOR( f, void( std::unique_ptr< int > ) ); + MOCK_EXPECT( f ).once().with( nullptr ); + MOCK_EXPECT( f ).once().with( mock::retrieve( i ) ); + f( 0 ); + std::unique_ptr< int > j( new int( 7 ) ); + f( std::move( j ) ); + BOOST_CHECK( !j ); + BOOST_REQUIRE( i ); + BOOST_CHECK_EQUAL( 7, *i ); + CHECK_CALLS( 2 ); + } } #endif