Skip to content

Commit c5f08bf

Browse files
Abseil Teamgennadiycivil
Abseil Team
authored andcommitted
Googletest export
One macro to rule them all. PiperOrigin-RevId: 221462515
1 parent d593250 commit c5f08bf

File tree

7 files changed

+1302
-0
lines changed

7 files changed

+1302
-0
lines changed

googlemock/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ $env:Path = \"$project_bin;$env:Path\"
153153
cxx_test(gmock-actions_test gmock_main)
154154
cxx_test(gmock-cardinalities_test gmock_main)
155155
cxx_test(gmock_ex_test gmock_main)
156+
cxx_test(gmock-function-mocker_test gmock_main)
156157
cxx_test(gmock-generated-actions_test gmock_main)
157158
cxx_test(gmock-generated-function-mockers_test gmock_main)
158159
cxx_test(gmock-generated-internal-utils_test gmock_main)

googlemock/Makefile.am

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ lib_libgmock_la_SOURCES = src/gmock-all.cc
2828
pkginclude_HEADERS = \
2929
include/gmock/gmock-actions.h \
3030
include/gmock/gmock-cardinalities.h \
31+
include/gmock/gmock-function-mocker.h \
3132
include/gmock/gmock-generated-actions.h \
3233
include/gmock/gmock-generated-function-mockers.h \
3334
include/gmock/gmock-generated-matchers.h \
@@ -43,6 +44,7 @@ pkginclude_internal_HEADERS = \
4344
include/gmock/internal/gmock-generated-internal-utils.h \
4445
include/gmock/internal/gmock-internal-utils.h \
4546
include/gmock/internal/gmock-port.h \
47+
include/gmock/internal/gmock-pp.h \
4648
include/gmock/internal/custom/gmock-generated-actions.h \
4749
include/gmock/internal/custom/gmock-matchers.h \
4850
include/gmock/internal/custom/gmock-port.h
@@ -107,6 +109,7 @@ EXTRA_DIST += \
107109
test/gmock-cardinalities_test.cc \
108110
test/gmock_ex_test.cc \
109111
test/gmock-generated-actions_test.cc \
112+
test/gmock-function-mocker_test.cc \
110113
test/gmock-generated-function-mockers_test.cc \
111114
test/gmock-generated-internal-utils_test.cc \
112115
test/gmock-generated-matchers_test.cc \
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
2+
#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
3+
4+
#include "gmock/gmock-generated-function-mockers.h" // NOLINT
5+
#include "gmock/internal/gmock-pp.h"
6+
7+
#define MOCK_METHOD(...) \
8+
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
9+
10+
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
11+
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
12+
13+
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \
14+
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
15+
16+
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
17+
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
18+
19+
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
20+
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
21+
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
22+
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
23+
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
24+
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec); \
25+
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
26+
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
27+
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
28+
GMOCK_INTERNAL_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \
29+
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
30+
31+
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
32+
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
33+
34+
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \
35+
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
36+
37+
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \
38+
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
39+
40+
#define GMOCK_INTERNAL_WRONG_ARITY(...) \
41+
static_assert( \
42+
false, \
43+
"MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \
44+
"_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \
45+
"enclosed in parentheses. If _Ret is a type with unprotected commas, " \
46+
"it must also be enclosed in parentheses.")
47+
48+
#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \
49+
static_assert(GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \
50+
"_Tuple should be enclosed in parentheses")
51+
52+
#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \
53+
static_assert( \
54+
std::is_function<__VA_ARGS__>::value, \
55+
"Signature must be a function type, maybe return type contains " \
56+
"unprotected comma."); \
57+
static_assert( \
58+
::testing::tuple_size<typename ::testing::internal::Function< \
59+
__VA_ARGS__>::ArgumentTuple>::value == _N, \
60+
"This method does not take " GMOCK_PP_STRINGIZE( \
61+
_N) " arguments. Parenthesize all types with unproctected commas.")
62+
63+
// TODO(iserna): Verify each element in spec is one of the allowed.
64+
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) static_assert(true, "");
65+
66+
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
67+
_Override, _Final, _Noexcept, \
68+
_CallType, _Signature) \
69+
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
70+
_Signature)>::Result \
71+
GMOCK_INTERNAL_EXPAND(_CallType) \
72+
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
73+
GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \
74+
GMOCK_PP_IF(_Override, override, ) \
75+
GMOCK_PP_IF(_Final, final, ) { \
76+
GMOCK_MOCKER_(_N, _Constness, _MethodName) \
77+
.SetOwnerAndName(this, #_MethodName); \
78+
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
79+
.Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
80+
} \
81+
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
82+
GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \
83+
GMOCK_PP_IF(_Constness, const, ) { \
84+
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
85+
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
86+
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
87+
} \
88+
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
89+
const ::testing::internal::WithoutMatchers&, \
90+
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
91+
GMOCK_PP_REMOVE_PARENS(_Signature)>*) \
92+
const GMOCK_PP_IF(_Noexcept, noexcept, ) { \
93+
return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \
94+
GMOCK_PP_IF(_Constness, const, ))(this) \
95+
->gmock_##_MethodName(GMOCK_PP_REPEAT( \
96+
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
97+
} \
98+
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
99+
GMOCK_MOCKER_(_N, _Constness, _MethodName)
100+
101+
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
102+
103+
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
104+
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
105+
106+
#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \
107+
GMOCK_PP_HAS_COMMA( \
108+
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))
109+
110+
#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
111+
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
112+
113+
#define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \
114+
GMOCK_PP_HAS_COMMA( \
115+
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
116+
117+
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
118+
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
119+
120+
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
121+
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)
122+
123+
#define GMOCK_INTERNAL_DETECT_CONST_I_const ,
124+
125+
#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \
126+
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)
127+
128+
#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,
129+
130+
#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \
131+
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)
132+
133+
#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
134+
135+
// TODO(iserna): Maybe noexcept should accept an argument here as well.
136+
#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
137+
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
138+
139+
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
140+
141+
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
142+
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
143+
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
144+
(_elem)
145+
146+
// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
147+
// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
148+
// maybe they can be simplified somehow.
149+
#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
150+
GMOCK_INTERNAL_IS_CALLTYPE_I( \
151+
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
152+
#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
153+
154+
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
155+
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
156+
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
157+
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
158+
GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg)
159+
160+
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
161+
162+
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
163+
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
164+
GMOCK_PP_IDENTITY) \
165+
(_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
166+
167+
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
168+
GMOCK_PP_COMMA_IF(_i) \
169+
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \
170+
GMOCK_PP_IDENTITY) \
171+
(_elem)
172+
173+
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
174+
GMOCK_PP_COMMA_IF(_i) \
175+
GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
176+
GMOCK_PP_REMOVE_PARENS(_Signature)) \
177+
gmock_a##_i
178+
179+
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
180+
GMOCK_PP_COMMA_IF(_i) \
181+
::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
182+
GMOCK_PP_REMOVE_PARENS(_Signature))>( \
183+
gmock_a##_i)
184+
185+
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
186+
GMOCK_PP_COMMA_IF(_i) \
187+
GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \
188+
GMOCK_PP_REMOVE_PARENS(_Signature)) \
189+
gmock_a##_i
190+
191+
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
192+
GMOCK_PP_COMMA_IF(_i) \
193+
gmock_a##_i
194+
195+
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
196+
GMOCK_PP_COMMA_IF(_i) \
197+
::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
198+
GMOCK_PP_REMOVE_PARENS(_Signature))>()
199+
200+
#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
201+
202+
#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
203+
GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
204+
205+
#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_

googlemock/include/gmock/gmock.h

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
#include "gmock/gmock-actions.h"
6060
#include "gmock/gmock-cardinalities.h"
61+
#include "gmock/gmock-function-mocker.h"
6162
#include "gmock/gmock-generated-actions.h"
6263
#include "gmock/gmock-generated-function-mockers.h"
6364
#include "gmock/gmock-generated-matchers.h"

0 commit comments

Comments
 (0)