1$$ -*- mode: c++; -*-
2$$ This is a Pump source file.  Please use Pump to convert
3$$ it to 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
36// Google Mock - a framework for writing C++ mock classes.
37//
38// This file implements function mockers of various arities.
39
40// GOOGLETEST_CM0002 DO NOT DELETE
41
42#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
43#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
44
45#include "gmock/gmock-spec-builders.h"
46#include "gmock/internal/gmock-internal-utils.h"
47
48#if GTEST_HAS_STD_FUNCTION_
49# include <functional>
50#endif
51
52namespace testing {
53namespace internal {
54
55template <typename F>
56class FunctionMockerBase;
57
58// Note: class FunctionMocker really belongs to the ::testing
59// namespace.  However if we define it in ::testing, MSVC will
60// complain when classes in ::testing::internal declare it as a
61// friend class template.  To workaround this compiler bug, we define
62// FunctionMocker in ::testing::internal and import it into ::testing.
63template <typename F>
64class FunctionMocker;
65
66
67$range i 0..n
68$for i [[
69$range j 1..i
70$var typename_As = [[$for j [[, typename A$j]]]]
71$var As = [[$for j, [[A$j]]]]
72$var as = [[$for j, [[internal::forward<A$j>(a$j)]]]]
73$var Aas = [[$for j, [[A$j a$j]]]]
74$var ms = [[$for j, [[m$j]]]]
75$var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]]
76template <typename R$typename_As>
77class FunctionMocker<R($As)> : public
78    internal::FunctionMockerBase<R($As)> {
79 public:
80  typedef R F($As);
81  typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
82
83  MockSpec<F> With($matchers) {
84    return MockSpec<F>(this, ::testing::make_tuple($ms));
85  }
86
87  R Invoke($Aas) {
88    // Even though gcc and MSVC don't enforce it, 'this->' is required
89    // by the C++ standard [14.6.4] here, as the base class type is
90    // dependent on the template argument (and thus shouldn't be
91    // looked into when resolving InvokeWith).
92    return this->InvokeWith(ArgumentTuple($as));
93  }
94};
95
96
97]]
98// Removes the given pointer; this is a helper for the expectation setter method
99// for parameterless matchers.
100//
101// We want to make sure that the user cannot set a parameterless expectation on
102// overloaded methods, including methods which are overloaded on const. Example:
103//
104//   class MockClass {
105//     MOCK_METHOD0(GetName, string&());
106//     MOCK_CONST_METHOD0(GetName, const string&());
107//   };
108//
109//   TEST() {
110//     // This should be an error, as it's not clear which overload is expected.
111//     EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
112//   }
113//
114// Here are the generated expectation-setter methods:
115//
116//   class MockClass {
117//     // Overload 1
118//     MockSpec<string&()> gmock_GetName() { ... }
119//     // Overload 2. Declared const so that the compiler will generate an
120//     // error when trying to resolve between this and overload 4 in
121//     // 'gmock_GetName(WithoutMatchers(), nullptr)'.
122//     MockSpec<string&()> gmock_GetName(
123//         const WithoutMatchers&, const Function<string&()>*) const {
124//       // Removes const from this, calls overload 1
125//       return AdjustConstness_(this)->gmock_GetName();
126//     }
127//
128//     // Overload 3
129//     const string& gmock_GetName() const { ... }
130//     // Overload 4
131//     MockSpec<const string&()> gmock_GetName(
132//         const WithoutMatchers&, const Function<const string&()>*) const {
133//       // Does not remove const, calls overload 3
134//       return AdjustConstness_const(this)->gmock_GetName();
135//     }
136//   }
137//
138template <typename MockType>
139const MockType* AdjustConstness_const(const MockType* mock) {
140  return mock;
141}
142
143// Removes const from and returns the given pointer; this is a helper for the
144// expectation setter method for parameterless matchers.
145template <typename MockType>
146MockType* AdjustConstness_(const MockType* mock) {
147  return const_cast<MockType*>(mock);
148}
149
150}  // namespace internal
151
152// The style guide prohibits "using" statements in a namespace scope
153// inside a header file.  However, the FunctionMocker class template
154// is meant to be defined in the ::testing namespace.  The following
155// line is just a trick for working around a bug in MSVC 8.0, which
156// cannot handle it if we define FunctionMocker in ::testing.
157using internal::FunctionMocker;
158
159// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
160// We define this as a variadic macro in case F contains unprotected
161// commas (the same reason that we use variadic macros in other places
162// in this file).
163// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
164#define GMOCK_RESULT_(tn, ...) \
165    tn ::testing::internal::Function<__VA_ARGS__>::Result
166
167// The type of argument N of the given function type.
168// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
169#define GMOCK_ARG_(tn, N, ...) \
170    tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
171
172// The matcher type for argument N of the given function type.
173// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
174#define GMOCK_MATCHER_(tn, N, ...) \
175    const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
176
177// The variable for mocking the given method.
178// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
179#define GMOCK_MOCKER_(arity, constness, Method) \
180    GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
181
182
183$for i [[
184$range j 1..i
185$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
186$var as = [[$for j, \
187  [[::testing::internal::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]]
188$var matcher_arg_as = [[$for j, \
189                     [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
190$var matcher_as = [[$for j, [[gmock_a$j]]]]
191$var anything_matchers = [[$for j, \
192                     [[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]]
193// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
194#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
195  GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
196      $arg_as) constness { \
197    GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \
198        tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
199        this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
200    GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
201    return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
202  } \
203  ::testing::MockSpec<__VA_ARGS__> \
204      gmock_##Method($matcher_arg_as) constness { \
205    GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
206    return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \
207  } \
208  ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
209      const ::testing::internal::WithoutMatchers&, \
210      constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
211        return ::testing::internal::AdjustConstness_##constness(this)-> \
212            gmock_##Method($anything_matchers); \
213      } \
214  mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
215
216
217]]
218$for i [[
219#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
220
221]]
222
223
224$for i [[
225#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
226
227]]
228
229
230$for i [[
231#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
232
233]]
234
235
236$for i [[
237#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
238    GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
239
240]]
241
242
243$for i [[
244#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
245    GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
246
247]]
248
249
250$for i [[
251#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
252    GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
253
254]]
255
256
257$for i [[
258#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
259    GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
260
261]]
262
263
264$for i [[
265#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
266    GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
267
268]]
269
270// A MockFunction<F> class has one mock method whose type is F.  It is
271// useful when you just want your test code to emit some messages and
272// have Google Mock verify the right messages are sent (and perhaps at
273// the right times).  For example, if you are exercising code:
274//
275//   Foo(1);
276//   Foo(2);
277//   Foo(3);
278//
279// and want to verify that Foo(1) and Foo(3) both invoke
280// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
281//
282// TEST(FooTest, InvokesBarCorrectly) {
283//   MyMock mock;
284//   MockFunction<void(string check_point_name)> check;
285//   {
286//     InSequence s;
287//
288//     EXPECT_CALL(mock, Bar("a"));
289//     EXPECT_CALL(check, Call("1"));
290//     EXPECT_CALL(check, Call("2"));
291//     EXPECT_CALL(mock, Bar("a"));
292//   }
293//   Foo(1);
294//   check.Call("1");
295//   Foo(2);
296//   check.Call("2");
297//   Foo(3);
298// }
299//
300// The expectation spec says that the first Bar("a") must happen
301// before check point "1", the second Bar("a") must happen after check
302// point "2", and nothing should happen between the two check
303// points. The explicit check points make it easy to tell which
304// Bar("a") is called by which call to Foo().
305//
306// MockFunction<F> can also be used to exercise code that accepts
307// std::function<F> callbacks. To do so, use AsStdFunction() method
308// to create std::function proxy forwarding to original object's Call.
309// Example:
310//
311// TEST(FooTest, RunsCallbackWithBarArgument) {
312//   MockFunction<int(string)> callback;
313//   EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
314//   Foo(callback.AsStdFunction());
315// }
316template <typename F>
317class MockFunction;
318
319
320$for i [[
321$range j 0..i-1
322$var ArgTypes = [[$for j, [[A$j]]]]
323$var ArgValues = [[$for j, [[::std::move(a$j)]]]]
324$var ArgDecls = [[$for j, [[A$j a$j]]]]
325template <typename R$for j [[, typename A$j]]>
326class MockFunction<R($ArgTypes)> {
327 public:
328  MockFunction() {}
329
330  MOCK_METHOD$i[[]]_T(Call, R($ArgTypes));
331
332#if GTEST_HAS_STD_FUNCTION_
333  ::std::function<R($ArgTypes)> AsStdFunction() {
334    return [this]($ArgDecls) -> R {
335      return this->Call($ArgValues);
336    };
337  }
338#endif  // GTEST_HAS_STD_FUNCTION_
339
340 private:
341  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
342};
343
344
345]]
346}  // namespace testing
347
348#endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
349