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

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

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

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

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

namespace testing {
namespace gmock_function_mocker_test {

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

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

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

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

  virtual void VoidReturning(int x) = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Abseil Team's avatar
Abseil Team committed
204
205
206
 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};
Abseil Team's avatar
Abseil Team committed
207
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

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
265
266
267
268
269
270
271
272
273
274
275
  // 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
276
277
278
279
 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockFoo);
};

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

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
495
496
497
class MockB {
 public:
  MockB() {}

  MOCK_METHOD(void, DoB, ());

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB);
};

Abseil Team's avatar
Abseil Team committed
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
class LegacyMockB {
 public:
  LegacyMockB() {}

  MOCK_METHOD0(DoB, void());

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockB);
};

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

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

  {
Abseil Team's avatar
Abseil Team committed
524
    TypeParam b;
Abseil Team's avatar
Abseil Team committed
525
526
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
562
    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:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack);
};

Abseil Team's avatar
Abseil Team committed
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
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:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStack);
};

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

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

  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
608
609
TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
610
611

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

  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:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStackWithCallType);
};

Abseil Team's avatar
Abseil Team committed
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
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:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStackWithCallType);
};

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
673
// Tests that template mock with calltype works.
Abseil Team's avatar
Abseil Team committed
674
675
TYPED_TEST(TemplateMockTestWithCallType, Works) {
  TypeParam mock;
Abseil Team's avatar
Abseil Team committed
676
677
678
679
680
681
682

  EXPECT_CALL(mock, GetSize())
      .WillOnce(Return(0))
      .WillOnce(Return(1))
      .WillOnce(Return(0));
  EXPECT_CALL(mock, Push(_));
  int n = 5;
683
684
  EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));
  EXPECT_CALL(mock, Pop()).Times(AnyNumber());
Abseil Team's avatar
Abseil Team committed
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

  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
700
701
702
703
704
#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
705
706
707
708
709
710
711
712
713
714
class MockOverloadedOnArgNumber {
 public:
  MockOverloadedOnArgNumber() {}

  MY_MOCK_METHODS1_;

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber);
};

Abseil Team's avatar
Abseil Team committed
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
class LegacyMockOverloadedOnArgNumber {
 public:
  LegacyMockOverloadedOnArgNumber() {}

  LEGACY_MY_MOCK_METHODS1_;

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockOverloadedOnArgNumber);
};

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
734
735
736
737
738
739
740
741
742
  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));
}

743
744
745
#define MY_MOCK_METHODS2_                     \
  MOCK_CONST_METHOD1(Overloaded, int(int n)); \
  MOCK_METHOD1(Overloaded, int(int n))
Abseil Team's avatar
Abseil Team committed
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774

class MockOverloadedOnConstness {
 public:
  MockOverloadedOnConstness() {}

  MY_MOCK_METHODS2_;

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnConstness);
};

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;
775
  EXPECT_CALL(foo, Call()).WillOnce(Return(1)).WillOnce(Return(2));
Abseil Team's avatar
Abseil Team committed
776
777
778
779
780
781
782
783
784
785
786
787
  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;
788
789
  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
790
791
792
793
794
795
  EXPECT_EQ(1, foo.Call(false, 42));
  EXPECT_EQ(2, foo.Call(false, 42));
  EXPECT_EQ(3, foo.Call(true, 120));
}

TEST(MockMethodMockFunctionTest, WorksFor10Arguments) {
796
797
798
  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
799
800
801
802
803
804
805
806
807
  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;
808
  auto call = [](const std::function<int(int)>& f, int i) { return f(i); };
Abseil Team's avatar
Abseil Team committed
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
  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) {
826
827
  MockFunction<int(int&)> foo;
  auto call = [](const std::function<int(int&)>& f, int& i) { return f(i); };
Abseil Team's avatar
Abseil Team committed
828
829
830
831
832
  int i = 42;
  EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1));
  EXPECT_EQ(-1, call(foo.AsStdFunction(), i));
}

833
834
835
namespace {

template <typename Expected, typename F>
836
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
Abseil Team's avatar
Abseil Team committed
837
    const internal::MockFunction<F>&) {
838
839
840
  return std::is_same<F, Expected>::value;
}

841
}  // namespace
842
843

template <typename F>
844
class MockMethodMockFunctionSignatureTest : public Test {};
845

846
847
848
849
850
851
852
853
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) {
854
855
  using Argument = TypeParam;
  MockFunction<Argument> foo;
Abseil Team's avatar
Abseil Team committed
856
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
857
858
}

859
860
TYPED_TEST(MockMethodMockFunctionSignatureTest,
           IsMockFunctionTemplateArgumentDeducedForStdFunction) {
861
862
  using Argument = std::function<TypeParam>;
  MockFunction<Argument> foo;
Abseil Team's avatar
Abseil Team committed
863
  EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));
864
865
}

866
867
868
TYPED_TEST(
    MockMethodMockFunctionSignatureTest,
    IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {
869
  using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
870
871
  using ForStdFunction =
      decltype(&MockFunction<std::function<TypeParam>>::Call);
872
873
874
  EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}

Abseil Team's avatar
Abseil Team committed
875
template <typename F>
876
struct AlternateCallable {};
Abseil Team's avatar
Abseil Team committed
877
878
879
880
881
882
883
884

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

885
886
TYPED_TEST(MockMethodMockFunctionSignatureTest,
           IsMockFunctionCallMethodSignatureTheSameForAlternateCallable) {
Abseil Team's avatar
Abseil Team committed
887
  using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
888
  using ForStdFunction =
Abseil Team's avatar
Abseil Team committed
889
      decltype(&MockFunction<std::function<TypeParam>>::Call);
890
891
  EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}
Abseil Team's avatar
Abseil Team committed
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908

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
909
struct LegacyMockMethodSizes0 {
910
  MOCK_METHOD0(func, void());
Abseil Team's avatar
Abseil Team committed
911
912
};
struct LegacyMockMethodSizes1 {
913
  MOCK_METHOD1(func, void(int));
Abseil Team's avatar
Abseil Team committed
914
915
};
struct LegacyMockMethodSizes2 {
916
  MOCK_METHOD2(func, void(int, int));
Abseil Team's avatar
Abseil Team committed
917
918
};
struct LegacyMockMethodSizes3 {
919
  MOCK_METHOD3(func, void(int, int, int));
Abseil Team's avatar
Abseil Team committed
920
921
};
struct LegacyMockMethodSizes4 {
922
  MOCK_METHOD4(func, void(int, int, int, int));
Abseil Team's avatar
Abseil Team committed
923
924
};

Abseil Team's avatar
Abseil Team committed
925
926
927
928
929
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
930
931
932
933
934
935
936

  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
937
938
}

939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
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
966
967
}  // namespace gmock_function_mocker_test
}  // namespace testing