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
// 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.

30
31
32
33
34
35
// Silence C4503 (decorated name length exceeded) for MSVC.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4503)
#endif

Abseil Team's avatar
Abseil Team committed
36
37
38
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the function mocker classes.
Abseil Team's avatar
Abseil Team committed
39
#include "gmock/gmock-function-mocker.h"
Abseil Team's avatar
Abseil Team committed
40
41
42
43
44

#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.
45
#include <objbase.h>
Abseil Team's avatar
Abseil Team committed
46
47
#endif  // GTEST_OS_WINDOWS

48
#include <functional>
Abseil Team's avatar
Abseil Team committed
49
50
#include <map>
#include <string>
51
52
#include <type_traits>

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

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

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

Abseil Team's avatar
Abseil Team committed
82
83
84
85
86
87
88
89
class FooInterface {
 public:
  virtual ~FooInterface() {}

  virtual void VoidReturning(int x) = 0;

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

Abseil Team's avatar
Abseil Team committed
112
113
114
115
  virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
  using fn_ptr = int (*)(bool);
  virtual fn_ptr ReturnsFunctionPointer2(int) = 0;

Abseil Team's avatar
Abseil Team committed
116
117
118
119
120
121
122
123
124
125
  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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#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
141
142
#pragma warning(push)
#pragma warning(disable : 4373)
Abseil Team's avatar
Abseil Team committed
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
175
176
177
178
179
180
#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
181
182
  MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
              (const TemplatedCopyable<int>&));  // NOLINT
Abseil Team's avatar
Abseil Team committed
183

Abseil Team's avatar
Abseil Team committed
184
185
186
  MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
  MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());

Abseil Team's avatar
Abseil Team committed
187
188
189
190
191
192
193
194
195
196
197
198
#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
199
200
201
202
203
204
205
206
207
208
209
  // 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
210
 private:
211
212
  MockFoo(const MockFoo&) = delete;
  MockFoo& operator=(const MockFoo&) = delete;
Abseil Team's avatar
Abseil Team committed
213
};
Abseil Team's avatar
Abseil Team committed
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
266
267
268
269
270
271

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
272
273
274
275
276
277
278
279
280
281
282
  // 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
283
 private:
284
285
  LegacyMockFoo(const LegacyMockFoo&) = delete;
  LegacyMockFoo& operator=(const LegacyMockFoo&) = delete;
Abseil Team's avatar
Abseil Team committed
286
287
};

Abseil Team's avatar
Abseil Team committed
288
#ifdef _MSC_VER
289
#pragma warning(pop)
Abseil Team's avatar
Abseil Team committed
290
291
#endif

Abseil Team's avatar
Abseil Team committed
292
293
template <class T>
class FunctionMockerTest : public testing::Test {
Abseil Team's avatar
Abseil Team committed
294
 protected:
Abseil Team's avatar
Abseil Team committed
295
  FunctionMockerTest() : foo_(&mock_foo_) {}
Abseil Team's avatar
Abseil Team committed
296
297

  FooInterface* const foo_;
Abseil Team's avatar
Abseil Team committed
298
  T mock_foo_;
Abseil Team's avatar
Abseil Team committed
299
};
Abseil Team's avatar
Abseil Team committed
300
301
using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>;
TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes);
Abseil Team's avatar
Abseil Team committed
302
303

// Tests mocking a void-returning function.
Abseil Team's avatar
Abseil Team committed
304
305
306
TYPED_TEST(FunctionMockerTest, MocksVoidFunction) {
  EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100)));
  this->foo_->VoidReturning(0);
Abseil Team's avatar
Abseil Team committed
307
308
309
}

// Tests mocking a nullary function.
Abseil Team's avatar
Abseil Team committed
310
311
TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) {
  EXPECT_CALL(this->mock_foo_, Nullary())
Abseil Team's avatar
Abseil Team committed
312
313
314
      .WillOnce(DoDefault())
      .WillOnce(Return(1));

Abseil Team's avatar
Abseil Team committed
315
316
  EXPECT_EQ(0, this->foo_->Nullary());
  EXPECT_EQ(1, this->foo_->Nullary());
Abseil Team's avatar
Abseil Team committed
317
318
319
}

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

Abseil Team's avatar
Abseil Team committed
323
324
  EXPECT_TRUE(this->foo_->Unary(2));
  EXPECT_FALSE(this->foo_->Unary(2));
Abseil Team's avatar
Abseil Team committed
325
326
327
}

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

Abseil Team's avatar
Abseil Team committed
331
  EXPECT_EQ(3, this->foo_->Binary(2, 1));
Abseil Team's avatar
Abseil Team committed
332
333
334
}

// Tests mocking a decimal function.
Abseil Team's avatar
Abseil Team committed
335
336
337
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
338
339
      .WillOnce(Return(5));

Abseil Team's avatar
Abseil Team committed
340
  EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi"));
Abseil Team's avatar
Abseil Team committed
341
342
343
}

// Tests mocking a function that takes a non-const reference.
Abseil Team's avatar
Abseil Team committed
344
TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
Abseil Team's avatar
Abseil Team committed
345
  int a = 0;
Abseil Team's avatar
Abseil Team committed
346
  EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a)))
Abseil Team's avatar
Abseil Team committed
347
348
      .WillOnce(Return(true));

Abseil Team's avatar
Abseil Team committed
349
  EXPECT_TRUE(this->foo_->TakesNonConstReference(a));
Abseil Team's avatar
Abseil Team committed
350
351
352
}

// Tests mocking a function that takes a const reference.
Abseil Team's avatar
Abseil Team committed
353
TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
Abseil Team's avatar
Abseil Team committed
354
  int a = 0;
Abseil Team's avatar
Abseil Team committed
355
  EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a)))
Abseil Team's avatar
Abseil Team committed
356
357
      .WillOnce(Return("Hello"));

Abseil Team's avatar
Abseil Team committed
358
  EXPECT_EQ("Hello", this->foo_->TakesConstReference(a));
Abseil Team's avatar
Abseil Team committed
359
360
361
}

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

Abseil Team's avatar
Abseil Team committed
365
  EXPECT_FALSE(this->foo_->TakesConst(5));
Abseil Team's avatar
Abseil Team committed
366
367
368
}

// Tests mocking functions overloaded on the number of arguments.
Abseil Team's avatar
Abseil Team committed
369
370
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber())
Abseil Team's avatar
Abseil Team committed
371
      .WillOnce(Return(1));
Abseil Team's avatar
Abseil Team committed
372
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_))
Abseil Team's avatar
Abseil Team committed
373
374
      .WillOnce(Return(2));

Abseil Team's avatar
Abseil Team committed
375
376
  EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1));
  EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber());
Abseil Team's avatar
Abseil Team committed
377
378
379
}

// Tests mocking functions overloaded on the types of argument.
Abseil Team's avatar
Abseil Team committed
380
381
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>()))
Abseil Team's avatar
Abseil Team committed
382
      .WillOnce(Return(1));
Abseil Team's avatar
Abseil Team committed
383
  EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
Abseil Team's avatar
Abseil Team committed
384
385
      .WillOnce(Return('b'));

Abseil Team's avatar
Abseil Team committed
386
387
  EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0));
  EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a'));
Abseil Team's avatar
Abseil Team committed
388
389
390
}

// Tests mocking functions overloaded on the const-ness of this object.
Abseil Team's avatar
Abseil Team committed
391
392
393
TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
  EXPECT_CALL(this->mock_foo_, OverloadedOnConstness());
  EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness())
Abseil Team's avatar
Abseil Team committed
394
395
      .WillOnce(Return('a'));

Abseil Team's avatar
Abseil Team committed
396
397
  EXPECT_EQ(0, this->foo_->OverloadedOnConstness());
  EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness());
Abseil Team's avatar
Abseil Team committed
398
399
}

Abseil Team's avatar
Abseil Team committed
400
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {
Abseil Team's avatar
Abseil Team committed
401
  const std::map<int, std::string> a_map;
Abseil Team's avatar
Abseil Team committed
402
403
  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
404

Abseil Team's avatar
Abseil Team committed
405
406
  EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma());
  EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42));
Abseil Team's avatar
Abseil Team committed
407
408
}

Abseil Team's avatar
Abseil Team committed
409
410
411
412
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
413
414
}

Abseil Team's avatar
Abseil Team committed
415
416
#if GTEST_OS_WINDOWS
// Tests mocking a nullary function with calltype.
Abseil Team's avatar
Abseil Team committed
417
418
TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
  EXPECT_CALL(this->mock_foo_, CTNullary())
Abseil Team's avatar
Abseil Team committed
419
420
421
      .WillOnce(Return(-1))
      .WillOnce(Return(0));

Abseil Team's avatar
Abseil Team committed
422
423
  EXPECT_EQ(-1, this->foo_->CTNullary());
  EXPECT_EQ(0, this->foo_->CTNullary());
Abseil Team's avatar
Abseil Team committed
424
425
426
}

// Tests mocking a unary function with calltype.
Abseil Team's avatar
Abseil Team committed
427
428
TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
  EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2)))
Abseil Team's avatar
Abseil Team committed
429
430
431
432
      .Times(2)
      .WillOnce(Return(true))
      .WillOnce(Return(false));

Abseil Team's avatar
Abseil Team committed
433
434
  EXPECT_TRUE(this->foo_->CTUnary(2));
  EXPECT_FALSE(this->foo_->CTUnary(2));
Abseil Team's avatar
Abseil Team committed
435
436
437
}

// Tests mocking a decimal function with calltype.
Abseil Team's avatar
Abseil Team committed
438
439
440
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
441
442
      .WillOnce(Return(10));

Abseil Team's avatar
Abseil Team committed
443
  EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
Abseil Team's avatar
Abseil Team committed
444
445
446
}

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

Abseil Team's avatar
Abseil Team committed
450
  EXPECT_EQ('a', Const(*this->foo_).CTConst(0));
Abseil Team's avatar
Abseil Team committed
451
452
}

Abseil Team's avatar
Abseil Team committed
453
TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
Abseil Team's avatar
Abseil Team committed
454
  const std::map<int, std::string> a_map;
Abseil Team's avatar
Abseil Team committed
455
  EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map));
Abseil Team's avatar
Abseil Team committed
456

Abseil Team's avatar
Abseil Team committed
457
  EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma());
Abseil Team's avatar
Abseil Team committed
458
459
460
461
}

#endif  // GTEST_OS_WINDOWS

Abseil Team's avatar
Abseil Team committed
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
490
491
492
493
494
495
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
496
497
498
499
500
501
502
class MockB {
 public:
  MockB() {}

  MOCK_METHOD(void, DoB, ());

 private:
503
504
  MockB(const MockB&) = delete;
  MockB& operator=(const MockB&) = delete;
Abseil Team's avatar
Abseil Team committed
505
506
};

Abseil Team's avatar
Abseil Team committed
507
508
509
510
511
512
513
class LegacyMockB {
 public:
  LegacyMockB() {}

  MOCK_METHOD0(DoB, void());

 private:
514
515
  LegacyMockB(const LegacyMockB&) = delete;
  LegacyMockB& operator=(const LegacyMockB&) = delete;
Abseil Team's avatar
Abseil Team committed
516
517
518
519
520
521
522
};

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
523
524
// Tests that functions with no EXPECT_CALL() rules can be called any
// number of times.
Abseil Team's avatar
Abseil Team committed
525
526
TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
  { TypeParam b; }
Abseil Team's avatar
Abseil Team committed
527
528

  {
Abseil Team's avatar
Abseil Team committed
529
    TypeParam b;
Abseil Team's avatar
Abseil Team committed
530
531
532
533
    b.DoB();
  }

  {
Abseil Team's avatar
Abseil Team committed
534
    TypeParam b;
Abseil Team's avatar
Abseil Team committed
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
564
565
566
567
568
569
    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:
570
571
  MockStack(const MockStack&) = delete;
  MockStack& operator=(const MockStack&) = delete;
Abseil Team's avatar
Abseil Team committed
572
573
};

Abseil Team's avatar
Abseil Team committed
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
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:
589
590
  LegacyMockStack(const LegacyMockStack&) = delete;
  LegacyMockStack& operator=(const LegacyMockStack&) = delete;
Abseil Team's avatar
Abseil Team committed
591
592
593
594
595
596
597
598
};

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
599
// Tests that template mock works.
Abseil Team's avatar
Abseil Team committed
600
601
TYPED_TEST(TemplateMockTest, Works) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
602
603
604
605
606
607
608

  EXPECT_CALL(mock, GetSize())
      .WillOnce(Return(0))
      .WillOnce(Return(1))
      .WillOnce(Return(0));
  EXPECT_CALL(mock, Push(_));
  int n = 5;
609
610
  EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));
  EXPECT_CALL(mock, Pop()).Times(AnyNumber());
Abseil Team's avatar
Abseil Team committed
611
612
613
614
615
616
617
618
619

  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
620
621
TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
622
623

  const std::map<int, int> a_map;
624
625
  EXPECT_CALL(mock, ReturnTypeWithComma()).WillOnce(Return(a_map));
  EXPECT_CALL(mock, ReturnTypeWithComma(1)).WillOnce(Return(a_map));
Abseil Team's avatar
Abseil Team committed
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
654
655
656
657
658
659

  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:
660
661
  MockStackWithCallType(const MockStackWithCallType&) = delete;
  MockStackWithCallType& operator=(const MockStackWithCallType&) = delete;
Abseil Team's avatar
Abseil Team committed
662
663
};

Abseil Team's avatar
Abseil Team committed
664
665
666
667
668
669
670
671
672
673
674
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:
675
676
677
  LegacyMockStackWithCallType(const LegacyMockStackWithCallType&) = delete;
  LegacyMockStackWithCallType& operator=(const LegacyMockStackWithCallType&) =
      delete;
Abseil Team's avatar
Abseil Team committed
678
679
680
681
682
683
684
685
686
687
};

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
688
// Tests that template mock with calltype works.
Abseil Team's avatar
Abseil Team committed
689
690
TYPED_TEST(TemplateMockTestWithCallType, Works) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
691
692
693
694
695
696
697

  EXPECT_CALL(mock, GetSize())
      .WillOnce(Return(0))
      .WillOnce(Return(1))
      .WillOnce(Return(0));
  EXPECT_CALL(mock, Push(_));
  int n = 5;
698
699
  EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));
  EXPECT_CALL(mock, Pop()).Times(AnyNumber());
Abseil Team's avatar
Abseil Team committed
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

  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
715
716
717
718
719
#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
720
721
722
723
724
725
726
class MockOverloadedOnArgNumber {
 public:
  MockOverloadedOnArgNumber() {}

  MY_MOCK_METHODS1_;

 private:
727
728
729
  MockOverloadedOnArgNumber(const MockOverloadedOnArgNumber&) = delete;
  MockOverloadedOnArgNumber& operator=(const MockOverloadedOnArgNumber&) =
      delete;
Abseil Team's avatar
Abseil Team committed
730
731
};

Abseil Team's avatar
Abseil Team committed
732
733
734
735
736
737
738
class LegacyMockOverloadedOnArgNumber {
 public:
  LegacyMockOverloadedOnArgNumber() {}

  LEGACY_MY_MOCK_METHODS1_;

 private:
739
740
741
742
  LegacyMockOverloadedOnArgNumber(const LegacyMockOverloadedOnArgNumber&) =
      delete;
  LegacyMockOverloadedOnArgNumber& operator=(
      const LegacyMockOverloadedOnArgNumber&) = delete;
Abseil Team's avatar
Abseil Team committed
743
744
745
746
747
748
749
750
751
752
753
};

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
754
755
756
757
758
759
760
761
762
  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));
}

763
764
765
#define MY_MOCK_METHODS2_                     \
  MOCK_CONST_METHOD1(Overloaded, int(int n)); \
  MOCK_METHOD1(Overloaded, int(int n))
Abseil Team's avatar
Abseil Team committed
766
767
768
769
770
771
772
773

class MockOverloadedOnConstness {
 public:
  MockOverloadedOnConstness() {}

  MY_MOCK_METHODS2_;

 private:
774
775
776
  MockOverloadedOnConstness(const MockOverloadedOnConstness&) = delete;
  MockOverloadedOnConstness& operator=(const MockOverloadedOnConstness&) =
      delete;
Abseil Team's avatar
Abseil Team committed
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
};

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;
797
  EXPECT_CALL(foo, Call()).WillOnce(Return(1)).WillOnce(Return(2));
Abseil Team's avatar
Abseil Team committed
798
799
800
801
802
803
804
805
806
807
808
809
  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;
810
811
  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
812
813
814
815
816
817
  EXPECT_EQ(1, foo.Call(false, 42));
  EXPECT_EQ(2, foo.Call(false, 42));
  EXPECT_EQ(3, foo.Call(true, 120));
}

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

855
856
857
namespace {

template <typename Expected, typename F>
858
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
Abseil Team's avatar
Abseil Team committed
859
    const internal::MockFunction<F>&) {
860
861
862
  return std::is_same<F, Expected>::value;
}

863
}  // namespace
864
865

template <typename F>
866
class MockMethodMockFunctionSignatureTest : public Test {};
867

868
869
870
871
872
873
874
875
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) {
876
877
  using Argument = TypeParam;
  MockFunction<Argument> foo;
Abseil Team's avatar
Abseil Team committed
878
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
879
880
}

881
882
TYPED_TEST(MockMethodMockFunctionSignatureTest,
           IsMockFunctionTemplateArgumentDeducedForStdFunction) {
883
884
  using Argument = std::function<TypeParam>;
  MockFunction<Argument> foo;
Abseil Team's avatar
Abseil Team committed
885
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
886
887
}

888
889
890
TYPED_TEST(
    MockMethodMockFunctionSignatureTest,
    IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {
891
  using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
892
893
  using ForStdFunction =
      decltype(&MockFunction<std::function<TypeParam>>::Call);
894
895
896
  EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}

Abseil Team's avatar
Abseil Team committed
897
template <typename F>
898
struct AlternateCallable {};
Abseil Team's avatar
Abseil Team committed
899
900
901
902
903
904
905
906

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

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

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
931
struct LegacyMockMethodSizes0 {
932
  MOCK_METHOD0(func, void());
Abseil Team's avatar
Abseil Team committed
933
934
};
struct LegacyMockMethodSizes1 {
935
  MOCK_METHOD1(func, void(int));
Abseil Team's avatar
Abseil Team committed
936
937
};
struct LegacyMockMethodSizes2 {
938
  MOCK_METHOD2(func, void(int, int));
Abseil Team's avatar
Abseil Team committed
939
940
};
struct LegacyMockMethodSizes3 {
941
  MOCK_METHOD3(func, void(int, int, int));
Abseil Team's avatar
Abseil Team committed
942
943
};
struct LegacyMockMethodSizes4 {
944
  MOCK_METHOD4(func, void(int, int, int, int));
Abseil Team's avatar
Abseil Team committed
945
946
};

Abseil Team's avatar
Abseil Team committed
947
948
949
950
951
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
952
953
954
955
956
957
958

  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
959
960
}

961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
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
}

976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
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
1003
1004
}  // namespace gmock_function_mocker_test
}  // namespace testing