• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(                                  \
50       GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple),        \
51       GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.")
52 
53 #define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...)                 \
54   static_assert(                                                       \
55       std::is_function<__VA_ARGS__>::value,                            \
56       "Signature must be a function type, maybe return type contains " \
57       "unprotected comma.");                                           \
58   static_assert(                                                       \
59       ::testing::tuple_size<typename ::testing::internal::Function<    \
60               __VA_ARGS__>::ArgumentTuple>::value == _N,               \
61       "This method does not take " GMOCK_PP_STRINGIZE(                 \
62           _N) " arguments. Parenthesize all types with unproctected commas.")
63 
64 #define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
65   GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
66 
67 #define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness,           \
68                                         _Override, _Final, _Noexcept,          \
69                                         _CallType, _Signature)                 \
70   typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS(               \
71       _Signature)>::Result                                                     \
72   GMOCK_INTERNAL_EXPAND(_CallType)                                             \
73       _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N))   \
74           GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, )  \
75               GMOCK_PP_IF(_Override, override, )                               \
76                   GMOCK_PP_IF(_Final, final, ) {                               \
77     GMOCK_MOCKER_(_N, _Constness, _MethodName)                                 \
78         .SetOwnerAndName(this, #_MethodName);                                  \
79     return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \
80         .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N));  \
81   }                                                                            \
82   ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
83       GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N))       \
84       GMOCK_PP_IF(_Constness, const, ) {                                       \
85     GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this);            \
86     return GMOCK_MOCKER_(_N, _Constness, _MethodName)                          \
87         .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N));         \
88   }                                                                            \
89   ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
90       const ::testing::internal::WithoutMatchers&,                             \
91       GMOCK_PP_IF(_Constness, const, )::testing::internal::Function<           \
92           GMOCK_PP_REMOVE_PARENS(_Signature)>*)                                \
93       const GMOCK_PP_IF(_Noexcept, noexcept, ) {                               \
94     return GMOCK_PP_CAT(::testing::internal::AdjustConstness_,                 \
95                         GMOCK_PP_IF(_Constness, const, ))(this)                \
96         ->gmock_##_MethodName(GMOCK_PP_REPEAT(                                 \
97             GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N));               \
98   }                                                                            \
99   mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)>        \
100       GMOCK_MOCKER_(_N, _Constness, _MethodName)
101 
102 #define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
103 
104 // Five Valid modifiers.
105 #define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
106   GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
107 
108 #define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \
109   GMOCK_PP_HAS_COMMA(                       \
110       GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))
111 
112 #define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
113   GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
114 
115 #define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \
116   GMOCK_PP_HAS_COMMA(                       \
117       GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
118 
119 #define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
120   GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
121 
122 #define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem)            \
123   static_assert(                                                          \
124       (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) +    \
125        GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
126        GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) +    \
127        GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
128        GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1,                           \
129       GMOCK_PP_STRINGIZE(                                                 \
130           _elem) " cannot be recognized as a valid specification modifier.");
131 
132 // Modifiers implementation.
133 #define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
134   GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)
135 
136 #define GMOCK_INTERNAL_DETECT_CONST_I_const ,
137 
138 #define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \
139   GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)
140 
141 #define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,
142 
143 #define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \
144   GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)
145 
146 #define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
147 
148 // TODO(iserna): Maybe noexcept should accept an argument here as well.
149 #define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
150   GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
151 
152 #define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
153 
154 #define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem)           \
155   GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem),                 \
156               GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
157   (_elem)
158 
159 // TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
160 // GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
161 // maybe they can be simplified somehow.
162 #define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
163   GMOCK_INTERNAL_IS_CALLTYPE_I(          \
164       GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
165 #define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
166 
167 #define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
168   GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(          \
169       GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
170 #define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
171   GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg)
172 
173 #define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
174 
175 #define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)                         \
176   GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
177               GMOCK_PP_IDENTITY)                                      \
178   (_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
179 
180 #define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem)                          \
181   GMOCK_PP_COMMA_IF(_i)                                                \
182   GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \
183               GMOCK_PP_IDENTITY)                                       \
184   (_elem)
185 
186 #define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _)        \
187   GMOCK_PP_COMMA_IF(_i)                                    \
188   GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i),         \
189                        GMOCK_PP_REMOVE_PARENS(_Signature)) \
190   gmock_a##_i
191 
192 #define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _)                       \
193   GMOCK_PP_COMMA_IF(_i)                                                     \
194   ::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i),           \
195                                       GMOCK_PP_REMOVE_PARENS(_Signature))>( \
196       gmock_a##_i)
197 
198 #define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _)    \
199   GMOCK_PP_COMMA_IF(_i)                                        \
200   GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i),         \
201                            GMOCK_PP_REMOVE_PARENS(_Signature)) \
202   gmock_a##_i
203 
204 #define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
205   GMOCK_PP_COMMA_IF(_i)                             \
206   gmock_a##_i
207 
208 #define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _)    \
209   GMOCK_PP_COMMA_IF(_i)                                         \
210   ::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
211                                     GMOCK_PP_REMOVE_PARENS(_Signature))>()
212 
213 #define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
214 
215 #define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
216   GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
217 
218 #endif  // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
219