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