blob: efcb3e8cefd8091c991444e962a316d2852939c2 [file] [log] [blame]
shiqiane35fdd92008-12-10 05:08:54 +00001$$ -*- mode: c++; -*-
Gennadiy Civilfe402c22018-04-05 16:09:17 -04002$$ This is a Pump source file. Please use Pump to convert
3$$ it to gmock-generated-function-mockers.h.
shiqiane35fdd92008-12-10 05:08:54 +00004$$
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
zhanyong.wan53e08c42010-09-14 05:38:21 +000044#include "gmock/gmock-spec-builders.h"
45#include "gmock/internal/gmock-internal-utils.h"
shiqiane35fdd92008-12-10 05:08:54 +000046
kosak389bad62014-11-17 01:08:51 +000047#if GTEST_HAS_STD_FUNCTION_
48# include <functional>
49#endif
50
shiqiane35fdd92008-12-10 05:08:54 +000051namespace testing {
shiqiane35fdd92008-12-10 05:08:54 +000052namespace internal {
53
54template <typename F>
55class 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.
62template <typename F>
63class 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]]]]
Gennadiy Civilfa658e02018-04-12 13:42:47 -040071$var as = [[$for j, [[internal::forward<A$j>(a$j)]]]]
shiqiane35fdd92008-12-10 05:08:54 +000072$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]]]]
75template <typename R$typename_As>
76class 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
Gennadiy Civilfa658e02018-04-12 13:42:47 -040082 MockSpec<F> With($matchers) {
83 return MockSpec<F>(this, ::testing::make_tuple($ms));
shiqiane35fdd92008-12-10 05:08:54 +000084 }
85
86 R Invoke($Aas) {
zhanyong.wan21a58462009-11-12 19:18:08 +000087 // Even though gcc and MSVC don't enforce it, 'this->' is required
88 // by the C++ standard [14.6.4] here, as the base class type is
89 // dependent on the template argument (and thus shouldn't be
90 // looked into when resolving InvokeWith).
91 return this->InvokeWith(ArgumentTuple($as));
shiqiane35fdd92008-12-10 05:08:54 +000092 }
93};
94
95
96]]
Gennadiy Civilb5391672018-04-25 13:10:41 -040097// Removes the given pointer; this is a helper for the expectation setter method
98// for parameterless matchers.
99//
100// We want to make sure that the user cannot set a parameterless expectation on
101// overloaded methods, including methods which are overloaded on const. Example:
102//
103// class MockClass {
104// MOCK_METHOD0(GetName, string&());
105// MOCK_CONST_METHOD0(GetName, const string&());
106// };
107//
108// TEST() {
109// // This should be an error, as it's not clear which overload is expected.
110// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
111// }
112//
113// Here are the generated expectation-setter methods:
114//
115// class MockClass {
116// // Overload 1
117// MockSpec<string&()> gmock_GetName() { … }
118// // Overload 2. Declared const so that the compiler will generate an
119// // error when trying to resolve between this and overload 4 in
120// // 'gmock_GetName(WithoutMatchers(), nullptr)'.
121// MockSpec<string&()> gmock_GetName(
122// const WithoutMatchers&, const Function<string&()>*) const {
123// // Removes const from this, calls overload 1
124// return AdjustConstness_(this)->gmock_GetName();
125// }
126//
127// // Overload 3
128// const string& gmock_GetName() const { … }
129// // Overload 4
130// MockSpec<const string&()> gmock_GetName(
131// const WithoutMatchers&, const Function<const string&()>*) const {
132// // Does not remove const, calls overload 3
133// return AdjustConstness_const(this)->gmock_GetName();
134// }
135// }
136//
137template <typename MockType>
138const MockType* AdjustConstness_const(const MockType* mock) {
139 return mock;
140}
141
142// Removes const from and returns the given pointer; this is a helper for the
143// expectation setter method for parameterless matchers.
144template <typename MockType>
145MockType* AdjustConstness_(const MockType* mock) {
146 return const_cast<MockType*>(mock);
147}
148
shiqiane35fdd92008-12-10 05:08:54 +0000149} // namespace internal
150
151// The style guide prohibits "using" statements in a namespace scope
152// inside a header file. However, the FunctionMocker class template
153// is meant to be defined in the ::testing namespace. The following
154// line is just a trick for working around a bug in MSVC 8.0, which
155// cannot handle it if we define FunctionMocker in ::testing.
156using internal::FunctionMocker;
157
zhanyong.wan20d1a232013-03-01 06:58:38 +0000158// GMOCK_RESULT_(tn, F) expands to the result type of function type F.
159// We define this as a variadic macro in case F contains unprotected
160// commas (the same reason that we use variadic macros in other places
161// in this file).
shiqiane35fdd92008-12-10 05:08:54 +0000162// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
zhanyong.wan20d1a232013-03-01 06:58:38 +0000163#define GMOCK_RESULT_(tn, ...) \
164 tn ::testing::internal::Function<__VA_ARGS__>::Result
shiqiane35fdd92008-12-10 05:08:54 +0000165
zhanyong.wan20d1a232013-03-01 06:58:38 +0000166// The type of argument N of the given function type.
shiqiane35fdd92008-12-10 05:08:54 +0000167// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
zhanyong.wan20d1a232013-03-01 06:58:38 +0000168#define GMOCK_ARG_(tn, N, ...) \
169 tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
shiqiane35fdd92008-12-10 05:08:54 +0000170
zhanyong.wan20d1a232013-03-01 06:58:38 +0000171// The matcher type for argument N of the given function type.
shiqiane35fdd92008-12-10 05:08:54 +0000172// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
zhanyong.wan20d1a232013-03-01 06:58:38 +0000173#define GMOCK_MATCHER_(tn, N, ...) \
174 const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>&
shiqiane35fdd92008-12-10 05:08:54 +0000175
176// The variable for mocking the given method.
177// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
zhanyong.wan68be1112009-03-25 03:56:48 +0000178#define GMOCK_MOCKER_(arity, constness, Method) \
zhanyong.wanccedc1c2010-08-09 22:46:12 +0000179 GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__)
shiqiane35fdd92008-12-10 05:08:54 +0000180
181
182$for i [[
183$range j 1..i
Gennadiy Civilfa658e02018-04-12 13:42:47 -0400184$var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
185$var as = [[$for j, \
186 [[::testing::internal::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]]
187$var matcher_arg_as = [[$for j, \
zhanyong.wan20d1a232013-03-01 06:58:38 +0000188 [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]]
Gennadiy Civilfa658e02018-04-12 13:42:47 -0400189$var matcher_as = [[$for j, [[gmock_a$j]]]]
Gennadiy Civilb5391672018-04-25 13:10:41 -0400190$var anything_matchers = [[$for j, \
191 [[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]]
shiqiane35fdd92008-12-10 05:08:54 +0000192// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
zhanyong.wan20d1a232013-03-01 06:58:38 +0000193#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \
194 GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
195 $arg_as) constness { \
kosakbd018832014-04-02 20:30:00 +0000196 GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
zhanyong.wan20d1a232013-03-01 06:58:38 +0000197 tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \
shiqiane35fdd92008-12-10 05:08:54 +0000198 this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \
zhanyong.wan68be1112009-03-25 03:56:48 +0000199 GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \
200 return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \
shiqiane35fdd92008-12-10 05:08:54 +0000201 } \
Gennadiy Civilfa658e02018-04-12 13:42:47 -0400202 ::testing::MockSpec<__VA_ARGS__> \
203 gmock_##Method($matcher_arg_as) constness { \
zhanyong.waned6c9272011-02-23 19:39:27 +0000204 GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \
Gennadiy Civilfa658e02018-04-12 13:42:47 -0400205 return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \
shiqiane35fdd92008-12-10 05:08:54 +0000206 } \
Gennadiy Civilb5391672018-04-25 13:10:41 -0400207 ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
208 const ::testing::internal::WithoutMatchers&, \
209 constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
210 return ::testing::internal::AdjustConstness_##constness(this)-> \
211 gmock_##Method($anything_matchers); \
212 } \
zhanyong.wan20d1a232013-03-01 06:58:38 +0000213 mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method)
shiqiane35fdd92008-12-10 05:08:54 +0000214
215
216]]
217$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000218#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000219
220]]
221
222
223$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000224#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000225
226]]
227
228
229$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000230#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000231
232]]
233
234
235$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000236#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \
237 GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000238
239]]
240
241
242$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000243#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
244 GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000245
246]]
247
248
249$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000250#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \
251 GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000252
253]]
254
255
256$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000257#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
258 GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000259
260]]
261
262
263$for i [[
zhanyong.wan20d1a232013-03-01 06:58:38 +0000264#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \
265 GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__)
shiqiane35fdd92008-12-10 05:08:54 +0000266
267]]
268
zhanyong.wanf3aa4d22009-09-25 22:34:47 +0000269// A MockFunction<F> class has one mock method whose type is F. It is
270// useful when you just want your test code to emit some messages and
271// have Google Mock verify the right messages are sent (and perhaps at
272// the right times). For example, if you are exercising code:
273//
274// Foo(1);
275// Foo(2);
276// Foo(3);
277//
278// and want to verify that Foo(1) and Foo(3) both invoke
279// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
280//
281// TEST(FooTest, InvokesBarCorrectly) {
282// MyMock mock;
283// MockFunction<void(string check_point_name)> check;
284// {
285// InSequence s;
286//
287// EXPECT_CALL(mock, Bar("a"));
288// EXPECT_CALL(check, Call("1"));
289// EXPECT_CALL(check, Call("2"));
290// EXPECT_CALL(mock, Bar("a"));
291// }
292// Foo(1);
293// check.Call("1");
294// Foo(2);
295// check.Call("2");
296// Foo(3);
297// }
298//
299// The expectation spec says that the first Bar("a") must happen
300// before check point "1", the second Bar("a") must happen after check
301// point "2", and nothing should happen between the two check
302// points. The explicit check points make it easy to tell which
303// Bar("a") is called by which call to Foo().
kosaka9e02a92014-06-17 23:19:54 +0000304//
305// MockFunction<F> can also be used to exercise code that accepts
306// std::function<F> callbacks. To do so, use AsStdFunction() method
307// to create std::function proxy forwarding to original object's Call.
308// Example:
309//
310// TEST(FooTest, RunsCallbackWithBarArgument) {
311// MockFunction<int(string)> callback;
312// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
313// Foo(callback.AsStdFunction());
314// }
zhanyong.wanf3aa4d22009-09-25 22:34:47 +0000315template <typename F>
316class MockFunction;
317
318
319$for i [[
320$range j 0..i-1
kosaka9e02a92014-06-17 23:19:54 +0000321$var ArgTypes = [[$for j, [[A$j]]]]
Gennadiy Civilfa658e02018-04-12 13:42:47 -0400322$var ArgValues = [[$for j, [[::std::move(a$j)]]]]
kosaka9e02a92014-06-17 23:19:54 +0000323$var ArgDecls = [[$for j, [[A$j a$j]]]]
zhanyong.wanf3aa4d22009-09-25 22:34:47 +0000324template <typename R$for j [[, typename A$j]]>
kosaka9e02a92014-06-17 23:19:54 +0000325class MockFunction<R($ArgTypes)> {
zhanyong.wanf3aa4d22009-09-25 22:34:47 +0000326 public:
zhanyong.wan32de5f52009-12-23 00:13:23 +0000327 MockFunction() {}
328
kosaka9e02a92014-06-17 23:19:54 +0000329 MOCK_METHOD$i[[]]_T(Call, R($ArgTypes));
330
kosak5b9cbbb2014-11-17 00:28:55 +0000331#if GTEST_HAS_STD_FUNCTION_
Gennadiy Civilfa658e02018-04-12 13:42:47 -0400332 ::std::function<R($ArgTypes)> AsStdFunction() {
kosaka6e32f02015-07-24 20:05:26 +0000333 return [this]($ArgDecls) -> R {
Gennadiy Civilfa658e02018-04-12 13:42:47 -0400334 return this->Call($ArgValues);
kosaka9e02a92014-06-17 23:19:54 +0000335 };
336 }
kosak5b9cbbb2014-11-17 00:28:55 +0000337#endif // GTEST_HAS_STD_FUNCTION_
zhanyong.wan32de5f52009-12-23 00:13:23 +0000338
339 private:
340 GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
zhanyong.wanf3aa4d22009-09-25 22:34:47 +0000341};
342
343
344]]
shiqiane35fdd92008-12-10 05:08:54 +0000345} // namespace testing
346
347#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_