blob: 95077768cb024a76f04f6522fd3f6bad2521a8e7 [file] [log] [blame]
zhanyong.wana18423e2009-07-22 23:58:19 +00001// Copyright 2007, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Author: wan@google.com (Zhanyong Wan)
31
32// Google Mock - a framework for writing C++ mock classes.
33//
34// This file tests the built-in actions in gmock-more-actions.h.
35
36#include <gmock/gmock-more-actions.h>
37
38#include <functional>
39#include <sstream>
40#include <string>
41#include <gmock/gmock.h>
42#include <gtest/gtest.h>
43
44namespace testing {
45namespace gmock_more_actions_test {
46
47using ::std::plus;
48using ::std::string;
49using ::std::tr1::get;
50using ::std::tr1::make_tuple;
51using ::std::tr1::tuple;
52using ::std::tr1::tuple_element;
53using testing::_;
54using testing::Action;
55using testing::ActionInterface;
56using testing::DeleteArg;
57using testing::Invoke;
58using testing::Return;
59using testing::ReturnArg;
60using testing::SaveArg;
61using testing::SetArgReferee;
62using testing::SetArgumentPointee;
63using testing::StaticAssertTypeEq;
64using testing::Unused;
65using testing::WithArg;
66using testing::WithoutArgs;
67
68// Sample functions and functors for testing Invoke() and etc.
69int Nullary() { return 1; }
70
71class NullaryFunctor {
72 public:
73 int operator()() { return 2; }
74};
75
76bool g_done = false;
77void VoidNullary() { g_done = true; }
78
79class VoidNullaryFunctor {
80 public:
81 void operator()() { g_done = true; }
82};
83
84bool Unary(int x) { return x < 0; }
85
86const char* Plus1(const char* s) { return s + 1; }
87
88void VoidUnary(int n) { g_done = true; }
89
90bool ByConstRef(const string& s) { return s == "Hi"; }
91
92const double g_double = 0;
93bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
94
95string ByNonConstRef(string& s) { return s += "+"; } // NOLINT
96
97struct UnaryFunctor {
98 int operator()(bool x) { return x ? 1 : -1; }
99};
100
101const char* Binary(const char* input, short n) { return input + n; } // NOLINT
102
103void VoidBinary(int, char) { g_done = true; }
104
105int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
106
107void VoidTernary(int, char, bool) { g_done = true; }
108
109int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
110
111int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
112
113void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
114
115string Concat4(const char* s1, const char* s2, const char* s3,
116 const char* s4) {
117 return string(s1) + s2 + s3 + s4;
118}
119
120int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
121
122struct SumOf5Functor {
123 int operator()(int a, int b, int c, int d, int e) {
124 return a + b + c + d + e;
125 }
126};
127
128string Concat5(const char* s1, const char* s2, const char* s3,
129 const char* s4, const char* s5) {
130 return string(s1) + s2 + s3 + s4 + s5;
131}
132
133int SumOf6(int a, int b, int c, int d, int e, int f) {
134 return a + b + c + d + e + f;
135}
136
137struct SumOf6Functor {
138 int operator()(int a, int b, int c, int d, int e, int f) {
139 return a + b + c + d + e + f;
140 }
141};
142
143string Concat6(const char* s1, const char* s2, const char* s3,
144 const char* s4, const char* s5, const char* s6) {
145 return string(s1) + s2 + s3 + s4 + s5 + s6;
146}
147
148string Concat7(const char* s1, const char* s2, const char* s3,
149 const char* s4, const char* s5, const char* s6,
150 const char* s7) {
151 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
152}
153
154string Concat8(const char* s1, const char* s2, const char* s3,
155 const char* s4, const char* s5, const char* s6,
156 const char* s7, const char* s8) {
157 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
158}
159
160string Concat9(const char* s1, const char* s2, const char* s3,
161 const char* s4, const char* s5, const char* s6,
162 const char* s7, const char* s8, const char* s9) {
163 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
164}
165
166string Concat10(const char* s1, const char* s2, const char* s3,
167 const char* s4, const char* s5, const char* s6,
168 const char* s7, const char* s8, const char* s9,
169 const char* s10) {
170 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
171}
172
173class Foo {
174 public:
175 Foo() : value_(123) {}
176
177 int Nullary() const { return value_; }
178
179 short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
180
181 string Binary(const string& str, char c) const { return str + c; }
182
183 int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
184
185 int SumOf4(int a, int b, int c, int d) const {
186 return a + b + c + d + value_;
187 }
188
189 int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
190
191 int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
192
193 int SumOf6(int a, int b, int c, int d, int e, int f) {
194 return a + b + c + d + e + f;
195 }
196
197 string Concat7(const char* s1, const char* s2, const char* s3,
198 const char* s4, const char* s5, const char* s6,
199 const char* s7) {
200 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
201 }
202
203 string Concat8(const char* s1, const char* s2, const char* s3,
204 const char* s4, const char* s5, const char* s6,
205 const char* s7, const char* s8) {
206 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
207 }
208
209 string Concat9(const char* s1, const char* s2, const char* s3,
210 const char* s4, const char* s5, const char* s6,
211 const char* s7, const char* s8, const char* s9) {
212 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
213 }
214
215 string Concat10(const char* s1, const char* s2, const char* s3,
216 const char* s4, const char* s5, const char* s6,
217 const char* s7, const char* s8, const char* s9,
218 const char* s10) {
219 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
220 }
221 private:
222 int value_;
223};
224
225// Tests using Invoke() with a nullary function.
226TEST(InvokeTest, Nullary) {
227 Action<int()> a = Invoke(Nullary); // NOLINT
228 EXPECT_EQ(1, a.Perform(make_tuple()));
229}
230
231// Tests using Invoke() with a unary function.
232TEST(InvokeTest, Unary) {
233 Action<bool(int)> a = Invoke(Unary); // NOLINT
234 EXPECT_FALSE(a.Perform(make_tuple(1)));
235 EXPECT_TRUE(a.Perform(make_tuple(-1)));
236}
237
238// Tests using Invoke() with a binary function.
239TEST(InvokeTest, Binary) {
240 Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
241 const char* p = "Hello";
242 EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
243}
244
245// Tests using Invoke() with a ternary function.
246TEST(InvokeTest, Ternary) {
247 Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
248 EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
249}
250
251// Tests using Invoke() with a 4-argument function.
252TEST(InvokeTest, FunctionThatTakes4Arguments) {
253 Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
254 EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
255}
256
257// Tests using Invoke() with a 5-argument function.
258TEST(InvokeTest, FunctionThatTakes5Arguments) {
259 Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
260 EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
261}
262
263// Tests using Invoke() with a 6-argument function.
264TEST(InvokeTest, FunctionThatTakes6Arguments) {
265 Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
266 EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
267}
268
269// A helper that turns the type of a C-string literal from const
270// char[N] to const char*.
271inline const char* CharPtr(const char* s) { return s; }
272
273// Tests using Invoke() with a 7-argument function.
274TEST(InvokeTest, FunctionThatTakes7Arguments) {
275 Action<string(const char*, const char*, const char*, const char*,
276 const char*, const char*, const char*)> a =
277 Invoke(Concat7);
278 EXPECT_EQ("1234567",
279 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
280 CharPtr("4"), CharPtr("5"), CharPtr("6"),
281 CharPtr("7"))));
282}
283
284// Tests using Invoke() with a 8-argument function.
285TEST(InvokeTest, FunctionThatTakes8Arguments) {
286 Action<string(const char*, const char*, const char*, const char*,
287 const char*, const char*, const char*, const char*)> a =
288 Invoke(Concat8);
289 EXPECT_EQ("12345678",
290 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
291 CharPtr("4"), CharPtr("5"), CharPtr("6"),
292 CharPtr("7"), CharPtr("8"))));
293}
294
295// Tests using Invoke() with a 9-argument function.
296TEST(InvokeTest, FunctionThatTakes9Arguments) {
297 Action<string(const char*, const char*, const char*, const char*,
298 const char*, const char*, const char*, const char*,
299 const char*)> a = Invoke(Concat9);
300 EXPECT_EQ("123456789",
301 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
302 CharPtr("4"), CharPtr("5"), CharPtr("6"),
303 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
304}
305
306// Tests using Invoke() with a 10-argument function.
307TEST(InvokeTest, FunctionThatTakes10Arguments) {
308 Action<string(const char*, const char*, const char*, const char*,
309 const char*, const char*, const char*, const char*,
310 const char*, const char*)> a = Invoke(Concat10);
311 EXPECT_EQ("1234567890",
312 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
313 CharPtr("4"), CharPtr("5"), CharPtr("6"),
314 CharPtr("7"), CharPtr("8"), CharPtr("9"),
315 CharPtr("0"))));
316}
317
318// Tests using Invoke() with functions with parameters declared as Unused.
319TEST(InvokeTest, FunctionWithUnusedParameters) {
320 Action<int(int, int, double, const string&)> a1 =
321 Invoke(SumOfFirst2);
322 EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
323
324 Action<int(int, int, bool, int*)> a2 =
325 Invoke(SumOfFirst2);
326 EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
327}
328
329// Tests using Invoke() with methods with parameters declared as Unused.
330TEST(InvokeTest, MethodWithUnusedParameters) {
331 Foo foo;
332 Action<int(string, bool, int, int)> a1 =
333 Invoke(&foo, &Foo::SumOfLast2);
334 EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
335
336 Action<int(char, double, int, int)> a2 =
337 Invoke(&foo, &Foo::SumOfLast2);
338 EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
339}
340
341// Tests using Invoke() with a functor.
342TEST(InvokeTest, Functor) {
343 Action<int(short, char)> a = Invoke(plus<short>()); // NOLINT
344 EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
345}
346
347// Tests using Invoke(f) as an action of a compatible type.
348TEST(InvokeTest, FunctionWithCompatibleType) {
349 Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
350 EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
351}
352
353#if GMOCK_HAS_GOOGLE3_CALLBACK_
354
355// Tests IgnoreResult(Invoke(result_callback)).
356TEST(InvokeTest, IgnoreResultOfResultCallback) {
357 ResultCallback<int>* c = NewPermanentCallback(Nullary);
358 Action<void()> a = IgnoreResult(Invoke(c));
359 a.Perform(make_tuple());
360}
361
362// Tests IgnoreResult(Invoke(result_callback4)).
363TEST(InvokeTest, IgnoreResultOfResultCallback4) {
364 ResultCallback4<int, int, int, int, int>* c =
365 NewPermanentCallback(SumOf4);
366 Action<void(int, int, int, int)> a = IgnoreResult(Invoke(c));
367 a.Perform(make_tuple(1, 2, 3, 4));
368}
369
370#endif // GMOCK_HAS_GOOGLE3_CALLBACK_
371
372// Tests using Invoke() with an object pointer and a method pointer.
373
374// Tests using Invoke() with a nullary method.
375TEST(InvokeMethodTest, Nullary) {
376 Foo foo;
377 Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT
378 EXPECT_EQ(123, a.Perform(make_tuple()));
379}
380
381// Tests using Invoke() with a unary method.
382TEST(InvokeMethodTest, Unary) {
383 Foo foo;
384 Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT
385 EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
386}
387
388// Tests using Invoke() with a binary method.
389TEST(InvokeMethodTest, Binary) {
390 Foo foo;
391 Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
392 string s("Hell");
393 EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
394}
395
396// Tests using Invoke() with a ternary method.
397TEST(InvokeMethodTest, Ternary) {
398 Foo foo;
399 Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT
400 EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
401}
402
403// Tests using Invoke() with a 4-argument method.
404TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
405 Foo foo;
406 Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT
407 EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
408}
409
410// Tests using Invoke() with a 5-argument method.
411TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
412 Foo foo;
413 Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5); // NOLINT
414 EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
415}
416
417// Tests using Invoke() with a 6-argument method.
418TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
419 Foo foo;
420 Action<int(int, int, int, int, int, int)> a = // NOLINT
421 Invoke(&foo, &Foo::SumOf6);
422 EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
423}
424
425// Tests using Invoke() with a 7-argument method.
426TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
427 Foo foo;
428 Action<string(const char*, const char*, const char*, const char*,
429 const char*, const char*, const char*)> a =
430 Invoke(&foo, &Foo::Concat7);
431 EXPECT_EQ("1234567",
432 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
433 CharPtr("4"), CharPtr("5"), CharPtr("6"),
434 CharPtr("7"))));
435}
436
437// Tests using Invoke() with a 8-argument method.
438TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
439 Foo foo;
440 Action<string(const char*, const char*, const char*, const char*,
441 const char*, const char*, const char*, const char*)> a =
442 Invoke(&foo, &Foo::Concat8);
443 EXPECT_EQ("12345678",
444 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
445 CharPtr("4"), CharPtr("5"), CharPtr("6"),
446 CharPtr("7"), CharPtr("8"))));
447}
448
449// Tests using Invoke() with a 9-argument method.
450TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
451 Foo foo;
452 Action<string(const char*, const char*, const char*, const char*,
453 const char*, const char*, const char*, const char*,
454 const char*)> a = Invoke(&foo, &Foo::Concat9);
455 EXPECT_EQ("123456789",
456 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
457 CharPtr("4"), CharPtr("5"), CharPtr("6"),
458 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
459}
460
461// Tests using Invoke() with a 10-argument method.
462TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
463 Foo foo;
464 Action<string(const char*, const char*, const char*, const char*,
465 const char*, const char*, const char*, const char*,
466 const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
467 EXPECT_EQ("1234567890",
468 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
469 CharPtr("4"), CharPtr("5"), CharPtr("6"),
470 CharPtr("7"), CharPtr("8"), CharPtr("9"),
471 CharPtr("0"))));
472}
473
474// Tests using Invoke(f) as an action of a compatible type.
475TEST(InvokeMethodTest, MethodWithCompatibleType) {
476 Foo foo;
477 Action<long(int, short, char, bool)> a = // NOLINT
478 Invoke(&foo, &Foo::SumOf4);
479 EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
480}
481
482#if GMOCK_HAS_GOOGLE3_CALLBACK_
483
484// We don't have dedicated tests to verify that Invoke(callback) and
485// InvokeWithoutArgs(callback) delete the callback argument. Instead,
486// we rely on the heap checker linked in this test program to do that.
487
488// Tests that Invoke(non-permanent-callback) kills the process.
489TEST(InvokeCallbackDeathTest, RejectsNonPermanentCallback) {
490 EXPECT_DEATH({
491 Action<int()> a = Invoke(NewCallback(Nullary)); // NOLINT
492 }, "");
493}
494
495// Tests using Invoke() with a nullary callback.
496TEST(InvokeCallbackTest, Nullary) {
497 // Tests using Invoke(callback) as an action of the exact type.
498 Action<int()> a = Invoke(NewPermanentCallback(Nullary)); // NOLINT
499 EXPECT_EQ(1, a.Perform(make_tuple()));
500
501 // Tests using Invoke(callback) as an action of a compatible type.
502 Action<bool()> a2 = Invoke(NewPermanentCallback(Nullary)); // NOLINT
503 EXPECT_TRUE(a2.Perform(make_tuple()));
504
505 // Tests using Invoke() on a callback that returns void.
506 Action<void()> a3 = Invoke(NewPermanentCallback(VoidNullary)); // NOLINT
507 g_done = false;
508 a3.Perform(make_tuple());
509 EXPECT_TRUE(g_done);
510}
511
512// Tests using Invoke() with a unary callback.
513TEST(InvokeCallbackTest, Unary) {
514 // Tests using Invoke(callback1) as an action of the exact type.
515 Action<bool(int)> a = Invoke(NewPermanentCallback(Unary)); // NOLINT
516 EXPECT_FALSE(a.Perform(make_tuple(1)));
517 EXPECT_TRUE(a.Perform(make_tuple(-1)));
518
519 // Tests using Invoke(callback1) as an action of a compatible type.
520 Action<int(long)> a2 = Invoke(NewPermanentCallback(Unary)); // NOLINT
521 EXPECT_EQ(0, a2.Perform(make_tuple(1L)));
522 EXPECT_EQ(1, a2.Perform(make_tuple(-1L)));
523
524 // Tests using Invoke() on a callback that returns void.
525 Action<void(char)> a3 = Invoke(NewPermanentCallback(VoidUnary)); // NOLINT
526 g_done = false;
527 a3.Perform(make_tuple('a'));
528 EXPECT_TRUE(g_done);
529}
530
531// Tests using Invoke() with a binary callback.
532TEST(InvokeCallbackTest, Binary) {
533 // Tests using Invoke(callback2) as an action of the exact type.
534 Action<const char*(const char*, short)> a = // NOLINT
535 Invoke(NewPermanentCallback(Binary));
536 const char* p = "Hello";
537 EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
538
539 // Tests using Invoke(callback2) as an action of a compatible type.
540 Action<bool(char*, int)> a2 = // NOLINT
541 Invoke(NewPermanentCallback(Binary));
542 char str[] = "Hello";
543 EXPECT_TRUE(a2.Perform(make_tuple(str, 2)));
544
545 // Tests using Invoke() on a callback that returns void.
546 Action<void(char, char)> a3 =
547 Invoke(NewPermanentCallback(VoidBinary)); // NOLINT
548 g_done = false;
549 a3.Perform(make_tuple('a', 'b'));
550 EXPECT_TRUE(g_done);
551}
552
553// Tests using Invoke() with a ternary callback.
554TEST(InvokeCallbackTest, Ternary) {
555 // Tests using Invoke(callback3) as an action of the exact type.
556 Action<int(int, char, short)> a = // NOLINT
557 Invoke(NewPermanentCallback(Ternary));
558 EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
559
560 // Tests using Invoke(callback3) as an action of a compatible type.
561 Action<long(char, int, int)> a2 = // NOLINT
562 Invoke(NewPermanentCallback(Ternary));
563 EXPECT_EQ(6, a2.Perform(make_tuple('\1', 2, 3)));
564
565 // Tests using Invoke() on a callback that returns void.
566 Action<void(char, char, bool)> a3 =
567 Invoke(NewPermanentCallback(VoidTernary)); // NOLINT
568 g_done = false;
569 a3.Perform(make_tuple('a', 'b', true));
570 EXPECT_TRUE(g_done);
571}
572
573// Tests using Invoke() with a 4-argument callback.
574TEST(InvokeCallbackTest, CallbackThatTakes4Arguments) {
575 // Tests using Invoke(callback4) as an action of the exact type.
576 Action<int(int, int, int, int)> a = // NOLINT
577 Invoke(NewPermanentCallback(SumOf4));
578 EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
579
580 // Tests using Invoke(callback4) as an action of a compatible type.
581 Action<long(int, short, char, bool)> a2 = // NOLINT
582 Invoke(NewPermanentCallback(SumOf4));
583 EXPECT_EQ(4321, a2.Perform(make_tuple(4000, 300, 20, true)));
584
585 // Tests using Invoke() on a callback that returns void.
586 Action<void(char, char, double, double)> a3 =
587 Invoke(NewPermanentCallback(VoidFunctionWithFourArguments)); // NOLINT
588 g_done = false;
589 a3.Perform(make_tuple('a', 'b', 0, 1));
590 EXPECT_TRUE(g_done);
591}
592
593#endif // GMOCK_HAS_GOOGLE3_CALLBACK_
594
595// Tests using WithoutArgs with an action that takes no argument.
596TEST(WithoutArgsTest, NoArg) {
597 Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
598 EXPECT_EQ(1, a.Perform(make_tuple(2)));
599}
600
601// Tests using WithArg with an action that takes 1 argument.
602TEST(WithArgTest, OneArg) {
603 Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
604 EXPECT_TRUE(b.Perform(make_tuple(1.5, -1)));
605 EXPECT_FALSE(b.Perform(make_tuple(1.5, 1)));
606}
607
608TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
609 const Action<int(int)> a = ReturnArg<0>();
610 EXPECT_EQ(5, a.Perform(make_tuple(5)));
611}
612
613TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
614 const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
615 EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
616}
617
618TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
619 const Action<string(int, int, string, int)> a = ReturnArg<2>();
620 EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
621}
622
623TEST(SaveArgActionTest, WorksForSameType) {
624 int result = 0;
625 const Action<void(int n)> a1 = SaveArg<0>(&result);
626 a1.Perform(make_tuple(5));
627 EXPECT_EQ(5, result);
628}
629
630TEST(SaveArgActionTest, WorksForCompatibleType) {
631 int result = 0;
632 const Action<void(bool, char)> a1 = SaveArg<1>(&result);
633 a1.Perform(make_tuple(true, 'a'));
634 EXPECT_EQ('a', result);
635}
636
637TEST(SetArgRefereeActionTest, WorksForSameType) {
638 int value = 0;
639 const Action<void(int&)> a1 = SetArgReferee<0>(1);
640 a1.Perform(tuple<int&>(value));
641 EXPECT_EQ(1, value);
642}
643
644TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
645 int value = 0;
646 const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
647 a1.Perform(tuple<int, int&>(0, value));
648 EXPECT_EQ('a', value);
649}
650
651TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
652 int value = 0;
653 const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
654 a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
655 EXPECT_EQ('a', value);
656}
657
658// A class that can be used to verify that its destructor is called: it will set
659// the bool provided to the constructor to true when destroyed.
660class DeletionTester {
661 public:
662 explicit DeletionTester(bool* is_deleted)
663 : is_deleted_(is_deleted) {
664 // Make sure the bit is set to false.
665 *is_deleted_ = false;
666 }
667
668 ~DeletionTester() {
669 *is_deleted_ = true;
670 }
671
672 private:
673 bool* is_deleted_;
674};
675
676TEST(DeleteArgActionTest, OneArg) {
677 bool is_deleted = false;
678 DeletionTester* t = new DeletionTester(&is_deleted);
679 const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT
680 EXPECT_FALSE(is_deleted);
681 a1.Perform(make_tuple(t));
682 EXPECT_TRUE(is_deleted);
683}
684
685TEST(DeleteArgActionTest, TenArgs) {
686 bool is_deleted = false;
687 DeletionTester* t = new DeletionTester(&is_deleted);
688 const Action<void(bool, int, int, const char*, bool,
689 int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
690 EXPECT_FALSE(is_deleted);
691 a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
692 EXPECT_TRUE(is_deleted);
693}
694
695#if GTEST_HAS_EXCEPTIONS
696
697TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
698 const Action<void(int n)> a = Throw('a');
699 EXPECT_THROW(a.Perform(make_tuple(0)), char);
700}
701
702class MyException {};
703
704TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
705 const Action<double(char ch)> a = Throw(MyException());
706 EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
707}
708
709TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
710 const Action<double()> a = Throw(MyException());
711 EXPECT_THROW(a.Perform(make_tuple()), MyException);
712}
713
714#endif // GTEST_HAS_EXCEPTIONS
715
716// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
717// pointed to by the N-th (0-based) argument to values in range [first, last).
718TEST(SetArrayArgumentTest, SetsTheNthArray) {
719 typedef void MyFunction(bool, int*, char*);
720 int numbers[] = { 1, 2, 3 };
721 Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
722
723 int n[4] = {};
724 int* pn = n;
725 char ch[4] = {};
726 char* pch = ch;
727 a.Perform(make_tuple(true, pn, pch));
728 EXPECT_EQ(1, n[0]);
729 EXPECT_EQ(2, n[1]);
730 EXPECT_EQ(3, n[2]);
731 EXPECT_EQ(0, n[3]);
732 EXPECT_EQ('\0', ch[0]);
733 EXPECT_EQ('\0', ch[1]);
734 EXPECT_EQ('\0', ch[2]);
735 EXPECT_EQ('\0', ch[3]);
736
737 // Tests first and last are iterators.
738 std::string letters = "abc";
739 a = SetArrayArgument<2>(letters.begin(), letters.end());
740 std::fill_n(n, 4, 0);
741 std::fill_n(ch, 4, '\0');
742 a.Perform(make_tuple(true, pn, pch));
743 EXPECT_EQ(0, n[0]);
744 EXPECT_EQ(0, n[1]);
745 EXPECT_EQ(0, n[2]);
746 EXPECT_EQ(0, n[3]);
747 EXPECT_EQ('a', ch[0]);
748 EXPECT_EQ('b', ch[1]);
749 EXPECT_EQ('c', ch[2]);
750 EXPECT_EQ('\0', ch[3]);
751}
752
753// Tests SetArrayArgument<N>(first, last) where first == last.
754TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
755 typedef void MyFunction(bool, int*);
756 int numbers[] = { 1, 2, 3 };
757 Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
758
759 int n[4] = {};
760 int* pn = n;
761 a.Perform(make_tuple(true, pn));
762 EXPECT_EQ(0, n[0]);
763 EXPECT_EQ(0, n[1]);
764 EXPECT_EQ(0, n[2]);
765 EXPECT_EQ(0, n[3]);
766}
767
768// Tests SetArrayArgument<N>(first, last) where *first is convertible
769// (but not equal) to the argument type.
770TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
771 typedef void MyFunction(bool, char*);
772 int codes[] = { 97, 98, 99 };
773 Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
774
775 char ch[4] = {};
776 char* pch = ch;
777 a.Perform(make_tuple(true, pch));
778 EXPECT_EQ('a', ch[0]);
779 EXPECT_EQ('b', ch[1]);
780 EXPECT_EQ('c', ch[2]);
781 EXPECT_EQ('\0', ch[3]);
782}
783
784// Test SetArrayArgument<N>(first, last) with iterator as argument.
785TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
786 typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
787 std::string letters = "abc";
788 Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
789
790 std::string s;
791 a.Perform(make_tuple(true, back_inserter(s)));
792 EXPECT_EQ(letters, s);
793}
794
795} // namespace gmock_generated_actions_test
796} // namespace testing