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 ::std::tr1::get;
     51 using ::std::tr1::make_tuple;
     52 using ::std::tr1::tuple;
     53 using ::std::tr1::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 string& s) { return s == "Hi"; }
     98 
     99 const double g_double = 0;
    100 bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
    101 
    102 string ByNonConstRef(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 string Concat4(const char* s1, const char* s2, const char* s3,
    123                const char* s4) {
    124   return 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 string 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 
    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 string 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 
    155 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 string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
    159 }
    160 
    161 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 string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
    165 }
    166 
    167 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 string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
    171 }
    172 
    173 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 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   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 
    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<string(const char*, const char*, const char*, const char*,
    284                 const char*, const char*, const char*)> a =
    285       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<string(const char*, const char*, const char*, const char*,
    295                 const char*, const char*, const char*, const char*)> a =
    296       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<string(const char*, const char*, const char*, const char*,
    306                 const char*, const char*, const char*, const char*,
    307                 const char*)> a = Invoke(Concat9);
    308   EXPECT_EQ("123456789",
    309             a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
    310                                  CharPtr("4"), CharPtr("5"), CharPtr("6"),
    311                                  CharPtr("7"), CharPtr("8"), CharPtr("9"))));
    312 }
    313 
    314 // Tests using Invoke() with a 10-argument function.
    315 TEST(InvokeTest, FunctionThatTakes10Arguments) {
    316   Action<string(const char*, const char*, const char*, const char*,
    317                 const char*, const char*, const char*, const char*,
    318                 const char*, const char*)> a = Invoke(Concat10);
    319   EXPECT_EQ("1234567890",
    320             a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
    321                                  CharPtr("4"), CharPtr("5"), CharPtr("6"),
    322                                  CharPtr("7"), CharPtr("8"), CharPtr("9"),
    323                                  CharPtr("0"))));
    324 }
    325 
    326 // Tests using Invoke() with functions with parameters declared as Unused.
    327 TEST(InvokeTest, FunctionWithUnusedParameters) {
    328   Action<int(int, int, double, const string&)> a1 =
    329       Invoke(SumOfFirst2);
    330   EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
    331 
    332   Action<int(int, int, bool, int*)> a2 =
    333       Invoke(SumOfFirst2);
    334   EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
    335 }
    336 
    337 // Tests using Invoke() with methods with parameters declared as Unused.
    338 TEST(InvokeTest, MethodWithUnusedParameters) {
    339   Foo foo;
    340   Action<int(string, bool, int, int)> a1 =
    341       Invoke(&foo, &Foo::SumOfLast2);
    342   EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
    343 
    344   Action<int(char, double, int, int)> a2 =
    345       Invoke(&foo, &Foo::SumOfLast2);
    346   EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
    347 }
    348 
    349 // Tests using Invoke() with a functor.
    350 TEST(InvokeTest, Functor) {
    351   Action<long(long, int)> a = Invoke(plus<long>());  // NOLINT
    352   EXPECT_EQ(3L, a.Perform(make_tuple(1, 2)));
    353 }
    354 
    355 // Tests using Invoke(f) as an action of a compatible type.
    356 TEST(InvokeTest, FunctionWithCompatibleType) {
    357   Action<long(int, short, char, bool)> a = Invoke(SumOf4);  // NOLINT
    358   EXPECT_EQ(4321, a.Perform(make_tuple(4000, Short(300), Char(20), true)));
    359 }
    360 
    361 // Tests using Invoke() with an object pointer and a method pointer.
    362 
    363 // Tests using Invoke() with a nullary method.
    364 TEST(InvokeMethodTest, Nullary) {
    365   Foo foo;
    366   Action<int()> a = Invoke(&foo, &Foo::Nullary);  // NOLINT
    367   EXPECT_EQ(123, a.Perform(make_tuple()));
    368 }
    369 
    370 // Tests using Invoke() with a unary method.
    371 TEST(InvokeMethodTest, Unary) {
    372   Foo foo;
    373   Action<short(long)> a = Invoke(&foo, &Foo::Unary);  // NOLINT
    374   EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
    375 }
    376 
    377 // Tests using Invoke() with a binary method.
    378 TEST(InvokeMethodTest, Binary) {
    379   Foo foo;
    380   Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
    381   string s("Hell");
    382   EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
    383 }
    384 
    385 // Tests using Invoke() with a ternary method.
    386 TEST(InvokeMethodTest, Ternary) {
    387   Foo foo;
    388   Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary);  // NOLINT
    389   EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, Char(1))));
    390 }
    391 
    392 // Tests using Invoke() with a 4-argument method.
    393 TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
    394   Foo foo;
    395   Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4);  // NOLINT
    396   EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
    397 }
    398 
    399 // Tests using Invoke() with a 5-argument method.
    400 TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
    401   Foo foo;
    402   Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5);  // NOLINT
    403   EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
    404 }
    405 
    406 // Tests using Invoke() with a 6-argument method.
    407 TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
    408   Foo foo;
    409   Action<int(int, int, int, int, int, int)> a =  // NOLINT
    410       Invoke(&foo, &Foo::SumOf6);
    411   EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
    412 }
    413 
    414 // Tests using Invoke() with a 7-argument method.
    415 TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
    416   Foo foo;
    417   Action<string(const char*, const char*, const char*, const char*,
    418                 const char*, const char*, const char*)> a =
    419       Invoke(&foo, &Foo::Concat7);
    420   EXPECT_EQ("1234567",
    421             a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
    422                                  CharPtr("4"), CharPtr("5"), CharPtr("6"),
    423                                  CharPtr("7"))));
    424 }
    425 
    426 // Tests using Invoke() with a 8-argument method.
    427 TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
    428   Foo foo;
    429   Action<string(const char*, const char*, const char*, const char*,
    430                 const char*, const char*, const char*, const char*)> a =
    431       Invoke(&foo, &Foo::Concat8);
    432   EXPECT_EQ("12345678",
    433             a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
    434                                  CharPtr("4"), CharPtr("5"), CharPtr("6"),
    435                                  CharPtr("7"), CharPtr("8"))));
    436 }
    437 
    438 // Tests using Invoke() with a 9-argument method.
    439 TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
    440   Foo foo;
    441   Action<string(const char*, const char*, const char*, const char*,
    442                 const char*, const char*, const char*, const char*,
    443                 const char*)> a = Invoke(&foo, &Foo::Concat9);
    444   EXPECT_EQ("123456789",
    445             a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
    446                                  CharPtr("4"), CharPtr("5"), CharPtr("6"),
    447                                  CharPtr("7"), CharPtr("8"), CharPtr("9"))));
    448 }
    449 
    450 // Tests using Invoke() with a 10-argument method.
    451 TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
    452   Foo foo;
    453   Action<string(const char*, const char*, const char*, const char*,
    454                 const char*, const char*, const char*, const char*,
    455                 const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
    456   EXPECT_EQ("1234567890",
    457             a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
    458                                  CharPtr("4"), CharPtr("5"), CharPtr("6"),
    459                                  CharPtr("7"), CharPtr("8"), CharPtr("9"),
    460                                  CharPtr("0"))));
    461 }
    462 
    463 // Tests using Invoke(f) as an action of a compatible type.
    464 TEST(InvokeMethodTest, MethodWithCompatibleType) {
    465   Foo foo;
    466   Action<long(int, short, char, bool)> a =  // NOLINT
    467       Invoke(&foo, &Foo::SumOf4);
    468   EXPECT_EQ(4444, a.Perform(make_tuple(4000, Short(300), Char(20), true)));
    469 }
    470 
    471 // Tests using WithoutArgs with an action that takes no argument.
    472 TEST(WithoutArgsTest, NoArg) {
    473   Action<int(int n)> a = WithoutArgs(Invoke(Nullary));  // NOLINT
    474   EXPECT_EQ(1, a.Perform(make_tuple(2)));
    475 }
    476 
    477 // Tests using WithArg with an action that takes 1 argument.
    478 TEST(WithArgTest, OneArg) {
    479   Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary));  // NOLINT
    480   EXPECT_TRUE(b.Perform(make_tuple(1.5, -1)));
    481   EXPECT_FALSE(b.Perform(make_tuple(1.5, 1)));
    482 }
    483 
    484 TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
    485   const Action<int(int)> a = ReturnArg<0>();
    486   EXPECT_EQ(5, a.Perform(make_tuple(5)));
    487 }
    488 
    489 TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
    490   const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
    491   EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
    492 }
    493 
    494 TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
    495   const Action<string(int, int, string, int)> a = ReturnArg<2>();
    496   EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
    497 }
    498 
    499 TEST(SaveArgActionTest, WorksForSameType) {
    500   int result = 0;
    501   const Action<void(int n)> a1 = SaveArg<0>(&result);
    502   a1.Perform(make_tuple(5));
    503   EXPECT_EQ(5, result);
    504 }
    505 
    506 TEST(SaveArgActionTest, WorksForCompatibleType) {
    507   int result = 0;
    508   const Action<void(bool, char)> a1 = SaveArg<1>(&result);
    509   a1.Perform(make_tuple(true, 'a'));
    510   EXPECT_EQ('a', result);
    511 }
    512 
    513 TEST(SaveArgPointeeActionTest, WorksForSameType) {
    514   int result = 0;
    515   const int value = 5;
    516   const Action<void(const int*)> a1 = SaveArgPointee<0>(&result);
    517   a1.Perform(make_tuple(&value));
    518   EXPECT_EQ(5, result);
    519 }
    520 
    521 TEST(SaveArgPointeeActionTest, WorksForCompatibleType) {
    522   int result = 0;
    523   char value = 'a';
    524   const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result);
    525   a1.Perform(make_tuple(true, &value));
    526   EXPECT_EQ('a', result);
    527 }
    528 
    529 TEST(SaveArgPointeeActionTest, WorksForLinkedPtr) {
    530   int result = 0;
    531   linked_ptr<int> value(new int(5));
    532   const Action<void(linked_ptr<int>)> a1 = SaveArgPointee<0>(&result);
    533   a1.Perform(make_tuple(value));
    534   EXPECT_EQ(5, result);
    535 }
    536 
    537 TEST(SetArgRefereeActionTest, WorksForSameType) {
    538   int value = 0;
    539   const Action<void(int&)> a1 = SetArgReferee<0>(1);
    540   a1.Perform(tuple<int&>(value));
    541   EXPECT_EQ(1, value);
    542 }
    543 
    544 TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
    545   int value = 0;
    546   const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
    547   a1.Perform(tuple<int, int&>(0, value));
    548   EXPECT_EQ('a', value);
    549 }
    550 
    551 TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
    552   int value = 0;
    553   const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
    554   a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
    555   EXPECT_EQ('a', value);
    556 }
    557 
    558 // A class that can be used to verify that its destructor is called: it will set
    559 // the bool provided to the constructor to true when destroyed.
    560 class DeletionTester {
    561  public:
    562   explicit DeletionTester(bool* is_deleted)
    563     : is_deleted_(is_deleted) {
    564     // Make sure the bit is set to false.
    565     *is_deleted_ = false;
    566   }
    567 
    568   ~DeletionTester() {
    569     *is_deleted_ = true;
    570   }
    571 
    572  private:
    573   bool* is_deleted_;
    574 };
    575 
    576 TEST(DeleteArgActionTest, OneArg) {
    577   bool is_deleted = false;
    578   DeletionTester* t = new DeletionTester(&is_deleted);
    579   const Action<void(DeletionTester*)> a1 = DeleteArg<0>();      // NOLINT
    580   EXPECT_FALSE(is_deleted);
    581   a1.Perform(make_tuple(t));
    582   EXPECT_TRUE(is_deleted);
    583 }
    584 
    585 TEST(DeleteArgActionTest, TenArgs) {
    586   bool is_deleted = false;
    587   DeletionTester* t = new DeletionTester(&is_deleted);
    588   const Action<void(bool, int, int, const char*, bool,
    589                     int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
    590   EXPECT_FALSE(is_deleted);
    591   a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
    592   EXPECT_TRUE(is_deleted);
    593 }
    594 
    595 #if GTEST_HAS_EXCEPTIONS
    596 
    597 TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
    598   const Action<void(int n)> a = Throw('a');
    599   EXPECT_THROW(a.Perform(make_tuple(0)), char);
    600 }
    601 
    602 class MyException {};
    603 
    604 TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
    605   const Action<double(char ch)> a = Throw(MyException());
    606   EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
    607 }
    608 
    609 TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
    610   const Action<double()> a = Throw(MyException());
    611   EXPECT_THROW(a.Perform(make_tuple()), MyException);
    612 }
    613 
    614 #endif  // GTEST_HAS_EXCEPTIONS
    615 
    616 // Tests that SetArrayArgument<N>(first, last) sets the elements of the array
    617 // pointed to by the N-th (0-based) argument to values in range [first, last).
    618 TEST(SetArrayArgumentTest, SetsTheNthArray) {
    619   typedef void MyFunction(bool, int*, char*);
    620   int numbers[] = { 1, 2, 3 };
    621   Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
    622 
    623   int n[4] = {};
    624   int* pn = n;
    625   char ch[4] = {};
    626   char* pch = ch;
    627   a.Perform(make_tuple(true, pn, pch));
    628   EXPECT_EQ(1, n[0]);
    629   EXPECT_EQ(2, n[1]);
    630   EXPECT_EQ(3, n[2]);
    631   EXPECT_EQ(0, n[3]);
    632   EXPECT_EQ('\0', ch[0]);
    633   EXPECT_EQ('\0', ch[1]);
    634   EXPECT_EQ('\0', ch[2]);
    635   EXPECT_EQ('\0', ch[3]);
    636 
    637   // Tests first and last are iterators.
    638   std::string letters = "abc";
    639   a = SetArrayArgument<2>(letters.begin(), letters.end());
    640   std::fill_n(n, 4, 0);
    641   std::fill_n(ch, 4, '\0');
    642   a.Perform(make_tuple(true, pn, pch));
    643   EXPECT_EQ(0, n[0]);
    644   EXPECT_EQ(0, n[1]);
    645   EXPECT_EQ(0, n[2]);
    646   EXPECT_EQ(0, n[3]);
    647   EXPECT_EQ('a', ch[0]);
    648   EXPECT_EQ('b', ch[1]);
    649   EXPECT_EQ('c', ch[2]);
    650   EXPECT_EQ('\0', ch[3]);
    651 }
    652 
    653 // Tests SetArrayArgument<N>(first, last) where first == last.
    654 TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
    655   typedef void MyFunction(bool, int*);
    656   int numbers[] = { 1, 2, 3 };
    657   Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
    658 
    659   int n[4] = {};
    660   int* pn = n;
    661   a.Perform(make_tuple(true, pn));
    662   EXPECT_EQ(0, n[0]);
    663   EXPECT_EQ(0, n[1]);
    664   EXPECT_EQ(0, n[2]);
    665   EXPECT_EQ(0, n[3]);
    666 }
    667 
    668 // Tests SetArrayArgument<N>(first, last) where *first is convertible
    669 // (but not equal) to the argument type.
    670 TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
    671   typedef void MyFunction(bool, char*);
    672   int codes[] = { 97, 98, 99 };
    673   Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
    674 
    675   char ch[4] = {};
    676   char* pch = ch;
    677   a.Perform(make_tuple(true, pch));
    678   EXPECT_EQ('a', ch[0]);
    679   EXPECT_EQ('b', ch[1]);
    680   EXPECT_EQ('c', ch[2]);
    681   EXPECT_EQ('\0', ch[3]);
    682 }
    683 
    684 // Test SetArrayArgument<N>(first, last) with iterator as argument.
    685 TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
    686   typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
    687   std::string letters = "abc";
    688   Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
    689 
    690   std::string s;
    691   a.Perform(make_tuple(true, back_inserter(s)));
    692   EXPECT_EQ(letters, s);
    693 }
    694 
    695 TEST(ReturnPointeeTest, Works) {
    696   int n = 42;
    697   const Action<int()> a = ReturnPointee(&n);
    698   EXPECT_EQ(42, a.Perform(make_tuple()));
    699 
    700   n = 43;
    701   EXPECT_EQ(43, a.Perform(make_tuple()));
    702 }
    703 
    704 }  // namespace gmock_generated_actions_test
    705 }  // namespace testing
    706