gmock-function-mocker_test.cc 33.6 KB
Newer Older
Abseil Team's avatar
Abseil Team committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the function mocker classes.
Abseil Team's avatar
Abseil Team committed
33
#include "gmock/gmock-function-mocker.h"
Abseil Team's avatar
Abseil Team committed
34
35
36
37
38

#if GTEST_OS_WINDOWS
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
// we are getting compiler errors if we use basetyps.h, hence including
// objbase.h for definition of STDMETHOD.
39
#include <objbase.h>
Abseil Team's avatar
Abseil Team committed
40
41
#endif  // GTEST_OS_WINDOWS

42
#include <functional>
Abseil Team's avatar
Abseil Team committed
43
44
#include <map>
#include <string>
45
46
#include <type_traits>

Abseil Team's avatar
Abseil Team committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace testing {
namespace gmock_function_mocker_test {

using testing::_;
using testing::A;
using testing::An;
using testing::AnyNumber;
using testing::Const;
using testing::DoDefault;
using testing::Eq;
using testing::Lt;
using testing::MockFunction;
using testing::Ref;
using testing::Return;
using testing::ReturnRef;
using testing::TypedEq;

67
template <typename T>
Abseil Team's avatar
Abseil Team committed
68
69
70
71
72
73
74
75
class TemplatedCopyable {
 public:
  TemplatedCopyable() {}

  template <typename U>
  TemplatedCopyable(const U& other) {}  // NOLINT
};

Abseil Team's avatar
Abseil Team committed
76
77
78
79
80
81
82
83
class FooInterface {
 public:
  virtual ~FooInterface() {}

  virtual void VoidReturning(int x) = 0;

  virtual int Nullary() = 0;
  virtual bool Unary(int x) = 0;
84
  virtual long Binary(short x, int y) = 0;                     // NOLINT
Abseil Team's avatar
Abseil Team committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  virtual int Decimal(bool b, char c, short d, int e, long f,  // NOLINT
                      float g, double h, unsigned i, char* j,
                      const std::string& k) = 0;

  virtual bool TakesNonConstReference(int& n) = 0;  // NOLINT
  virtual std::string TakesConstReference(const int& n) = 0;
  virtual bool TakesConst(const int x) = 0;

  virtual int OverloadedOnArgumentNumber() = 0;
  virtual int OverloadedOnArgumentNumber(int n) = 0;

  virtual int OverloadedOnArgumentType(int n) = 0;
  virtual char OverloadedOnArgumentType(char c) = 0;

  virtual int OverloadedOnConstness() = 0;
  virtual char OverloadedOnConstness() const = 0;

  virtual int TypeWithHole(int (*func)()) = 0;
  virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
Abseil Team's avatar
Abseil Team committed
104
  virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;
Abseil Team's avatar
Abseil Team committed
105

Abseil Team's avatar
Abseil Team committed
106
107
108
109
  virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
  using fn_ptr = int (*)(bool);
  virtual fn_ptr ReturnsFunctionPointer2(int) = 0;

Abseil Team's avatar
Abseil Team committed
110
111
112
113
114
115
116
117
118
119
  virtual int RefQualifiedConstRef() const& = 0;
  virtual int RefQualifiedConstRefRef() const&& = 0;
  virtual int RefQualifiedRef() & = 0;
  virtual int RefQualifiedRefRef() && = 0;

  virtual int RefQualifiedOverloaded() const& = 0;
  virtual int RefQualifiedOverloaded() const&& = 0;
  virtual int RefQualifiedOverloaded() & = 0;
  virtual int RefQualifiedOverloaded() && = 0;

Abseil Team's avatar
Abseil Team committed
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#if GTEST_OS_WINDOWS
  STDMETHOD_(int, CTNullary)() = 0;
  STDMETHOD_(bool, CTUnary)(int x) = 0;
  STDMETHOD_(int, CTDecimal)
  (bool b, char c, short d, int e, long f,  // NOLINT
   float g, double h, unsigned i, char* j, const std::string& k) = 0;
  STDMETHOD_(char, CTConst)(int x) const = 0;
#endif  // GTEST_OS_WINDOWS
};

// Const qualifiers on arguments were once (incorrectly) considered
// significant in determining whether two virtual functions had the same
// signature. This was fixed in Visual Studio 2008. However, the compiler
// still emits a warning that alerts about this change in behavior.
#ifdef _MSC_VER
135
136
#pragma warning(push)
#pragma warning(disable : 4373)
Abseil Team's avatar
Abseil Team committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#endif
class MockFoo : public FooInterface {
 public:
  MockFoo() {}

  // Makes sure that a mock function parameter can be named.
  MOCK_METHOD(void, VoidReturning, (int n));  // NOLINT

  MOCK_METHOD(int, Nullary, ());  // NOLINT

  // Makes sure that a mock function parameter can be unnamed.
  MOCK_METHOD(bool, Unary, (int));          // NOLINT
  MOCK_METHOD(long, Binary, (short, int));  // NOLINT
  MOCK_METHOD(int, Decimal,
              (bool, char, short, int, long, float,  // NOLINT
               double, unsigned, char*, const std::string& str),
              (override));

  MOCK_METHOD(bool, TakesNonConstReference, (int&));  // NOLINT
  MOCK_METHOD(std::string, TakesConstReference, (const int&));
  MOCK_METHOD(bool, TakesConst, (const int));  // NOLINT

  // Tests that the function return type can contain unprotected comma.
  MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (), ());
  MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (int),
              (const));  // NOLINT

  MOCK_METHOD(int, OverloadedOnArgumentNumber, ());     // NOLINT
  MOCK_METHOD(int, OverloadedOnArgumentNumber, (int));  // NOLINT

  MOCK_METHOD(int, OverloadedOnArgumentType, (int));    // NOLINT
  MOCK_METHOD(char, OverloadedOnArgumentType, (char));  // NOLINT

  MOCK_METHOD(int, OverloadedOnConstness, (), (override));          // NOLINT
  MOCK_METHOD(char, OverloadedOnConstness, (), (override, const));  // NOLINT

  MOCK_METHOD(int, TypeWithHole, (int (*)()), ());  // NOLINT
  MOCK_METHOD(int, TypeWithComma, ((const std::map<int, std::string>&)));
Abseil Team's avatar
Abseil Team committed
175
176
  MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
              (const TemplatedCopyable<int>&));  // NOLINT
Abseil Team's avatar
Abseil Team committed
177

Abseil Team's avatar
Abseil Team committed
178
179
180
  MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
  MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());

Abseil Team's avatar
Abseil Team committed
181
182
183
184
185
186
187
188
189
190
191
192
#if GTEST_OS_WINDOWS
  MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
  MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
  MOCK_METHOD(int, CTDecimal,
              (bool b, char c, short d, int e, long f, float g, double h,
               unsigned i, char* j, const std::string& k),
              (Calltype(STDMETHODCALLTYPE)));
  MOCK_METHOD(char, CTConst, (int), (const, Calltype(STDMETHODCALLTYPE)));
  MOCK_METHOD((std::map<int, std::string>), CTReturnTypeWithComma, (),
              (Calltype(STDMETHODCALLTYPE)));
#endif  // GTEST_OS_WINDOWS

Abseil Team's avatar
Abseil Team committed
193
194
195
196
197
198
199
200
201
202
203
  // Test reference qualified functions.
  MOCK_METHOD(int, RefQualifiedConstRef, (), (const, ref(&), override));
  MOCK_METHOD(int, RefQualifiedConstRefRef, (), (const, ref(&&), override));
  MOCK_METHOD(int, RefQualifiedRef, (), (ref(&), override));
  MOCK_METHOD(int, RefQualifiedRefRef, (), (ref(&&), override));

  MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&), override));
  MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&&), override));
  MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&), override));
  MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&&), override));

Abseil Team's avatar
Abseil Team committed
204
 private:
205
206
  MockFoo(const MockFoo&) = delete;
  MockFoo& operator=(const MockFoo&) = delete;
Abseil Team's avatar
Abseil Team committed
207
};
Abseil Team's avatar
Abseil Team committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265

class LegacyMockFoo : public FooInterface {
 public:
  LegacyMockFoo() {}

  // Makes sure that a mock function parameter can be named.
  MOCK_METHOD1(VoidReturning, void(int n));  // NOLINT

  MOCK_METHOD0(Nullary, int());  // NOLINT

  // Makes sure that a mock function parameter can be unnamed.
  MOCK_METHOD1(Unary, bool(int));                                  // NOLINT
  MOCK_METHOD2(Binary, long(short, int));                          // NOLINT
  MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float,  // NOLINT
                             double, unsigned, char*, const std::string& str));

  MOCK_METHOD1(TakesNonConstReference, bool(int&));  // NOLINT
  MOCK_METHOD1(TakesConstReference, std::string(const int&));
  MOCK_METHOD1(TakesConst, bool(const int));  // NOLINT

  // Tests that the function return type can contain unprotected comma.
  MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>());
  MOCK_CONST_METHOD1(ReturnTypeWithComma,
                     std::map<int, std::string>(int));  // NOLINT

  MOCK_METHOD0(OverloadedOnArgumentNumber, int());     // NOLINT
  MOCK_METHOD1(OverloadedOnArgumentNumber, int(int));  // NOLINT

  MOCK_METHOD1(OverloadedOnArgumentType, int(int));    // NOLINT
  MOCK_METHOD1(OverloadedOnArgumentType, char(char));  // NOLINT

  MOCK_METHOD0(OverloadedOnConstness, int());         // NOLINT
  MOCK_CONST_METHOD0(OverloadedOnConstness, char());  // NOLINT

  MOCK_METHOD1(TypeWithHole, int(int (*)()));  // NOLINT
  MOCK_METHOD1(TypeWithComma,
               int(const std::map<int, std::string>&));  // NOLINT
  MOCK_METHOD1(TypeWithTemplatedCopyCtor,
               int(const TemplatedCopyable<int>&));  // NOLINT

  MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));
  MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));

#if GTEST_OS_WINDOWS
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int));  // NOLINT
  MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal,
                              int(bool b, char c, short d, int e,  // NOLINT
                                  long f, float g, double h,       // NOLINT
                                  unsigned i, char* j, const std::string& k));
  MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst,
                                   char(int));  // NOLINT

  // Tests that the function return type can contain unprotected comma.
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma,
                             std::map<int, std::string>());
#endif  // GTEST_OS_WINDOWS

Abseil Team's avatar
Abseil Team committed
266
267
268
269
270
271
272
273
274
275
276
  // We can't mock these with the old macros, but we need to define them to make
  // it concrete.
  int RefQualifiedConstRef() const& override { return 0; }
  int RefQualifiedConstRefRef() const&& override { return 0; }
  int RefQualifiedRef() & override { return 0; }
  int RefQualifiedRefRef() && override { return 0; }
  int RefQualifiedOverloaded() const& override { return 0; }
  int RefQualifiedOverloaded() const&& override { return 0; }
  int RefQualifiedOverloaded() & override { return 0; }
  int RefQualifiedOverloaded() && override { return 0; }

Abseil Team's avatar
Abseil Team committed
277
 private:
278
279
  LegacyMockFoo(const LegacyMockFoo&) = delete;
  LegacyMockFoo& operator=(const LegacyMockFoo&) = delete;
Abseil Team's avatar
Abseil Team committed
280
281
};

Abseil Team's avatar
Abseil Team committed
282
#ifdef _MSC_VER
283
#pragma warning(pop)
Abseil Team's avatar
Abseil Team committed
284
285
#endif

Abseil Team's avatar
Abseil Team committed
286
287
template <class T>
class FunctionMockerTest : public testing::Test {
Abseil Team's avatar
Abseil Team committed
288
 protected:
Abseil Team's avatar
Abseil Team committed
289
  FunctionMockerTest() : foo_(&mock_foo_) {}
Abseil Team's avatar
Abseil Team committed
290
291

  FooInterface* const foo_;
Abseil Team's avatar
Abseil Team committed
292
  T mock_foo_;
Abseil Team's avatar
Abseil Team committed
293
};
Abseil Team's avatar
Abseil Team committed
294
295
using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>;
TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes);
Abseil Team's avatar
Abseil Team committed
296
297

// Tests mocking a void-returning function.
Abseil Team's avatar
Abseil Team committed
298
299
300
TYPED_TEST(FunctionMockerTest, MocksVoidFunction) {
  EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100)));
  this->foo_->VoidReturning(0);
Abseil Team's avatar
Abseil Team committed
301
302
303
}

// Tests mocking a nullary function.
Abseil Team's avatar
Abseil Team committed
304
305
TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) {
  EXPECT_CALL(this->mock_foo_, Nullary())
Abseil Team's avatar
Abseil Team committed
306
307
308
      .WillOnce(DoDefault())
      .WillOnce(Return(1));

Abseil Team's avatar
Abseil Team committed
309
310
  EXPECT_EQ(0, this->foo_->Nullary());
  EXPECT_EQ(1, this->foo_->Nullary());
Abseil Team's avatar
Abseil Team committed
311
312
313
}

// Tests mocking a unary function.
Abseil Team's avatar
Abseil Team committed
314
315
TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) {
  EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true));
Abseil Team's avatar
Abseil Team committed
316

Abseil Team's avatar
Abseil Team committed
317
318
  EXPECT_TRUE(this->foo_->Unary(2));
  EXPECT_FALSE(this->foo_->Unary(2));
Abseil Team's avatar
Abseil Team committed
319
320
321
}

// Tests mocking a binary function.
Abseil Team's avatar
Abseil Team committed
322
323
TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) {
  EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3));
Abseil Team's avatar
Abseil Team committed
324

Abseil Team's avatar
Abseil Team committed
325
  EXPECT_EQ(3, this->foo_->Binary(2, 1));
Abseil Team's avatar
Abseil Team committed
326
327
328
}

// Tests mocking a decimal function.
Abseil Team's avatar
Abseil Team committed
329
330
331
TYPED_TEST(FunctionMockerTest, MocksDecimalFunction) {
  EXPECT_CALL(this->mock_foo_,
              Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, NULL, "hi"))
Abseil Team's avatar
Abseil Team committed
332
333
      .WillOnce(Return(5));

Abseil Team's avatar
Abseil Team committed
334
  EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi"));
Abseil Team's avatar
Abseil Team committed
335
336
337
}

// Tests mocking a function that takes a non-const reference.
Abseil Team's avatar
Abseil Team committed
338
TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
Abseil Team's avatar
Abseil Team committed
339
  int a = 0;
Abseil Team's avatar
Abseil Team committed
340
  EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a)))
Abseil Team's avatar
Abseil Team committed
341
342
      .WillOnce(Return(true));

Abseil Team's avatar
Abseil Team committed
343
  EXPECT_TRUE(this->foo_->TakesNonConstReference(a));
Abseil Team's avatar
Abseil Team committed
344
345
346
}

// Tests mocking a function that takes a const reference.
Abseil Team's avatar
Abseil Team committed
347
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
Abseil Team's avatar
Abseil Team committed
348
  int a = 0;
Abseil Team's avatar
Abseil Team committed
349
  EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a)))
Abseil Team's avatar
Abseil Team committed
350
351
      .WillOnce(Return("Hello"));

Abseil Team's avatar
Abseil Team committed
352
  EXPECT_EQ("Hello", this->foo_->TakesConstReference(a));
Abseil Team's avatar
Abseil Team committed
353
354
355
}

// Tests mocking a function that takes a const variable.
Abseil Team's avatar
Abseil Team committed
356
357
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstArgument) {
  EXPECT_CALL(this->mock_foo_, TakesConst(Lt(10))).WillOnce(DoDefault());
Abseil Team's avatar
Abseil Team committed
358

Abseil Team's avatar
Abseil Team committed
359
  EXPECT_FALSE(this->foo_->TakesConst(5));
Abseil Team's avatar
Abseil Team committed
360
361
362
}

// Tests mocking functions overloaded on the number of arguments.
Abseil Team's avatar
Abseil Team committed
363
364
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber())
Abseil Team's avatar
Abseil Team committed
365
      .WillOnce(Return(1));
Abseil Team's avatar
Abseil Team committed
366
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_))
Abseil Team's avatar
Abseil Team committed
367
368
      .WillOnce(Return(2));

Abseil Team's avatar
Abseil Team committed
369
370
  EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1));
  EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber());
Abseil Team's avatar
Abseil Team committed
371
372
373
}

// Tests mocking functions overloaded on the types of argument.
Abseil Team's avatar
Abseil Team committed
374
375
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>()))
Abseil Team's avatar
Abseil Team committed
376
      .WillOnce(Return(1));
Abseil Team's avatar
Abseil Team committed
377
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
Abseil Team's avatar
Abseil Team committed
378
379
      .WillOnce(Return('b'));

Abseil Team's avatar
Abseil Team committed
380
381
  EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0));
  EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a'));
Abseil Team's avatar
Abseil Team committed
382
383
384
}

// Tests mocking functions overloaded on the const-ness of this object.
Abseil Team's avatar
Abseil Team committed
385
386
387
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
  EXPECT_CALL(this->mock_foo_, OverloadedOnConstness());
  EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness())
Abseil Team's avatar
Abseil Team committed
388
389
      .WillOnce(Return('a'));

Abseil Team's avatar
Abseil Team committed
390
391
  EXPECT_EQ(0, this->foo_->OverloadedOnConstness());
  EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness());
Abseil Team's avatar
Abseil Team committed
392
393
}

Abseil Team's avatar
Abseil Team committed
394
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {
Abseil Team's avatar
Abseil Team committed
395
  const std::map<int, std::string> a_map;
Abseil Team's avatar
Abseil Team committed
396
397
  EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma()).WillOnce(Return(a_map));
  EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma(42)).WillOnce(Return(a_map));
Abseil Team's avatar
Abseil Team committed
398

Abseil Team's avatar
Abseil Team committed
399
400
  EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma());
  EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42));
Abseil Team's avatar
Abseil Team committed
401
402
}

Abseil Team's avatar
Abseil Team committed
403
404
405
406
TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
  EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_))
      .WillOnce(Return(true));
  EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
Abseil Team's avatar
Abseil Team committed
407
408
}

Abseil Team's avatar
Abseil Team committed
409
410
#if GTEST_OS_WINDOWS
// Tests mocking a nullary function with calltype.
Abseil Team's avatar
Abseil Team committed
411
412
TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
  EXPECT_CALL(this->mock_foo_, CTNullary())
Abseil Team's avatar
Abseil Team committed
413
414
415
      .WillOnce(Return(-1))
      .WillOnce(Return(0));

Abseil Team's avatar
Abseil Team committed
416
417
  EXPECT_EQ(-1, this->foo_->CTNullary());
  EXPECT_EQ(0, this->foo_->CTNullary());
Abseil Team's avatar
Abseil Team committed
418
419
420
}

// Tests mocking a unary function with calltype.
Abseil Team's avatar
Abseil Team committed
421
422
TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
  EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2)))
Abseil Team's avatar
Abseil Team committed
423
424
425
426
      .Times(2)
      .WillOnce(Return(true))
      .WillOnce(Return(false));

Abseil Team's avatar
Abseil Team committed
427
428
  EXPECT_TRUE(this->foo_->CTUnary(2));
  EXPECT_FALSE(this->foo_->CTUnary(2));
Abseil Team's avatar
Abseil Team committed
429
430
431
}

// Tests mocking a decimal function with calltype.
Abseil Team's avatar
Abseil Team committed
432
433
434
TYPED_TEST(FunctionMockerTest, MocksDecimalFunctionWithCallType) {
  EXPECT_CALL(this->mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),
                                         Lt(100), 5U, NULL, "hi"))
Abseil Team's avatar
Abseil Team committed
435
436
      .WillOnce(Return(10));

Abseil Team's avatar
Abseil Team committed
437
  EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
Abseil Team's avatar
Abseil Team committed
438
439
440
}

// Tests mocking functions overloaded on the const-ness of this object.
Abseil Team's avatar
Abseil Team committed
441
442
TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
  EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a'));
Abseil Team's avatar
Abseil Team committed
443

Abseil Team's avatar
Abseil Team committed
444
  EXPECT_EQ('a', Const(*this->foo_).CTConst(0));
Abseil Team's avatar
Abseil Team committed
445
446
}

Abseil Team's avatar
Abseil Team committed
447
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
Abseil Team's avatar
Abseil Team committed
448
  const std::map<int, std::string> a_map;
Abseil Team's avatar
Abseil Team committed
449
  EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map));
Abseil Team's avatar
Abseil Team committed
450

Abseil Team's avatar
Abseil Team committed
451
  EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma());
Abseil Team's avatar
Abseil Team committed
452
453
454
455
}

#endif  // GTEST_OS_WINDOWS

Abseil Team's avatar
Abseil Team committed
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
TEST(FunctionMockerTest, RefQualified) {
  MockFoo mock_foo;

  EXPECT_CALL(mock_foo, RefQualifiedConstRef).WillOnce(Return(1));
  EXPECT_CALL(std::move(mock_foo),  // NOLINT
              RefQualifiedConstRefRef)
      .WillOnce(Return(2));
  EXPECT_CALL(mock_foo, RefQualifiedRef).WillOnce(Return(3));
  EXPECT_CALL(std::move(mock_foo),  // NOLINT
              RefQualifiedRefRef)
      .WillOnce(Return(4));

  EXPECT_CALL(static_cast<const MockFoo&>(mock_foo), RefQualifiedOverloaded())
      .WillOnce(Return(5));
  EXPECT_CALL(static_cast<const MockFoo&&>(mock_foo), RefQualifiedOverloaded())
      .WillOnce(Return(6));
  EXPECT_CALL(static_cast<MockFoo&>(mock_foo), RefQualifiedOverloaded())
      .WillOnce(Return(7));
  EXPECT_CALL(static_cast<MockFoo&&>(mock_foo), RefQualifiedOverloaded())
      .WillOnce(Return(8));

  EXPECT_EQ(mock_foo.RefQualifiedConstRef(), 1);
  EXPECT_EQ(std::move(mock_foo).RefQualifiedConstRefRef(), 2);  // NOLINT
  EXPECT_EQ(mock_foo.RefQualifiedRef(), 3);
  EXPECT_EQ(std::move(mock_foo).RefQualifiedRefRef(), 4);  // NOLINT

  EXPECT_EQ(std::cref(mock_foo).get().RefQualifiedOverloaded(), 5);
  EXPECT_EQ(std::move(std::cref(mock_foo).get())  // NOLINT
                .RefQualifiedOverloaded(),
            6);
  EXPECT_EQ(mock_foo.RefQualifiedOverloaded(), 7);
  EXPECT_EQ(std::move(mock_foo).RefQualifiedOverloaded(), 8);  // NOLINT
}

Abseil Team's avatar
Abseil Team committed
490
491
492
493
494
495
496
class MockB {
 public:
  MockB() {}

  MOCK_METHOD(void, DoB, ());

 private:
497
498
  MockB(const MockB&) = delete;
  MockB& operator=(const MockB&) = delete;
Abseil Team's avatar
Abseil Team committed
499
500
};

Abseil Team's avatar
Abseil Team committed
501
502
503
504
505
506
507
class LegacyMockB {
 public:
  LegacyMockB() {}

  MOCK_METHOD0(DoB, void());

 private:
508
509
  LegacyMockB(const LegacyMockB&) = delete;
  LegacyMockB& operator=(const LegacyMockB&) = delete;
Abseil Team's avatar
Abseil Team committed
510
511
512
513
514
515
516
};

template <typename T>
class ExpectCallTest : public ::testing::Test {};
using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>;
TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes);

Abseil Team's avatar
Abseil Team committed
517
518
// Tests that functions with no EXPECT_CALL() rules can be called any
// number of times.
Abseil Team's avatar
Abseil Team committed
519
520
TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
  { TypeParam b; }
Abseil Team's avatar
Abseil Team committed
521
522

  {
Abseil Team's avatar
Abseil Team committed
523
    TypeParam b;
Abseil Team's avatar
Abseil Team committed
524
525
526
527
    b.DoB();
  }

  {
Abseil Team's avatar
Abseil Team committed
528
    TypeParam b;
Abseil Team's avatar
Abseil Team committed
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
    b.DoB();
    b.DoB();
  }
}

// Tests mocking template interfaces.

template <typename T>
class StackInterface {
 public:
  virtual ~StackInterface() {}

  // Template parameter appears in function parameter.
  virtual void Push(const T& value) = 0;
  virtual void Pop() = 0;
  virtual int GetSize() const = 0;
  // Template parameter appears in function return type.
  virtual const T& GetTop() const = 0;
};

template <typename T>
class MockStack : public StackInterface<T> {
 public:
  MockStack() {}

  MOCK_METHOD(void, Push, (const T& elem), ());
  MOCK_METHOD(void, Pop, (), (final));
  MOCK_METHOD(int, GetSize, (), (const, override));
  MOCK_METHOD(const T&, GetTop, (), (const));

  // Tests that the function return type can contain unprotected comma.
  MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (), ());
  MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (int), (const));

 private:
564
565
  MockStack(const MockStack&) = delete;
  MockStack& operator=(const MockStack&) = delete;
Abseil Team's avatar
Abseil Team committed
566
567
};

Abseil Team's avatar
Abseil Team committed
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
template <typename T>
class LegacyMockStack : public StackInterface<T> {
 public:
  LegacyMockStack() {}

  MOCK_METHOD1_T(Push, void(const T& elem));
  MOCK_METHOD0_T(Pop, void());
  MOCK_CONST_METHOD0_T(GetSize, int());  // NOLINT
  MOCK_CONST_METHOD0_T(GetTop, const T&());

  // Tests that the function return type can contain unprotected comma.
  MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>());
  MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int));  // NOLINT

 private:
583
584
  LegacyMockStack(const LegacyMockStack&) = delete;
  LegacyMockStack& operator=(const LegacyMockStack&) = delete;
Abseil Team's avatar
Abseil Team committed
585
586
587
588
589
590
591
592
};

template <typename T>
class TemplateMockTest : public ::testing::Test {};
using TemplateMockTestTypes =
    ::testing::Types<MockStack<int>, LegacyMockStack<int>>;
TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes);

Abseil Team's avatar
Abseil Team committed
593
// Tests that template mock works.
Abseil Team's avatar
Abseil Team committed
594
595
TYPED_TEST(TemplateMockTest, Works) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
596
597
598
599
600
601
602

  EXPECT_CALL(mock, GetSize())
      .WillOnce(Return(0))
      .WillOnce(Return(1))
      .WillOnce(Return(0));
  EXPECT_CALL(mock, Push(_));
  int n = 5;
603
604
  EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));
  EXPECT_CALL(mock, Pop()).Times(AnyNumber());
Abseil Team's avatar
Abseil Team committed
605
606
607
608
609
610
611
612
613

  EXPECT_EQ(0, mock.GetSize());
  mock.Push(5);
  EXPECT_EQ(1, mock.GetSize());
  EXPECT_EQ(5, mock.GetTop());
  mock.Pop();
  EXPECT_EQ(0, mock.GetSize());
}

Abseil Team's avatar
Abseil Team committed
614
615
TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
616
617

  const std::map<int, int> a_map;
618
619
  EXPECT_CALL(mock, ReturnTypeWithComma()).WillOnce(Return(a_map));
  EXPECT_CALL(mock, ReturnTypeWithComma(1)).WillOnce(Return(a_map));
Abseil Team's avatar
Abseil Team committed
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653

  EXPECT_EQ(a_map, mock.ReturnTypeWithComma());
  EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));
}

#if GTEST_OS_WINDOWS
// Tests mocking template interfaces with calltype.

template <typename T>
class StackInterfaceWithCallType {
 public:
  virtual ~StackInterfaceWithCallType() {}

  // Template parameter appears in function parameter.
  STDMETHOD_(void, Push)(const T& value) = 0;
  STDMETHOD_(void, Pop)() = 0;
  STDMETHOD_(int, GetSize)() const = 0;
  // Template parameter appears in function return type.
  STDMETHOD_(const T&, GetTop)() const = 0;
};

template <typename T>
class MockStackWithCallType : public StackInterfaceWithCallType<T> {
 public:
  MockStackWithCallType() {}

  MOCK_METHOD(void, Push, (const T& elem),
              (Calltype(STDMETHODCALLTYPE), override));
  MOCK_METHOD(void, Pop, (), (Calltype(STDMETHODCALLTYPE), override));
  MOCK_METHOD(int, GetSize, (), (Calltype(STDMETHODCALLTYPE), override, const));
  MOCK_METHOD(const T&, GetTop, (),
              (Calltype(STDMETHODCALLTYPE), override, const));

 private:
654
655
  MockStackWithCallType(const MockStackWithCallType&) = delete;
  MockStackWithCallType& operator=(const MockStackWithCallType&) = delete;
Abseil Team's avatar
Abseil Team committed
656
657
};

Abseil Team's avatar
Abseil Team committed
658
659
660
661
662
663
664
665
666
667
668
template <typename T>
class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> {
 public:
  LegacyMockStackWithCallType() {}

  MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
  MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
  MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
  MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());

 private:
669
670
671
  LegacyMockStackWithCallType(const LegacyMockStackWithCallType&) = delete;
  LegacyMockStackWithCallType& operator=(const LegacyMockStackWithCallType&) =
      delete;
Abseil Team's avatar
Abseil Team committed
672
673
674
675
676
677
678
679
680
681
};

template <typename T>
class TemplateMockTestWithCallType : public ::testing::Test {};
using TemplateMockTestWithCallTypeTypes =
    ::testing::Types<MockStackWithCallType<int>,
                     LegacyMockStackWithCallType<int>>;
TYPED_TEST_SUITE(TemplateMockTestWithCallType,
                 TemplateMockTestWithCallTypeTypes);

Abseil Team's avatar
Abseil Team committed
682
// Tests that template mock with calltype works.
Abseil Team's avatar
Abseil Team committed
683
684
TYPED_TEST(TemplateMockTestWithCallType, Works) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
685
686
687
688
689
690
691

  EXPECT_CALL(mock, GetSize())
      .WillOnce(Return(0))
      .WillOnce(Return(1))
      .WillOnce(Return(0));
  EXPECT_CALL(mock, Push(_));
  int n = 5;
692
693
  EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));
  EXPECT_CALL(mock, Pop()).Times(AnyNumber());
Abseil Team's avatar
Abseil Team committed
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708

  EXPECT_EQ(0, mock.GetSize());
  mock.Push(5);
  EXPECT_EQ(1, mock.GetSize());
  EXPECT_EQ(5, mock.GetTop());
  mock.Pop();
  EXPECT_EQ(0, mock.GetSize());
}
#endif  // GTEST_OS_WINDOWS

#define MY_MOCK_METHODS1_                       \
  MOCK_METHOD(void, Overloaded, ());            \
  MOCK_METHOD(int, Overloaded, (int), (const)); \
  MOCK_METHOD(bool, Overloaded, (bool f, int n))

Abseil Team's avatar
Abseil Team committed
709
710
711
712
713
#define LEGACY_MY_MOCK_METHODS1_              \
  MOCK_METHOD0(Overloaded, void());           \
  MOCK_CONST_METHOD1(Overloaded, int(int n)); \
  MOCK_METHOD2(Overloaded, bool(bool f, int n))

Abseil Team's avatar
Abseil Team committed
714
715
716
717
718
719
720
class MockOverloadedOnArgNumber {
 public:
  MockOverloadedOnArgNumber() {}

  MY_MOCK_METHODS1_;

 private:
721
722
723
  MockOverloadedOnArgNumber(const MockOverloadedOnArgNumber&) = delete;
  MockOverloadedOnArgNumber& operator=(const MockOverloadedOnArgNumber&) =
      delete;
Abseil Team's avatar
Abseil Team committed
724
725
};

Abseil Team's avatar
Abseil Team committed
726
727
728
729
730
731
732
class LegacyMockOverloadedOnArgNumber {
 public:
  LegacyMockOverloadedOnArgNumber() {}

  LEGACY_MY_MOCK_METHODS1_;

 private:
733
734
735
736
  LegacyMockOverloadedOnArgNumber(const LegacyMockOverloadedOnArgNumber&) =
      delete;
  LegacyMockOverloadedOnArgNumber& operator=(
      const LegacyMockOverloadedOnArgNumber&) = delete;
Abseil Team's avatar
Abseil Team committed
737
738
739
740
741
742
743
744
745
746
747
};

template <typename T>
class OverloadedMockMethodTest : public ::testing::Test {};
using OverloadedMockMethodTestTypes =
    ::testing::Types<MockOverloadedOnArgNumber,
                     LegacyMockOverloadedOnArgNumber>;
TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes);

TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
748
749
750
751
752
753
754
755
756
  EXPECT_CALL(mock, Overloaded());
  EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
  EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true));

  mock.Overloaded();
  EXPECT_EQ(2, mock.Overloaded(1));
  EXPECT_TRUE(mock.Overloaded(true, 1));
}

757
758
759
#define MY_MOCK_METHODS2_                     \
  MOCK_CONST_METHOD1(Overloaded, int(int n)); \
  MOCK_METHOD1(Overloaded, int(int n))
Abseil Team's avatar
Abseil Team committed
760
761
762
763
764
765
766
767

class MockOverloadedOnConstness {
 public:
  MockOverloadedOnConstness() {}

  MY_MOCK_METHODS2_;

 private:
768
769
770
  MockOverloadedOnConstness(const MockOverloadedOnConstness&) = delete;
  MockOverloadedOnConstness& operator=(const MockOverloadedOnConstness&) =
      delete;
Abseil Team's avatar
Abseil Team committed
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
};

TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) {
  MockOverloadedOnConstness mock;
  const MockOverloadedOnConstness* const_mock = &mock;
  EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
  EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3));

  EXPECT_EQ(2, mock.Overloaded(1));
  EXPECT_EQ(3, const_mock->Overloaded(1));
}

TEST(MockMethodMockFunctionTest, WorksForVoidNullary) {
  MockFunction<void()> foo;
  EXPECT_CALL(foo, Call());
  foo.Call();
}

TEST(MockMethodMockFunctionTest, WorksForNonVoidNullary) {
  MockFunction<int()> foo;
791
  EXPECT_CALL(foo, Call()).WillOnce(Return(1)).WillOnce(Return(2));
Abseil Team's avatar
Abseil Team committed
792
793
794
795
796
797
798
799
800
801
802
803
  EXPECT_EQ(1, foo.Call());
  EXPECT_EQ(2, foo.Call());
}

TEST(MockMethodMockFunctionTest, WorksForVoidUnary) {
  MockFunction<void(int)> foo;
  EXPECT_CALL(foo, Call(1));
  foo.Call(1);
}

TEST(MockMethodMockFunctionTest, WorksForNonVoidBinary) {
  MockFunction<int(bool, int)> foo;
804
805
  EXPECT_CALL(foo, Call(false, 42)).WillOnce(Return(1)).WillOnce(Return(2));
  EXPECT_CALL(foo, Call(true, Ge(100))).WillOnce(Return(3));
Abseil Team's avatar
Abseil Team committed
806
807
808
809
810
811
  EXPECT_EQ(1, foo.Call(false, 42));
  EXPECT_EQ(2, foo.Call(false, 42));
  EXPECT_EQ(3, foo.Call(true, 120));
}

TEST(MockMethodMockFunctionTest, WorksFor10Arguments) {
812
813
814
  MockFunction<int(bool a0, char a1, int a2, int a3, int a4, int a5, int a6,
                   char a7, int a8, bool a9)>
      foo;
Abseil Team's avatar
Abseil Team committed
815
816
817
818
819
820
821
822
823
  EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _))
      .WillOnce(Return(1))
      .WillOnce(Return(2));
  EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true));
  EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false));
}

TEST(MockMethodMockFunctionTest, AsStdFunction) {
  MockFunction<int(int)> foo;
824
  auto call = [](const std::function<int(int)>& f, int i) { return f(i); };
Abseil Team's avatar
Abseil Team committed
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
  EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1));
  EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2));
  EXPECT_EQ(-1, call(foo.AsStdFunction(), 1));
  EXPECT_EQ(-2, call(foo.AsStdFunction(), 2));
}

TEST(MockMethodMockFunctionTest, AsStdFunctionReturnsReference) {
  MockFunction<int&()> foo;
  int value = 1;
  EXPECT_CALL(foo, Call()).WillOnce(ReturnRef(value));
  int& ref = foo.AsStdFunction()();
  EXPECT_EQ(1, ref);
  value = 2;
  EXPECT_EQ(2, ref);
}

TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
842
843
  MockFunction<int(int&)> foo;
  auto call = [](const std::function<int(int&)>& f, int& i) { return f(i); };
Abseil Team's avatar
Abseil Team committed
844
845
846
847
848
  int i = 42;
  EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1));
  EXPECT_EQ(-1, call(foo.AsStdFunction(), i));
}

849
850
851
namespace {

template <typename Expected, typename F>
852
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
Abseil Team's avatar
Abseil Team committed
853
    const internal::MockFunction<F>&) {
854
855
856
  return std::is_same<F, Expected>::value;
}

857
}  // namespace
858
859

template <typename F>
860
class MockMethodMockFunctionSignatureTest : public Test {};
861

862
863
864
865
866
867
868
869
using MockMethodMockFunctionSignatureTypes =
    Types<void(), int(), void(int), int(int), int(bool, int),
          int(bool, char, int, int, int, int, int, char, int, bool)>;
TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest,
                 MockMethodMockFunctionSignatureTypes);

TYPED_TEST(MockMethodMockFunctionSignatureTest,
           IsMockFunctionTemplateArgumentDeducedForRawSignature) {
870
871
  using Argument = TypeParam;
  MockFunction<Argument> foo;
Abseil Team's avatar
Abseil Team committed
872
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
873
874
}

875
876
TYPED_TEST(MockMethodMockFunctionSignatureTest,
           IsMockFunctionTemplateArgumentDeducedForStdFunction) {
877
878
  using Argument = std::function<TypeParam>;
  MockFunction<Argument> foo;
Abseil Team's avatar
Abseil Team committed
879
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
880
881
}

882
883
884
TYPED_TEST(
    MockMethodMockFunctionSignatureTest,
    IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {
885
  using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
886
887
  using ForStdFunction =
      decltype(&MockFunction<std::function<TypeParam>>::Call);
888
889
890
  EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}

Abseil Team's avatar
Abseil Team committed
891
template <typename F>
892
struct AlternateCallable {};
Abseil Team's avatar
Abseil Team committed
893
894
895
896
897
898
899
900

TYPED_TEST(MockMethodMockFunctionSignatureTest,
           IsMockFunctionTemplateArgumentDeducedForAlternateCallable) {
  using Argument = AlternateCallable<TypeParam>;
  MockFunction<Argument> foo;
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
}

901
902
TYPED_TEST(MockMethodMockFunctionSignatureTest,
           IsMockFunctionCallMethodSignatureTheSameForAlternateCallable) {
Abseil Team's avatar
Abseil Team committed
903
  using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
904
  using ForStdFunction =
Abseil Team's avatar
Abseil Team committed
905
      decltype(&MockFunction<std::function<TypeParam>>::Call);
906
907
  EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}
Abseil Team's avatar
Abseil Team committed
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924

struct MockMethodSizes0 {
  MOCK_METHOD(void, func, ());
};
struct MockMethodSizes1 {
  MOCK_METHOD(void, func, (int));
};
struct MockMethodSizes2 {
  MOCK_METHOD(void, func, (int, int));
};
struct MockMethodSizes3 {
  MOCK_METHOD(void, func, (int, int, int));
};
struct MockMethodSizes4 {
  MOCK_METHOD(void, func, (int, int, int, int));
};

Abseil Team's avatar
Abseil Team committed
925
struct LegacyMockMethodSizes0 {
926
  MOCK_METHOD0(func, void());
Abseil Team's avatar
Abseil Team committed
927
928
};
struct LegacyMockMethodSizes1 {
929
  MOCK_METHOD1(func, void(int));
Abseil Team's avatar
Abseil Team committed
930
931
};
struct LegacyMockMethodSizes2 {
932
  MOCK_METHOD2(func, void(int, int));
Abseil Team's avatar
Abseil Team committed
933
934
};
struct LegacyMockMethodSizes3 {
935
  MOCK_METHOD3(func, void(int, int, int));
Abseil Team's avatar
Abseil Team committed
936
937
};
struct LegacyMockMethodSizes4 {
938
  MOCK_METHOD4(func, void(int, int, int, int));
Abseil Team's avatar
Abseil Team committed
939
940
};

Abseil Team's avatar
Abseil Team committed
941
942
943
944
945
TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {
  EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1));
  EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2));
  EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3));
  EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4));
Abseil Team's avatar
Abseil Team committed
946
947
948
949
950
951
952

  EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1));
  EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2));
  EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3));
  EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4));

  EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));
Abseil Team's avatar
Abseil Team committed
953
954
}

955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
void hasTwoParams(int, int);
void MaybeThrows();
void DoesntThrow() noexcept;
struct MockMethodNoexceptSpecifier {
  MOCK_METHOD(void, func1, (), (noexcept));
  MOCK_METHOD(void, func2, (), (noexcept(true)));
  MOCK_METHOD(void, func3, (), (noexcept(false)));
  MOCK_METHOD(void, func4, (), (noexcept(noexcept(MaybeThrows()))));
  MOCK_METHOD(void, func5, (), (noexcept(noexcept(DoesntThrow()))));
  MOCK_METHOD(void, func6, (), (noexcept(noexcept(DoesntThrow())), const));
  MOCK_METHOD(void, func7, (), (const, noexcept(noexcept(DoesntThrow()))));
  // Put commas in the noexcept expression
  MOCK_METHOD(void, func8, (), (noexcept(noexcept(hasTwoParams(1, 2))), const));
};

TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) {
  EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func1()));
  EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func2()));
  EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func3()));
  EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func4()));
  EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func5()));
  EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func6()));
  EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func7()));
  EXPECT_EQ(noexcept(std::declval<MockMethodNoexceptSpecifier>().func8()),
            noexcept(hasTwoParams(1, 2)));
}

Abseil Team's avatar
Abseil Team committed
982
983
}  // namespace gmock_function_mocker_test
}  // namespace testing