1// 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#include "gtest/internal/gtest-linked_ptr.h"
44
45namespace testing {
46namespace gmock_more_actions_test {
47
48using ::std::plus;
49using ::std::string;
50using ::std::tr1::get;
51using ::std::tr1::make_tuple;
52using ::std::tr1::tuple;
53using ::std::tr1::tuple_element;
54using testing::_;
55using testing::Action;
56using testing::ActionInterface;
57using testing::DeleteArg;
58using testing::Invoke;
59using testing::Return;
60using testing::ReturnArg;
61using testing::ReturnPointee;
62using testing::SaveArg;
63using testing::SaveArgPointee;
64using testing::SetArgReferee;
65using testing::StaticAssertTypeEq;
66using testing::Unused;
67using testing::WithArg;
68using testing::WithoutArgs;
69using testing::internal::linked_ptr;
70
71// For suppressing compiler warnings on conversion possibly losing precision.
72inline short Short(short n) { return n; }  // NOLINT
73inline char Char(char ch) { return ch; }
74
75// Sample functions and functors for testing Invoke() and etc.
76int Nullary() { return 1; }
77
78class NullaryFunctor {
79 public:
80  int operator()() { return 2; }
81};
82
83bool g_done = false;
84void VoidNullary() { g_done = true; }
85
86class VoidNullaryFunctor {
87 public:
88  void operator()() { g_done = true; }
89};
90
91bool Unary(int x) { return x < 0; }
92
93const char* Plus1(const char* s) { return s + 1; }
94
95void VoidUnary(int /* n */) { g_done = true; }
96
97bool ByConstRef(const string& s) { return s == "Hi"; }
98
99const double g_double = 0;
100bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
101
102string ByNonConstRef(string& s) { return s += "+"; }  // NOLINT
103
104struct UnaryFunctor {
105  int operator()(bool x) { return x ? 1 : -1; }
106};
107
108const char* Binary(const char* input, short n) { return input + n; }  // NOLINT
109
110void VoidBinary(int, char) { g_done = true; }
111
112int Ternary(int x, char y, short z) { return x + y + z; }  // NOLINT
113
114void VoidTernary(int, char, bool) { g_done = true; }
115
116int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
117
118int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
119
120void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
121
122string Concat4(const char* s1, const char* s2, const char* s3,
123               const char* s4) {
124  return string(s1) + s2 + s3 + s4;
125}
126
127int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
128
129struct SumOf5Functor {
130  int operator()(int a, int b, int c, int d, int e) {
131    return a + b + c + d + e;
132  }
133};
134
135string Concat5(const char* s1, const char* s2, const char* s3,
136               const char* s4, const char* s5) {
137  return string(s1) + s2 + s3 + s4 + s5;
138}
139
140int SumOf6(int a, int b, int c, int d, int e, int f) {
141  return a + b + c + d + e + f;
142}
143
144struct SumOf6Functor {
145  int operator()(int a, int b, int c, int d, int e, int f) {
146    return a + b + c + d + e + f;
147  }
148};
149
150string Concat6(const char* s1, const char* s2, const char* s3,
151               const char* s4, const char* s5, const char* s6) {
152  return string(s1) + s2 + s3 + s4 + s5 + s6;
153}
154
155string Concat7(const char* s1, const char* s2, const char* s3,
156               const char* s4, const char* s5, const char* s6,
157               const char* s7) {
158  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
159}
160
161string Concat8(const char* s1, const char* s2, const char* s3,
162               const char* s4, const char* s5, const char* s6,
163               const char* s7, const char* s8) {
164  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
165}
166
167string Concat9(const char* s1, const char* s2, const char* s3,
168               const char* s4, const char* s5, const char* s6,
169               const char* s7, const char* s8, const char* s9) {
170  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
171}
172
173string Concat10(const char* s1, const char* s2, const char* s3,
174                const char* s4, const char* s5, const char* s6,
175                const char* s7, const char* s8, const char* s9,
176                const char* s10) {
177  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
178}
179
180class Foo {
181 public:
182  Foo() : value_(123) {}
183
184  int Nullary() const { return value_; }
185
186  short Unary(long x) { return static_cast<short>(value_ + x); }  // NOLINT
187
188  string Binary(const string& str, char c) const { return str + c; }
189
190  int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
191
192  int SumOf4(int a, int b, int c, int d) const {
193    return a + b + c + d + value_;
194  }
195
196  int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
197
198  int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
199
200  int SumOf6(int a, int b, int c, int d, int e, int f) {
201    return a + b + c + d + e + f;
202  }
203
204  string Concat7(const char* s1, const char* s2, const char* s3,
205                 const char* s4, const char* s5, const char* s6,
206                 const char* s7) {
207    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
208  }
209
210  string Concat8(const char* s1, const char* s2, const char* s3,
211                 const char* s4, const char* s5, const char* s6,
212                 const char* s7, const char* s8) {
213    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
214  }
215
216  string Concat9(const char* s1, const char* s2, const char* s3,
217                 const char* s4, const char* s5, const char* s6,
218                 const char* s7, const char* s8, const char* s9) {
219    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
220  }
221
222  string Concat10(const char* s1, const char* s2, const char* s3,
223                  const char* s4, const char* s5, const char* s6,
224                  const char* s7, const char* s8, const char* s9,
225                  const char* s10) {
226    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
227  }
228 private:
229  int value_;
230};
231
232// Tests using Invoke() with a nullary function.
233TEST(InvokeTest, Nullary) {
234  Action<int()> a = Invoke(Nullary);  // NOLINT
235  EXPECT_EQ(1, a.Perform(make_tuple()));
236}
237
238// Tests using Invoke() with a unary function.
239TEST(InvokeTest, Unary) {
240  Action<bool(int)> a = Invoke(Unary);  // NOLINT
241  EXPECT_FALSE(a.Perform(make_tuple(1)));
242  EXPECT_TRUE(a.Perform(make_tuple(-1)));
243}
244
245// Tests using Invoke() with a binary function.
246TEST(InvokeTest, Binary) {
247  Action<const char*(const char*, short)> a = Invoke(Binary);  // NOLINT
248  const char* p = "Hello";
249  EXPECT_EQ(p + 2, a.Perform(make_tuple(p, Short(2))));
250}
251
252// Tests using Invoke() with a ternary function.
253TEST(InvokeTest, Ternary) {
254  Action<int(int, char, short)> a = Invoke(Ternary);  // NOLINT
255  EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', Short(3))));
256}
257
258// Tests using Invoke() with a 4-argument function.
259TEST(InvokeTest, FunctionThatTakes4Arguments) {
260  Action<int(int, int, int, int)> a = Invoke(SumOf4);  // NOLINT
261  EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
262}
263
264// Tests using Invoke() with a 5-argument function.
265TEST(InvokeTest, FunctionThatTakes5Arguments) {
266  Action<int(int, int, int, int, int)> a = Invoke(SumOf5);  // NOLINT
267  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
268}
269
270// Tests using Invoke() with a 6-argument function.
271TEST(InvokeTest, FunctionThatTakes6Arguments) {
272  Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6);  // NOLINT
273  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
274}
275
276// A helper that turns the type of a C-string literal from const
277// char[N] to const char*.
278inline const char* CharPtr(const char* s) { return s; }
279
280// Tests using Invoke() with a 7-argument function.
281TEST(InvokeTest, FunctionThatTakes7Arguments) {
282  Action<string(const char*, const char*, const char*, const char*,
283                const char*, const char*, const char*)> a =
284      Invoke(Concat7);
285  EXPECT_EQ("1234567",
286            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
287                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
288                                 CharPtr("7"))));
289}
290
291// Tests using Invoke() with a 8-argument function.
292TEST(InvokeTest, FunctionThatTakes8Arguments) {
293  Action<string(const char*, const char*, const char*, const char*,
294                const char*, const char*, const char*, const char*)> a =
295      Invoke(Concat8);
296  EXPECT_EQ("12345678",
297            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
298                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
299                                 CharPtr("7"), CharPtr("8"))));
300}
301
302// Tests using Invoke() with a 9-argument function.
303TEST(InvokeTest, FunctionThatTakes9Arguments) {
304  Action<string(const char*, const char*, const char*, const char*,
305                const char*, const char*, const char*, const char*,
306                const char*)> a = Invoke(Concat9);
307  EXPECT_EQ("123456789",
308            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
309                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
310                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
311}
312
313// Tests using Invoke() with a 10-argument function.
314TEST(InvokeTest, FunctionThatTakes10Arguments) {
315  Action<string(const char*, const char*, const char*, const char*,
316                const char*, const char*, const char*, const char*,
317                const char*, const char*)> a = Invoke(Concat10);
318  EXPECT_EQ("1234567890",
319            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
320                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
321                                 CharPtr("7"), CharPtr("8"), CharPtr("9"),
322                                 CharPtr("0"))));
323}
324
325// Tests using Invoke() with functions with parameters declared as Unused.
326TEST(InvokeTest, FunctionWithUnusedParameters) {
327  Action<int(int, int, double, const string&)> a1 =
328      Invoke(SumOfFirst2);
329  EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
330
331  Action<int(int, int, bool, int*)> a2 =
332      Invoke(SumOfFirst2);
333  EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
334}
335
336// Tests using Invoke() with methods with parameters declared as Unused.
337TEST(InvokeTest, MethodWithUnusedParameters) {
338  Foo foo;
339  Action<int(string, bool, int, int)> a1 =
340      Invoke(&foo, &Foo::SumOfLast2);
341  EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
342
343  Action<int(char, double, int, int)> a2 =
344      Invoke(&foo, &Foo::SumOfLast2);
345  EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
346}
347
348// Tests using Invoke() with a functor.
349TEST(InvokeTest, Functor) {
350  Action<long(long, int)> a = Invoke(plus<long>());  // NOLINT
351  EXPECT_EQ(3L, a.Perform(make_tuple(1, 2)));
352}
353
354// Tests using Invoke(f) as an action of a compatible type.
355TEST(InvokeTest, FunctionWithCompatibleType) {
356  Action<long(int, short, char, bool)> a = Invoke(SumOf4);  // NOLINT
357  EXPECT_EQ(4321, a.Perform(make_tuple(4000, Short(300), Char(20), true)));
358}
359
360// Tests using Invoke() with an object pointer and a method pointer.
361
362// Tests using Invoke() with a nullary method.
363TEST(InvokeMethodTest, Nullary) {
364  Foo foo;
365  Action<int()> a = Invoke(&foo, &Foo::Nullary);  // NOLINT
366  EXPECT_EQ(123, a.Perform(make_tuple()));
367}
368
369// Tests using Invoke() with a unary method.
370TEST(InvokeMethodTest, Unary) {
371  Foo foo;
372  Action<short(long)> a = Invoke(&foo, &Foo::Unary);  // NOLINT
373  EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
374}
375
376// Tests using Invoke() with a binary method.
377TEST(InvokeMethodTest, Binary) {
378  Foo foo;
379  Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
380  string s("Hell");
381  EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
382}
383
384// Tests using Invoke() with a ternary method.
385TEST(InvokeMethodTest, Ternary) {
386  Foo foo;
387  Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary);  // NOLINT
388  EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, Char(1))));
389}
390
391// Tests using Invoke() with a 4-argument method.
392TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
393  Foo foo;
394  Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4);  // NOLINT
395  EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
396}
397
398// Tests using Invoke() with a 5-argument method.
399TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
400  Foo foo;
401  Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5);  // NOLINT
402  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
403}
404
405// Tests using Invoke() with a 6-argument method.
406TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
407  Foo foo;
408  Action<int(int, int, int, int, int, int)> a =  // NOLINT
409      Invoke(&foo, &Foo::SumOf6);
410  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
411}
412
413// Tests using Invoke() with a 7-argument method.
414TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
415  Foo foo;
416  Action<string(const char*, const char*, const char*, const char*,
417                const char*, const char*, const char*)> a =
418      Invoke(&foo, &Foo::Concat7);
419  EXPECT_EQ("1234567",
420            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
421                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
422                                 CharPtr("7"))));
423}
424
425// Tests using Invoke() with a 8-argument method.
426TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
427  Foo foo;
428  Action<string(const char*, const char*, const char*, const char*,
429                const char*, const char*, const char*, const char*)> a =
430      Invoke(&foo, &Foo::Concat8);
431  EXPECT_EQ("12345678",
432            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
433                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
434                                 CharPtr("7"), CharPtr("8"))));
435}
436
437// Tests using Invoke() with a 9-argument method.
438TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
439  Foo foo;
440  Action<string(const char*, const char*, const char*, const char*,
441                const char*, const char*, const char*, const char*,
442                const char*)> a = Invoke(&foo, &Foo::Concat9);
443  EXPECT_EQ("123456789",
444            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
445                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
446                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
447}
448
449// Tests using Invoke() with a 10-argument method.
450TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
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*, const char*)> a = Invoke(&foo, &Foo::Concat10);
455  EXPECT_EQ("1234567890",
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                                 CharPtr("0"))));
460}
461
462// Tests using Invoke(f) as an action of a compatible type.
463TEST(InvokeMethodTest, MethodWithCompatibleType) {
464  Foo foo;
465  Action<long(int, short, char, bool)> a =  // NOLINT
466      Invoke(&foo, &Foo::SumOf4);
467  EXPECT_EQ(4444, a.Perform(make_tuple(4000, Short(300), Char(20), true)));
468}
469
470// Tests using WithoutArgs with an action that takes no argument.
471TEST(WithoutArgsTest, NoArg) {
472  Action<int(int n)> a = WithoutArgs(Invoke(Nullary));  // NOLINT
473  EXPECT_EQ(1, a.Perform(make_tuple(2)));
474}
475
476// Tests using WithArg with an action that takes 1 argument.
477TEST(WithArgTest, OneArg) {
478  Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary));  // NOLINT
479  EXPECT_TRUE(b.Perform(make_tuple(1.5, -1)));
480  EXPECT_FALSE(b.Perform(make_tuple(1.5, 1)));
481}
482
483TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
484  const Action<int(int)> a = ReturnArg<0>();
485  EXPECT_EQ(5, a.Perform(make_tuple(5)));
486}
487
488TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
489  const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
490  EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
491}
492
493TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
494  const Action<string(int, int, string, int)> a = ReturnArg<2>();
495  EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
496}
497
498TEST(SaveArgActionTest, WorksForSameType) {
499  int result = 0;
500  const Action<void(int n)> a1 = SaveArg<0>(&result);
501  a1.Perform(make_tuple(5));
502  EXPECT_EQ(5, result);
503}
504
505TEST(SaveArgActionTest, WorksForCompatibleType) {
506  int result = 0;
507  const Action<void(bool, char)> a1 = SaveArg<1>(&result);
508  a1.Perform(make_tuple(true, 'a'));
509  EXPECT_EQ('a', result);
510}
511
512TEST(SaveArgPointeeActionTest, WorksForSameType) {
513  int result = 0;
514  const int value = 5;
515  const Action<void(const int*)> a1 = SaveArgPointee<0>(&result);
516  a1.Perform(make_tuple(&value));
517  EXPECT_EQ(5, result);
518}
519
520TEST(SaveArgPointeeActionTest, WorksForCompatibleType) {
521  int result = 0;
522  char value = 'a';
523  const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result);
524  a1.Perform(make_tuple(true, &value));
525  EXPECT_EQ('a', result);
526}
527
528TEST(SaveArgPointeeActionTest, WorksForLinkedPtr) {
529  int result = 0;
530  linked_ptr<int> value(new int(5));
531  const Action<void(linked_ptr<int>)> a1 = SaveArgPointee<0>(&result);
532  a1.Perform(make_tuple(value));
533  EXPECT_EQ(5, result);
534}
535
536TEST(SetArgRefereeActionTest, WorksForSameType) {
537  int value = 0;
538  const Action<void(int&)> a1 = SetArgReferee<0>(1);
539  a1.Perform(tuple<int&>(value));
540  EXPECT_EQ(1, value);
541}
542
543TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
544  int value = 0;
545  const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
546  a1.Perform(tuple<int, int&>(0, value));
547  EXPECT_EQ('a', value);
548}
549
550TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
551  int value = 0;
552  const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
553  a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
554  EXPECT_EQ('a', value);
555}
556
557// A class that can be used to verify that its destructor is called: it will set
558// the bool provided to the constructor to true when destroyed.
559class DeletionTester {
560 public:
561  explicit DeletionTester(bool* is_deleted)
562    : is_deleted_(is_deleted) {
563    // Make sure the bit is set to false.
564    *is_deleted_ = false;
565  }
566
567  ~DeletionTester() {
568    *is_deleted_ = true;
569  }
570
571 private:
572  bool* is_deleted_;
573};
574
575TEST(DeleteArgActionTest, OneArg) {
576  bool is_deleted = false;
577  DeletionTester* t = new DeletionTester(&is_deleted);
578  const Action<void(DeletionTester*)> a1 = DeleteArg<0>();      // NOLINT
579  EXPECT_FALSE(is_deleted);
580  a1.Perform(make_tuple(t));
581  EXPECT_TRUE(is_deleted);
582}
583
584TEST(DeleteArgActionTest, TenArgs) {
585  bool is_deleted = false;
586  DeletionTester* t = new DeletionTester(&is_deleted);
587  const Action<void(bool, int, int, const char*, bool,
588                    int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
589  EXPECT_FALSE(is_deleted);
590  a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
591  EXPECT_TRUE(is_deleted);
592}
593
594#if GTEST_HAS_EXCEPTIONS
595
596TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
597  const Action<void(int n)> a = Throw('a');
598  EXPECT_THROW(a.Perform(make_tuple(0)), char);
599}
600
601class MyException {};
602
603TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
604  const Action<double(char ch)> a = Throw(MyException());
605  EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
606}
607
608TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
609  const Action<double()> a = Throw(MyException());
610  EXPECT_THROW(a.Perform(make_tuple()), MyException);
611}
612
613#endif  // GTEST_HAS_EXCEPTIONS
614
615// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
616// pointed to by the N-th (0-based) argument to values in range [first, last).
617TEST(SetArrayArgumentTest, SetsTheNthArray) {
618  typedef void MyFunction(bool, int*, char*);
619  int numbers[] = { 1, 2, 3 };
620  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
621
622  int n[4] = {};
623  int* pn = n;
624  char ch[4] = {};
625  char* pch = ch;
626  a.Perform(make_tuple(true, pn, pch));
627  EXPECT_EQ(1, n[0]);
628  EXPECT_EQ(2, n[1]);
629  EXPECT_EQ(3, n[2]);
630  EXPECT_EQ(0, n[3]);
631  EXPECT_EQ('\0', ch[0]);
632  EXPECT_EQ('\0', ch[1]);
633  EXPECT_EQ('\0', ch[2]);
634  EXPECT_EQ('\0', ch[3]);
635
636  // Tests first and last are iterators.
637  std::string letters = "abc";
638  a = SetArrayArgument<2>(letters.begin(), letters.end());
639  std::fill_n(n, 4, 0);
640  std::fill_n(ch, 4, '\0');
641  a.Perform(make_tuple(true, pn, pch));
642  EXPECT_EQ(0, n[0]);
643  EXPECT_EQ(0, n[1]);
644  EXPECT_EQ(0, n[2]);
645  EXPECT_EQ(0, n[3]);
646  EXPECT_EQ('a', ch[0]);
647  EXPECT_EQ('b', ch[1]);
648  EXPECT_EQ('c', ch[2]);
649  EXPECT_EQ('\0', ch[3]);
650}
651
652// Tests SetArrayArgument<N>(first, last) where first == last.
653TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
654  typedef void MyFunction(bool, int*);
655  int numbers[] = { 1, 2, 3 };
656  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
657
658  int n[4] = {};
659  int* pn = n;
660  a.Perform(make_tuple(true, pn));
661  EXPECT_EQ(0, n[0]);
662  EXPECT_EQ(0, n[1]);
663  EXPECT_EQ(0, n[2]);
664  EXPECT_EQ(0, n[3]);
665}
666
667// Tests SetArrayArgument<N>(first, last) where *first is convertible
668// (but not equal) to the argument type.
669TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
670  typedef void MyFunction(bool, char*);
671  int codes[] = { 97, 98, 99 };
672  Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
673
674  char ch[4] = {};
675  char* pch = ch;
676  a.Perform(make_tuple(true, pch));
677  EXPECT_EQ('a', ch[0]);
678  EXPECT_EQ('b', ch[1]);
679  EXPECT_EQ('c', ch[2]);
680  EXPECT_EQ('\0', ch[3]);
681}
682
683// Test SetArrayArgument<N>(first, last) with iterator as argument.
684TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
685  typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
686  std::string letters = "abc";
687  Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
688
689  std::string s;
690  a.Perform(make_tuple(true, back_inserter(s)));
691  EXPECT_EQ(letters, s);
692}
693
694TEST(ReturnPointeeTest, Works) {
695  int n = 42;
696  const Action<int()> a = ReturnPointee(&n);
697  EXPECT_EQ(42, a.Perform(make_tuple()));
698
699  n = 43;
700  EXPECT_EQ(43, a.Perform(make_tuple()));
701}
702
703}  // namespace gmock_generated_actions_test
704}  // namespace testing
705