]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | $$ -*- mode: c++; -*- |
2 | $$ This is a Pump source file. Please use Pump to convert it to | |
3 | $$ gmock-generated-function-mockers.h. | |
4 | $$ | |
5 | $var n = 10 $$ The maximum arity we support. | |
6 | // Copyright 2007, Google Inc. | |
7 | // All rights reserved. | |
8 | // | |
9 | // Redistribution and use in source and binary forms, with or without | |
10 | // modification, are permitted provided that the following conditions are | |
11 | // met: | |
12 | // | |
13 | // * Redistributions of source code must retain the above copyright | |
14 | // notice, this list of conditions and the following disclaimer. | |
15 | // * Redistributions in binary form must reproduce the above | |
16 | // copyright notice, this list of conditions and the following disclaimer | |
17 | // in the documentation and/or other materials provided with the | |
18 | // distribution. | |
19 | // * Neither the name of Google Inc. nor the names of its | |
20 | // contributors may be used to endorse or promote products derived from | |
21 | // this software without specific prior written permission. | |
22 | // | |
23 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
24 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
25 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
26 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
27 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
28 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
29 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
30 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
31 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
32 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
33 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 | // | |
35 | // Author: wan@google.com (Zhanyong Wan) | |
36 | ||
37 | // Google Mock - a framework for writing C++ mock classes. | |
38 | // | |
39 | // This file implements function mockers of various arities. | |
40 | ||
41 | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ | |
42 | #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ | |
43 | ||
44 | #include "gmock/gmock-spec-builders.h" | |
45 | #include "gmock/internal/gmock-internal-utils.h" | |
46 | ||
47 | #if GTEST_HAS_STD_FUNCTION_ | |
48 | # include <functional> | |
49 | #endif | |
50 | ||
51 | namespace testing { | |
52 | namespace internal { | |
53 | ||
54 | template <typename F> | |
55 | class FunctionMockerBase; | |
56 | ||
57 | // Note: class FunctionMocker really belongs to the ::testing | |
58 | // namespace. However if we define it in ::testing, MSVC will | |
59 | // complain when classes in ::testing::internal declare it as a | |
60 | // friend class template. To workaround this compiler bug, we define | |
61 | // FunctionMocker in ::testing::internal and import it into ::testing. | |
62 | template <typename F> | |
63 | class FunctionMocker; | |
64 | ||
65 | ||
66 | $range i 0..n | |
67 | $for i [[ | |
68 | $range j 1..i | |
69 | $var typename_As = [[$for j [[, typename A$j]]]] | |
70 | $var As = [[$for j, [[A$j]]]] | |
71 | $var as = [[$for j, [[a$j]]]] | |
72 | $var Aas = [[$for j, [[A$j a$j]]]] | |
73 | $var ms = [[$for j, [[m$j]]]] | |
74 | $var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]] | |
75 | template <typename R$typename_As> | |
76 | class FunctionMocker<R($As)> : public | |
77 | internal::FunctionMockerBase<R($As)> { | |
78 | public: | |
79 | typedef R F($As); | |
80 | typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | |
81 | ||
82 | MockSpec<F>& With($matchers) { | |
83 | ||
84 | $if i >= 1 [[ | |
85 | this->current_spec().SetMatchers(::testing::make_tuple($ms)); | |
86 | ||
87 | ]] | |
88 | return this->current_spec(); | |
89 | } | |
90 | ||
91 | R Invoke($Aas) { | |
92 | // Even though gcc and MSVC don't enforce it, 'this->' is required | |
93 | // by the C++ standard [14.6.4] here, as the base class type is | |
94 | // dependent on the template argument (and thus shouldn't be | |
95 | // looked into when resolving InvokeWith). | |
96 | return this->InvokeWith(ArgumentTuple($as)); | |
97 | } | |
98 | }; | |
99 | ||
100 | ||
101 | ]] | |
102 | } // namespace internal | |
103 | ||
104 | // The style guide prohibits "using" statements in a namespace scope | |
105 | // inside a header file. However, the FunctionMocker class template | |
106 | // is meant to be defined in the ::testing namespace. The following | |
107 | // line is just a trick for working around a bug in MSVC 8.0, which | |
108 | // cannot handle it if we define FunctionMocker in ::testing. | |
109 | using internal::FunctionMocker; | |
110 | ||
111 | // GMOCK_RESULT_(tn, F) expands to the result type of function type F. | |
112 | // We define this as a variadic macro in case F contains unprotected | |
113 | // commas (the same reason that we use variadic macros in other places | |
114 | // in this file). | |
115 | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | |
116 | #define GMOCK_RESULT_(tn, ...) \ | |
117 | tn ::testing::internal::Function<__VA_ARGS__>::Result | |
118 | ||
119 | // The type of argument N of the given function type. | |
120 | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | |
121 | #define GMOCK_ARG_(tn, N, ...) \ | |
122 | tn ::testing::internal::Function<__VA_ARGS__>::Argument##N | |
123 | ||
124 | // The matcher type for argument N of the given function type. | |
125 | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | |
126 | #define GMOCK_MATCHER_(tn, N, ...) \ | |
127 | const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>& | |
128 | ||
129 | // The variable for mocking the given method. | |
130 | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | |
131 | #define GMOCK_MOCKER_(arity, constness, Method) \ | |
132 | GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) | |
133 | ||
134 | ||
135 | $for i [[ | |
136 | $range j 1..i | |
137 | $var arg_as = [[$for j, \ | |
138 | [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] | |
139 | $var as = [[$for j, [[gmock_a$j]]]] | |
140 | $var matcher_as = [[$for j, \ | |
141 | [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] | |
142 | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | |
143 | #define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ | |
144 | GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ | |
145 | $arg_as) constness { \ | |
146 | GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ | |
147 | tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \ | |
148 | this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \ | |
149 | GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ | |
150 | return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ | |
151 | } \ | |
152 | ::testing::MockSpec<__VA_ARGS__>& \ | |
153 | gmock_##Method($matcher_as) constness { \ | |
154 | GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ | |
155 | return GMOCK_MOCKER_($i, constness, Method).With($as); \ | |
156 | } \ | |
157 | mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) | |
158 | ||
159 | ||
160 | ]] | |
161 | $for i [[ | |
162 | #define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) | |
163 | ||
164 | ]] | |
165 | ||
166 | ||
167 | $for i [[ | |
168 | #define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) | |
169 | ||
170 | ]] | |
171 | ||
172 | ||
173 | $for i [[ | |
174 | #define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) | |
175 | ||
176 | ]] | |
177 | ||
178 | ||
179 | $for i [[ | |
180 | #define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ | |
181 | GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) | |
182 | ||
183 | ]] | |
184 | ||
185 | ||
186 | $for i [[ | |
187 | #define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ | |
188 | GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) | |
189 | ||
190 | ]] | |
191 | ||
192 | ||
193 | $for i [[ | |
194 | #define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ | |
195 | GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) | |
196 | ||
197 | ]] | |
198 | ||
199 | ||
200 | $for i [[ | |
201 | #define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ | |
202 | GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) | |
203 | ||
204 | ]] | |
205 | ||
206 | ||
207 | $for i [[ | |
208 | #define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ | |
209 | GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) | |
210 | ||
211 | ]] | |
212 | ||
213 | // A MockFunction<F> class has one mock method whose type is F. It is | |
214 | // useful when you just want your test code to emit some messages and | |
215 | // have Google Mock verify the right messages are sent (and perhaps at | |
216 | // the right times). For example, if you are exercising code: | |
217 | // | |
218 | // Foo(1); | |
219 | // Foo(2); | |
220 | // Foo(3); | |
221 | // | |
222 | // and want to verify that Foo(1) and Foo(3) both invoke | |
223 | // mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: | |
224 | // | |
225 | // TEST(FooTest, InvokesBarCorrectly) { | |
226 | // MyMock mock; | |
227 | // MockFunction<void(string check_point_name)> check; | |
228 | // { | |
229 | // InSequence s; | |
230 | // | |
231 | // EXPECT_CALL(mock, Bar("a")); | |
232 | // EXPECT_CALL(check, Call("1")); | |
233 | // EXPECT_CALL(check, Call("2")); | |
234 | // EXPECT_CALL(mock, Bar("a")); | |
235 | // } | |
236 | // Foo(1); | |
237 | // check.Call("1"); | |
238 | // Foo(2); | |
239 | // check.Call("2"); | |
240 | // Foo(3); | |
241 | // } | |
242 | // | |
243 | // The expectation spec says that the first Bar("a") must happen | |
244 | // before check point "1", the second Bar("a") must happen after check | |
245 | // point "2", and nothing should happen between the two check | |
246 | // points. The explicit check points make it easy to tell which | |
247 | // Bar("a") is called by which call to Foo(). | |
248 | // | |
249 | // MockFunction<F> can also be used to exercise code that accepts | |
250 | // std::function<F> callbacks. To do so, use AsStdFunction() method | |
251 | // to create std::function proxy forwarding to original object's Call. | |
252 | // Example: | |
253 | // | |
254 | // TEST(FooTest, RunsCallbackWithBarArgument) { | |
255 | // MockFunction<int(string)> callback; | |
256 | // EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); | |
257 | // Foo(callback.AsStdFunction()); | |
258 | // } | |
259 | template <typename F> | |
260 | class MockFunction; | |
261 | ||
262 | ||
263 | $for i [[ | |
264 | $range j 0..i-1 | |
265 | $var ArgTypes = [[$for j, [[A$j]]]] | |
266 | $var ArgNames = [[$for j, [[a$j]]]] | |
267 | $var ArgDecls = [[$for j, [[A$j a$j]]]] | |
268 | template <typename R$for j [[, typename A$j]]> | |
269 | class MockFunction<R($ArgTypes)> { | |
270 | public: | |
271 | MockFunction() {} | |
272 | ||
273 | MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); | |
274 | ||
275 | #if GTEST_HAS_STD_FUNCTION_ | |
276 | std::function<R($ArgTypes)> AsStdFunction() { | |
277 | return [this]($ArgDecls) -> R { | |
278 | return this->Call($ArgNames); | |
279 | }; | |
280 | } | |
281 | #endif // GTEST_HAS_STD_FUNCTION_ | |
282 | ||
283 | private: | |
284 | GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); | |
285 | }; | |
286 | ||
287 | ||
288 | ]] | |
289 | } // namespace testing | |
290 | ||
291 | #endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ |