Skip to content

Commit

Permalink
Googletest export
Browse files Browse the repository at this point in the history
Addressing #2502

Add MOCK_METHOD support for returning function pointers.

PiperOrigin-RevId: 275323671
  • Loading branch information
Abseil Team authored and Andy Soffer committed Oct 18, 2019
1 parent bbe4b73 commit 1f9edcd
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 4 deletions.
29 changes: 25 additions & 4 deletions googlemock/include/gmock/gmock-function-mocker.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
#include "gmock/gmock-generated-function-mockers.h" // NOLINT
#include "gmock/internal/gmock-pp.h"

namespace testing {
namespace internal {
template <typename T>
using identity_t = T;
} // namespace internal
} // namespace testing

#define MOCK_METHOD(...) \
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)

Expand Down Expand Up @@ -207,10 +214,24 @@

#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype

#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
GMOCK_PP_IDENTITY) \
(_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
// Note: The use of `identity_t` here allows _Ret to represent return types that
// would normally need to be specified in a different way. For example, a method
// returning a function pointer must be written as
//
// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...)
//
// But we only support placing the return type at the beginning. To handle this,
// we wrap all calls in identity_t, so that a declaration will be expanded to
//
// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...)
//
// This allows us to work around the syntactic oddities of function/method
// types.
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \
GMOCK_PP_REMOVE_PARENS, \
GMOCK_PP_IDENTITY)(_Ret)>( \
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))

#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
GMOCK_PP_COMMA_IF(_i) \
Expand Down
7 changes: 7 additions & 0 deletions googlemock/test/gmock-function-mocker_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ class FooInterface {
virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;

virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
using fn_ptr = int (*)(bool);
virtual fn_ptr ReturnsFunctionPointer2(int) = 0;

#if GTEST_OS_WINDOWS
STDMETHOD_(int, CTNullary)() = 0;
STDMETHOD_(bool, CTUnary)(int x) = 0;
Expand Down Expand Up @@ -159,6 +163,9 @@ class MockFoo : public FooInterface {
MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
(const TemplatedCopyable<int>&)); // NOLINT

MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());

#if GTEST_OS_WINDOWS
MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
Expand Down

0 comments on commit 1f9edcd

Please sign in to comment.