github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/third_party/googlemock/test/gmock-more-actions_test.cc (about)

     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  
    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, string("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