gmock-function-mocker_test.cc 34.1 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
// Silence C4503 (decorated name length exceeded) for MSVC.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4503)

Abseil Team's avatar
Abseil Team committed
38
39
40
41
#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.
42
#include <objbase.h>
Abseil Team's avatar
Abseil Team committed
43
44
#endif  // GTEST_OS_WINDOWS

45
#include <functional>
Abseil Team's avatar
Abseil Team committed
46
47
#include <map>
#include <string>
48
49
#include <type_traits>

Abseil Team's avatar
Abseil Team committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#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;

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

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

Abseil Team's avatar
Abseil Team committed
79
80
81
82
83
84
85
86
class FooInterface {
 public:
  virtual ~FooInterface() {}

  virtual void VoidReturning(int x) = 0;

  virtual int Nullary() = 0;
  virtual bool Unary(int x) = 0;
87
  virtual long Binary(short x, int y) = 0;                     // NOLINT
Abseil Team's avatar
Abseil Team committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  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
107
  virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;
Abseil Team's avatar
Abseil Team committed
108

Abseil Team's avatar
Abseil Team committed
109
110
111
112
  virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
  using fn_ptr = int (*)(bool);
  virtual fn_ptr ReturnsFunctionPointer2(int) = 0;

Abseil Team's avatar
Abseil Team committed
113
114
115
116
117
118
119
120
121
122
  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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#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.
137
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4373)
Abseil Team's avatar
Abseil Team committed
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
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
};

282
GTEST_DISABLE_MSC_WARNINGS_POP_()  // 4373
Abseil Team's avatar
Abseil Team committed
283

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

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

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

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

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

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

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

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

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

// Tests mocking a decimal function.
Abseil Team's avatar
Abseil Team committed
327
328
329
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
330
331
      .WillOnce(Return(5));

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

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

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

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

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

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

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

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

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

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

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

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

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

Abseil Team's avatar
Abseil Team committed
392
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {
Abseil Team's avatar
Abseil Team committed
393
  const std::map<int, std::string> a_map;
Abseil Team's avatar
Abseil Team committed
394
395
  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
396

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

Abseil Team's avatar
Abseil Team committed
401
402
403
404
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
405
406
}

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

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

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

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

// Tests mocking a decimal function with calltype.
Abseil Team's avatar
Abseil Team committed
430
431
432
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
433
434
      .WillOnce(Return(10));

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

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

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

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

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

#endif  // GTEST_OS_WINDOWS

Abseil Team's avatar
Abseil Team committed
454
455
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
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
488
489
490
491
492
493
494
class MockB {
 public:
  MockB() {}

  MOCK_METHOD(void, DoB, ());

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

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

  MOCK_METHOD0(DoB, void());

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

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
515
516
// Tests that functions with no EXPECT_CALL() rules can be called any
// number of times.
Abseil Team's avatar
Abseil Team committed
517
518
TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
  { TypeParam b; }
Abseil Team's avatar
Abseil Team committed
519
520

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

  {
Abseil Team's avatar
Abseil Team committed
526
    TypeParam b;
Abseil Team's avatar
Abseil Team committed
527
528
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
    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:
562
563
  MockStack(const MockStack&) = delete;
  MockStack& operator=(const MockStack&) = delete;
Abseil Team's avatar
Abseil Team committed
564
565
};

Abseil Team's avatar
Abseil Team committed
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
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:
581
582
  LegacyMockStack(const LegacyMockStack&) = delete;
  LegacyMockStack& operator=(const LegacyMockStack&) = delete;
Abseil Team's avatar
Abseil Team committed
583
584
585
586
587
588
589
590
};

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
591
// Tests that template mock works.
Abseil Team's avatar
Abseil Team committed
592
593
TYPED_TEST(TemplateMockTest, Works) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
594
595
596
597
598
599
600

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

  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
612
613
TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
614
615

  const std::map<int, int> a_map;
616
617
  EXPECT_CALL(mock, ReturnTypeWithComma()).WillOnce(Return(a_map));
  EXPECT_CALL(mock, ReturnTypeWithComma(1)).WillOnce(Return(a_map));
Abseil Team's avatar
Abseil Team committed
618
619
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

  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:
652
653
  MockStackWithCallType(const MockStackWithCallType&) = delete;
  MockStackWithCallType& operator=(const MockStackWithCallType&) = delete;
Abseil Team's avatar
Abseil Team committed
654
655
};

Abseil Team's avatar
Abseil Team committed
656
657
658
659
660
661
662
663
664
665
666
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:
667
668
669
  LegacyMockStackWithCallType(const LegacyMockStackWithCallType&) = delete;
  LegacyMockStackWithCallType& operator=(const LegacyMockStackWithCallType&) =
      delete;
Abseil Team's avatar
Abseil Team committed
670
671
672
673
674
675
676
677
678
679
};

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
680
// Tests that template mock with calltype works.
Abseil Team's avatar
Abseil Team committed
681
682
TYPED_TEST(TemplateMockTestWithCallType, Works) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
683
684
685
686
687
688
689

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

  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
707
708
709
710
711
#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
712
713
714
715
716
717
718
class MockOverloadedOnArgNumber {
 public:
  MockOverloadedOnArgNumber() {}

  MY_MOCK_METHODS1_;

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

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

  LEGACY_MY_MOCK_METHODS1_;

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

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
746
747
748
749
750
751
752
753
754
  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));
}

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

class MockOverloadedOnConstness {
 public:
  MockOverloadedOnConstness() {}

  MY_MOCK_METHODS2_;

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

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;
789
  EXPECT_CALL(foo, Call()).WillOnce(Return(1)).WillOnce(Return(2));
Abseil Team's avatar
Abseil Team committed
790
791
792
793
794
795
796
797
798
799
800
801
  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;
802
803
  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
804
805
806
807
808
809
  EXPECT_EQ(1, foo.Call(false, 42));
  EXPECT_EQ(2, foo.Call(false, 42));
  EXPECT_EQ(3, foo.Call(true, 120));
}

TEST(MockMethodMockFunctionTest, WorksFor10Arguments) {
810
811
812
  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
813
814
815
816
817
818
819
820
821
  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;
822
  auto call = [](const std::function<int(int)>& f, int i) { return f(i); };
Abseil Team's avatar
Abseil Team committed
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
  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) {
840
841
  MockFunction<int(int&)> foo;
  auto call = [](const std::function<int(int&)>& f, int& i) { return f(i); };
Abseil Team's avatar
Abseil Team committed
842
843
844
845
846
  int i = 42;
  EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1));
  EXPECT_EQ(-1, call(foo.AsStdFunction(), i));
}

847
848
849
namespace {

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

855
}  // namespace
856
857

template <typename F>
858
class MockMethodMockFunctionSignatureTest : public Test {};
859

860
861
862
863
864
865
866
867
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) {
868
869
  using Argument = TypeParam;
  MockFunction<Argument> foo;
Abseil Team's avatar
Abseil Team committed
870
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
871
872
}

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

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

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

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

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

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
923
struct LegacyMockMethodSizes0 {
924
  MOCK_METHOD0(func, void());
Abseil Team's avatar
Abseil Team committed
925
926
};
struct LegacyMockMethodSizes1 {
927
  MOCK_METHOD1(func, void(int));
Abseil Team's avatar
Abseil Team committed
928
929
};
struct LegacyMockMethodSizes2 {
930
  MOCK_METHOD2(func, void(int, int));
Abseil Team's avatar
Abseil Team committed
931
932
};
struct LegacyMockMethodSizes3 {
933
  MOCK_METHOD3(func, void(int, int, int));
Abseil Team's avatar
Abseil Team committed
934
935
};
struct LegacyMockMethodSizes4 {
936
  MOCK_METHOD4(func, void(int, int, int, int));
Abseil Team's avatar
Abseil Team committed
937
938
};

Abseil Team's avatar
Abseil Team committed
939
940
941
942
943
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
944
945
946
947
948
949
950

  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
951
952
}

953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
TEST(MockMethodMockFunctionTest, EnsureNoUnusedMemberFunction) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic error "-Wunused-member-function"
#endif
  // https://github.com/google/googletest/issues/4052
  struct Foo {
    MOCK_METHOD(void, foo, ());
  };
  EXPECT_CALL(Foo(), foo()).Times(0);
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}

968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
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
995
996
}  // namespace gmock_function_mocker_test
}  // namespace testing
997
998

GTEST_DISABLE_MSC_WARNINGS_POP_()  // 4503