113481Sgiacomo.travaglini@arm.com// Copyright 2007, Google Inc.
213481Sgiacomo.travaglini@arm.com// All rights reserved.
313481Sgiacomo.travaglini@arm.com//
413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
613481Sgiacomo.travaglini@arm.com// met:
713481Sgiacomo.travaglini@arm.com//
813481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1013481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1313481Sgiacomo.travaglini@arm.com// distribution.
1413481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1713481Sgiacomo.travaglini@arm.com//
1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913481Sgiacomo.travaglini@arm.com//
3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan)
3113481Sgiacomo.travaglini@arm.com
3213481Sgiacomo.travaglini@arm.com// Google Mock - a framework for writing C++ mock classes.
3313481Sgiacomo.travaglini@arm.com//
3413481Sgiacomo.travaglini@arm.com// This file tests the built-in actions in gmock-more-actions.h.
3513481Sgiacomo.travaglini@arm.com
3613481Sgiacomo.travaglini@arm.com#include "gmock/gmock-more-actions.h"
3713481Sgiacomo.travaglini@arm.com
3813481Sgiacomo.travaglini@arm.com#include <functional>
3913481Sgiacomo.travaglini@arm.com#include <sstream>
4013481Sgiacomo.travaglini@arm.com#include <string>
4113481Sgiacomo.travaglini@arm.com#include "gmock/gmock.h"
4213481Sgiacomo.travaglini@arm.com#include "gtest/gtest.h"
4313481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-linked_ptr.h"
4413481Sgiacomo.travaglini@arm.com
4513481Sgiacomo.travaglini@arm.comnamespace testing {
4613481Sgiacomo.travaglini@arm.comnamespace gmock_more_actions_test {
4713481Sgiacomo.travaglini@arm.com
4813481Sgiacomo.travaglini@arm.comusing ::std::plus;
4913481Sgiacomo.travaglini@arm.comusing ::std::string;
5013481Sgiacomo.travaglini@arm.comusing testing::get;
5113481Sgiacomo.travaglini@arm.comusing testing::make_tuple;
5213481Sgiacomo.travaglini@arm.comusing testing::tuple;
5313481Sgiacomo.travaglini@arm.comusing testing::tuple_element;
5413481Sgiacomo.travaglini@arm.comusing testing::_;
5513481Sgiacomo.travaglini@arm.comusing testing::Action;
5613481Sgiacomo.travaglini@arm.comusing testing::ActionInterface;
5713481Sgiacomo.travaglini@arm.comusing testing::DeleteArg;
5813481Sgiacomo.travaglini@arm.comusing testing::Invoke;
5913481Sgiacomo.travaglini@arm.comusing testing::Return;
6013481Sgiacomo.travaglini@arm.comusing testing::ReturnArg;
6113481Sgiacomo.travaglini@arm.comusing testing::ReturnPointee;
6213481Sgiacomo.travaglini@arm.comusing testing::SaveArg;
6313481Sgiacomo.travaglini@arm.comusing testing::SaveArgPointee;
6413481Sgiacomo.travaglini@arm.comusing testing::SetArgReferee;
6513481Sgiacomo.travaglini@arm.comusing testing::StaticAssertTypeEq;
6613481Sgiacomo.travaglini@arm.comusing testing::Unused;
6713481Sgiacomo.travaglini@arm.comusing testing::WithArg;
6813481Sgiacomo.travaglini@arm.comusing testing::WithoutArgs;
6913481Sgiacomo.travaglini@arm.comusing testing::internal::linked_ptr;
7013481Sgiacomo.travaglini@arm.com
7113481Sgiacomo.travaglini@arm.com// For suppressing compiler warnings on conversion possibly losing precision.
7213481Sgiacomo.travaglini@arm.cominline short Short(short n) { return n; }  // NOLINT
7313481Sgiacomo.travaglini@arm.cominline char Char(char ch) { return ch; }
7413481Sgiacomo.travaglini@arm.com
7513481Sgiacomo.travaglini@arm.com// Sample functions and functors for testing Invoke() and etc.
7613481Sgiacomo.travaglini@arm.comint Nullary() { return 1; }
7713481Sgiacomo.travaglini@arm.com
7813481Sgiacomo.travaglini@arm.comclass NullaryFunctor {
7913481Sgiacomo.travaglini@arm.com public:
8013481Sgiacomo.travaglini@arm.com  int operator()() { return 2; }
8113481Sgiacomo.travaglini@arm.com};
8213481Sgiacomo.travaglini@arm.com
8313481Sgiacomo.travaglini@arm.combool g_done = false;
8413481Sgiacomo.travaglini@arm.comvoid VoidNullary() { g_done = true; }
8513481Sgiacomo.travaglini@arm.com
8613481Sgiacomo.travaglini@arm.comclass VoidNullaryFunctor {
8713481Sgiacomo.travaglini@arm.com public:
8813481Sgiacomo.travaglini@arm.com  void operator()() { g_done = true; }
8913481Sgiacomo.travaglini@arm.com};
9013481Sgiacomo.travaglini@arm.com
9113481Sgiacomo.travaglini@arm.combool Unary(int x) { return x < 0; }
9213481Sgiacomo.travaglini@arm.com
9313481Sgiacomo.travaglini@arm.comconst char* Plus1(const char* s) { return s + 1; }
9413481Sgiacomo.travaglini@arm.com
9513481Sgiacomo.travaglini@arm.comvoid VoidUnary(int /* n */) { g_done = true; }
9613481Sgiacomo.travaglini@arm.com
9713481Sgiacomo.travaglini@arm.combool ByConstRef(const string& s) { return s == "Hi"; }
9813481Sgiacomo.travaglini@arm.com
9913481Sgiacomo.travaglini@arm.comconst double g_double = 0;
10013481Sgiacomo.travaglini@arm.combool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
10113481Sgiacomo.travaglini@arm.com
10213481Sgiacomo.travaglini@arm.comstring ByNonConstRef(string& s) { return s += "+"; }  // NOLINT
10313481Sgiacomo.travaglini@arm.com
10413481Sgiacomo.travaglini@arm.comstruct UnaryFunctor {
10513481Sgiacomo.travaglini@arm.com  int operator()(bool x) { return x ? 1 : -1; }
10613481Sgiacomo.travaglini@arm.com};
10713481Sgiacomo.travaglini@arm.com
10813481Sgiacomo.travaglini@arm.comconst char* Binary(const char* input, short n) { return input + n; }  // NOLINT
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.comvoid VoidBinary(int, char) { g_done = true; }
11113481Sgiacomo.travaglini@arm.com
11213481Sgiacomo.travaglini@arm.comint Ternary(int x, char y, short z) { return x + y + z; }  // NOLINT
11313481Sgiacomo.travaglini@arm.com
11413481Sgiacomo.travaglini@arm.comvoid VoidTernary(int, char, bool) { g_done = true; }
11513481Sgiacomo.travaglini@arm.com
11613481Sgiacomo.travaglini@arm.comint SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
11713481Sgiacomo.travaglini@arm.com
11813481Sgiacomo.travaglini@arm.comint SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
11913481Sgiacomo.travaglini@arm.com
12013481Sgiacomo.travaglini@arm.comvoid VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
12113481Sgiacomo.travaglini@arm.com
12213481Sgiacomo.travaglini@arm.comstring Concat4(const char* s1, const char* s2, const char* s3,
12313481Sgiacomo.travaglini@arm.com               const char* s4) {
12413481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4;
12513481Sgiacomo.travaglini@arm.com}
12613481Sgiacomo.travaglini@arm.com
12713481Sgiacomo.travaglini@arm.comint SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
12813481Sgiacomo.travaglini@arm.com
12913481Sgiacomo.travaglini@arm.comstruct SumOf5Functor {
13013481Sgiacomo.travaglini@arm.com  int operator()(int a, int b, int c, int d, int e) {
13113481Sgiacomo.travaglini@arm.com    return a + b + c + d + e;
13213481Sgiacomo.travaglini@arm.com  }
13313481Sgiacomo.travaglini@arm.com};
13413481Sgiacomo.travaglini@arm.com
13513481Sgiacomo.travaglini@arm.comstring Concat5(const char* s1, const char* s2, const char* s3,
13613481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5) {
13713481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5;
13813481Sgiacomo.travaglini@arm.com}
13913481Sgiacomo.travaglini@arm.com
14013481Sgiacomo.travaglini@arm.comint SumOf6(int a, int b, int c, int d, int e, int f) {
14113481Sgiacomo.travaglini@arm.com  return a + b + c + d + e + f;
14213481Sgiacomo.travaglini@arm.com}
14313481Sgiacomo.travaglini@arm.com
14413481Sgiacomo.travaglini@arm.comstruct SumOf6Functor {
14513481Sgiacomo.travaglini@arm.com  int operator()(int a, int b, int c, int d, int e, int f) {
14613481Sgiacomo.travaglini@arm.com    return a + b + c + d + e + f;
14713481Sgiacomo.travaglini@arm.com  }
14813481Sgiacomo.travaglini@arm.com};
14913481Sgiacomo.travaglini@arm.com
15013481Sgiacomo.travaglini@arm.comstring Concat6(const char* s1, const char* s2, const char* s3,
15113481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5, const char* s6) {
15213481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6;
15313481Sgiacomo.travaglini@arm.com}
15413481Sgiacomo.travaglini@arm.com
15513481Sgiacomo.travaglini@arm.comstring Concat7(const char* s1, const char* s2, const char* s3,
15613481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5, const char* s6,
15713481Sgiacomo.travaglini@arm.com               const char* s7) {
15813481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
15913481Sgiacomo.travaglini@arm.com}
16013481Sgiacomo.travaglini@arm.com
16113481Sgiacomo.travaglini@arm.comstring Concat8(const char* s1, const char* s2, const char* s3,
16213481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5, const char* s6,
16313481Sgiacomo.travaglini@arm.com               const char* s7, const char* s8) {
16413481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
16513481Sgiacomo.travaglini@arm.com}
16613481Sgiacomo.travaglini@arm.com
16713481Sgiacomo.travaglini@arm.comstring Concat9(const char* s1, const char* s2, const char* s3,
16813481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5, const char* s6,
16913481Sgiacomo.travaglini@arm.com               const char* s7, const char* s8, const char* s9) {
17013481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
17113481Sgiacomo.travaglini@arm.com}
17213481Sgiacomo.travaglini@arm.com
17313481Sgiacomo.travaglini@arm.comstring Concat10(const char* s1, const char* s2, const char* s3,
17413481Sgiacomo.travaglini@arm.com                const char* s4, const char* s5, const char* s6,
17513481Sgiacomo.travaglini@arm.com                const char* s7, const char* s8, const char* s9,
17613481Sgiacomo.travaglini@arm.com                const char* s10) {
17713481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
17813481Sgiacomo.travaglini@arm.com}
17913481Sgiacomo.travaglini@arm.com
18013481Sgiacomo.travaglini@arm.comclass Foo {
18113481Sgiacomo.travaglini@arm.com public:
18213481Sgiacomo.travaglini@arm.com  Foo() : value_(123) {}
18313481Sgiacomo.travaglini@arm.com
18413481Sgiacomo.travaglini@arm.com  int Nullary() const { return value_; }
18513481Sgiacomo.travaglini@arm.com
18613481Sgiacomo.travaglini@arm.com  short Unary(long x) { return static_cast<short>(value_ + x); }  // NOLINT
18713481Sgiacomo.travaglini@arm.com
18813481Sgiacomo.travaglini@arm.com  string Binary(const string& str, char c) const { return str + c; }
18913481Sgiacomo.travaglini@arm.com
19013481Sgiacomo.travaglini@arm.com  int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
19113481Sgiacomo.travaglini@arm.com
19213481Sgiacomo.travaglini@arm.com  int SumOf4(int a, int b, int c, int d) const {
19313481Sgiacomo.travaglini@arm.com    return a + b + c + d + value_;
19413481Sgiacomo.travaglini@arm.com  }
19513481Sgiacomo.travaglini@arm.com
19613481Sgiacomo.travaglini@arm.com  int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
19713481Sgiacomo.travaglini@arm.com
19813481Sgiacomo.travaglini@arm.com  int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
19913481Sgiacomo.travaglini@arm.com
20013481Sgiacomo.travaglini@arm.com  int SumOf6(int a, int b, int c, int d, int e, int f) {
20113481Sgiacomo.travaglini@arm.com    return a + b + c + d + e + f;
20213481Sgiacomo.travaglini@arm.com  }
20313481Sgiacomo.travaglini@arm.com
20413481Sgiacomo.travaglini@arm.com  string Concat7(const char* s1, const char* s2, const char* s3,
20513481Sgiacomo.travaglini@arm.com                 const char* s4, const char* s5, const char* s6,
20613481Sgiacomo.travaglini@arm.com                 const char* s7) {
20713481Sgiacomo.travaglini@arm.com    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
20813481Sgiacomo.travaglini@arm.com  }
20913481Sgiacomo.travaglini@arm.com
21013481Sgiacomo.travaglini@arm.com  string Concat8(const char* s1, const char* s2, const char* s3,
21113481Sgiacomo.travaglini@arm.com                 const char* s4, const char* s5, const char* s6,
21213481Sgiacomo.travaglini@arm.com                 const char* s7, const char* s8) {
21313481Sgiacomo.travaglini@arm.com    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
21413481Sgiacomo.travaglini@arm.com  }
21513481Sgiacomo.travaglini@arm.com
21613481Sgiacomo.travaglini@arm.com  string Concat9(const char* s1, const char* s2, const char* s3,
21713481Sgiacomo.travaglini@arm.com                 const char* s4, const char* s5, const char* s6,
21813481Sgiacomo.travaglini@arm.com                 const char* s7, const char* s8, const char* s9) {
21913481Sgiacomo.travaglini@arm.com    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
22013481Sgiacomo.travaglini@arm.com  }
22113481Sgiacomo.travaglini@arm.com
22213481Sgiacomo.travaglini@arm.com  string Concat10(const char* s1, const char* s2, const char* s3,
22313481Sgiacomo.travaglini@arm.com                  const char* s4, const char* s5, const char* s6,
22413481Sgiacomo.travaglini@arm.com                  const char* s7, const char* s8, const char* s9,
22513481Sgiacomo.travaglini@arm.com                  const char* s10) {
22613481Sgiacomo.travaglini@arm.com    return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
22713481Sgiacomo.travaglini@arm.com  }
22813481Sgiacomo.travaglini@arm.com
22913481Sgiacomo.travaglini@arm.com private:
23013481Sgiacomo.travaglini@arm.com  int value_;
23113481Sgiacomo.travaglini@arm.com};
23213481Sgiacomo.travaglini@arm.com
23313481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a nullary function.
23413481Sgiacomo.travaglini@arm.comTEST(InvokeTest, Nullary) {
23513481Sgiacomo.travaglini@arm.com  Action<int()> a = Invoke(Nullary);  // NOLINT
23613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a.Perform(make_tuple()));
23713481Sgiacomo.travaglini@arm.com}
23813481Sgiacomo.travaglini@arm.com
23913481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a unary function.
24013481Sgiacomo.travaglini@arm.comTEST(InvokeTest, Unary) {
24113481Sgiacomo.travaglini@arm.com  Action<bool(int)> a = Invoke(Unary);  // NOLINT
24213481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(a.Perform(make_tuple(1)));
24313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(a.Perform(make_tuple(-1)));
24413481Sgiacomo.travaglini@arm.com}
24513481Sgiacomo.travaglini@arm.com
24613481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a binary function.
24713481Sgiacomo.travaglini@arm.comTEST(InvokeTest, Binary) {
24813481Sgiacomo.travaglini@arm.com  Action<const char*(const char*, short)> a = Invoke(Binary);  // NOLINT
24913481Sgiacomo.travaglini@arm.com  const char* p = "Hello";
25013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(p + 2, a.Perform(make_tuple(p, Short(2))));
25113481Sgiacomo.travaglini@arm.com}
25213481Sgiacomo.travaglini@arm.com
25313481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a ternary function.
25413481Sgiacomo.travaglini@arm.comTEST(InvokeTest, Ternary) {
25513481Sgiacomo.travaglini@arm.com  Action<int(int, char, short)> a = Invoke(Ternary);  // NOLINT
25613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', Short(3))));
25713481Sgiacomo.travaglini@arm.com}
25813481Sgiacomo.travaglini@arm.com
25913481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 4-argument function.
26013481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionThatTakes4Arguments) {
26113481Sgiacomo.travaglini@arm.com  Action<int(int, int, int, int)> a = Invoke(SumOf4);  // NOLINT
26213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
26313481Sgiacomo.travaglini@arm.com}
26413481Sgiacomo.travaglini@arm.com
26513481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 5-argument function.
26613481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionThatTakes5Arguments) {
26713481Sgiacomo.travaglini@arm.com  Action<int(int, int, int, int, int)> a = Invoke(SumOf5);  // NOLINT
26813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
26913481Sgiacomo.travaglini@arm.com}
27013481Sgiacomo.travaglini@arm.com
27113481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 6-argument function.
27213481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionThatTakes6Arguments) {
27313481Sgiacomo.travaglini@arm.com  Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6);  // NOLINT
27413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
27513481Sgiacomo.travaglini@arm.com}
27613481Sgiacomo.travaglini@arm.com
27713481Sgiacomo.travaglini@arm.com// A helper that turns the type of a C-string literal from const
27813481Sgiacomo.travaglini@arm.com// char[N] to const char*.
27913481Sgiacomo.travaglini@arm.cominline const char* CharPtr(const char* s) { return s; }
28013481Sgiacomo.travaglini@arm.com
28113481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 7-argument function.
28213481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionThatTakes7Arguments) {
28313481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
28413481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*)> a =
28513481Sgiacomo.travaglini@arm.com      Invoke(Concat7);
28613481Sgiacomo.travaglini@arm.com  EXPECT_EQ("1234567",
28713481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
28813481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
28913481Sgiacomo.travaglini@arm.com                                 CharPtr("7"))));
29013481Sgiacomo.travaglini@arm.com}
29113481Sgiacomo.travaglini@arm.com
29213481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 8-argument function.
29313481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionThatTakes8Arguments) {
29413481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
29513481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*, const char*)> a =
29613481Sgiacomo.travaglini@arm.com      Invoke(Concat8);
29713481Sgiacomo.travaglini@arm.com  EXPECT_EQ("12345678",
29813481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
29913481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
30013481Sgiacomo.travaglini@arm.com                                 CharPtr("7"), CharPtr("8"))));
30113481Sgiacomo.travaglini@arm.com}
30213481Sgiacomo.travaglini@arm.com
30313481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 9-argument function.
30413481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionThatTakes9Arguments) {
30513481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
30613481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*, const char*,
30713481Sgiacomo.travaglini@arm.com                const char*)> a = Invoke(Concat9);
30813481Sgiacomo.travaglini@arm.com  EXPECT_EQ("123456789",
30913481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
31013481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
31113481Sgiacomo.travaglini@arm.com                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
31213481Sgiacomo.travaglini@arm.com}
31313481Sgiacomo.travaglini@arm.com
31413481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 10-argument function.
31513481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionThatTakes10Arguments) {
31613481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
31713481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*, const char*,
31813481Sgiacomo.travaglini@arm.com                const char*, const char*)> a = Invoke(Concat10);
31913481Sgiacomo.travaglini@arm.com  EXPECT_EQ("1234567890",
32013481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
32113481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
32213481Sgiacomo.travaglini@arm.com                                 CharPtr("7"), CharPtr("8"), CharPtr("9"),
32313481Sgiacomo.travaglini@arm.com                                 CharPtr("0"))));
32413481Sgiacomo.travaglini@arm.com}
32513481Sgiacomo.travaglini@arm.com
32613481Sgiacomo.travaglini@arm.com// Tests using Invoke() with functions with parameters declared as Unused.
32713481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionWithUnusedParameters) {
32813481Sgiacomo.travaglini@arm.com  Action<int(int, int, double, const string&)> a1 =
32913481Sgiacomo.travaglini@arm.com      Invoke(SumOfFirst2);
33013481Sgiacomo.travaglini@arm.com  string s("hi");
33113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(12, a1.Perform(
33213481Sgiacomo.travaglini@arm.com    tuple<int, int, double, const string&>(10, 2, 5.6, s)));
33313481Sgiacomo.travaglini@arm.com
33413481Sgiacomo.travaglini@arm.com  Action<int(int, int, bool, int*)> a2 =
33513481Sgiacomo.travaglini@arm.com      Invoke(SumOfFirst2);
33613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
33713481Sgiacomo.travaglini@arm.com}
33813481Sgiacomo.travaglini@arm.com
33913481Sgiacomo.travaglini@arm.com// Tests using Invoke() with methods with parameters declared as Unused.
34013481Sgiacomo.travaglini@arm.comTEST(InvokeTest, MethodWithUnusedParameters) {
34113481Sgiacomo.travaglini@arm.com  Foo foo;
34213481Sgiacomo.travaglini@arm.com  Action<int(string, bool, int, int)> a1 =
34313481Sgiacomo.travaglini@arm.com      Invoke(&foo, &Foo::SumOfLast2);
34413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
34513481Sgiacomo.travaglini@arm.com
34613481Sgiacomo.travaglini@arm.com  Action<int(char, double, int, int)> a2 =
34713481Sgiacomo.travaglini@arm.com      Invoke(&foo, &Foo::SumOfLast2);
34813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
34913481Sgiacomo.travaglini@arm.com}
35013481Sgiacomo.travaglini@arm.com
35113481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a functor.
35213481Sgiacomo.travaglini@arm.comTEST(InvokeTest, Functor) {
35313481Sgiacomo.travaglini@arm.com  Action<long(long, int)> a = Invoke(plus<long>());  // NOLINT
35413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3L, a.Perform(make_tuple(1, 2)));
35513481Sgiacomo.travaglini@arm.com}
35613481Sgiacomo.travaglini@arm.com
35713481Sgiacomo.travaglini@arm.com// Tests using Invoke(f) as an action of a compatible type.
35813481Sgiacomo.travaglini@arm.comTEST(InvokeTest, FunctionWithCompatibleType) {
35913481Sgiacomo.travaglini@arm.com  Action<long(int, short, char, bool)> a = Invoke(SumOf4);  // NOLINT
36013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4321, a.Perform(make_tuple(4000, Short(300), Char(20), true)));
36113481Sgiacomo.travaglini@arm.com}
36213481Sgiacomo.travaglini@arm.com
36313481Sgiacomo.travaglini@arm.com// Tests using Invoke() with an object pointer and a method pointer.
36413481Sgiacomo.travaglini@arm.com
36513481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a nullary method.
36613481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, Nullary) {
36713481Sgiacomo.travaglini@arm.com  Foo foo;
36813481Sgiacomo.travaglini@arm.com  Action<int()> a = Invoke(&foo, &Foo::Nullary);  // NOLINT
36913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123, a.Perform(make_tuple()));
37013481Sgiacomo.travaglini@arm.com}
37113481Sgiacomo.travaglini@arm.com
37213481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a unary method.
37313481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, Unary) {
37413481Sgiacomo.travaglini@arm.com  Foo foo;
37513481Sgiacomo.travaglini@arm.com  Action<short(long)> a = Invoke(&foo, &Foo::Unary);  // NOLINT
37613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
37713481Sgiacomo.travaglini@arm.com}
37813481Sgiacomo.travaglini@arm.com
37913481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a binary method.
38013481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, Binary) {
38113481Sgiacomo.travaglini@arm.com  Foo foo;
38213481Sgiacomo.travaglini@arm.com  Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
38313481Sgiacomo.travaglini@arm.com  string s("Hell");
38413481Sgiacomo.travaglini@arm.com  EXPECT_EQ("Hello", a.Perform(
38513481Sgiacomo.travaglini@arm.com      tuple<const string&, char>(s, 'o')));
38613481Sgiacomo.travaglini@arm.com}
38713481Sgiacomo.travaglini@arm.com
38813481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a ternary method.
38913481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, Ternary) {
39013481Sgiacomo.travaglini@arm.com  Foo foo;
39113481Sgiacomo.travaglini@arm.com  Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary);  // NOLINT
39213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, Char(1))));
39313481Sgiacomo.travaglini@arm.com}
39413481Sgiacomo.travaglini@arm.com
39513481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 4-argument method.
39613481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodThatTakes4Arguments) {
39713481Sgiacomo.travaglini@arm.com  Foo foo;
39813481Sgiacomo.travaglini@arm.com  Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4);  // NOLINT
39913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
40013481Sgiacomo.travaglini@arm.com}
40113481Sgiacomo.travaglini@arm.com
40213481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 5-argument method.
40313481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodThatTakes5Arguments) {
40413481Sgiacomo.travaglini@arm.com  Foo foo;
40513481Sgiacomo.travaglini@arm.com  Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5);  // NOLINT
40613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
40713481Sgiacomo.travaglini@arm.com}
40813481Sgiacomo.travaglini@arm.com
40913481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 6-argument method.
41013481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodThatTakes6Arguments) {
41113481Sgiacomo.travaglini@arm.com  Foo foo;
41213481Sgiacomo.travaglini@arm.com  Action<int(int, int, int, int, int, int)> a =  // NOLINT
41313481Sgiacomo.travaglini@arm.com      Invoke(&foo, &Foo::SumOf6);
41413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
41513481Sgiacomo.travaglini@arm.com}
41613481Sgiacomo.travaglini@arm.com
41713481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 7-argument method.
41813481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodThatTakes7Arguments) {
41913481Sgiacomo.travaglini@arm.com  Foo foo;
42013481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
42113481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*)> a =
42213481Sgiacomo.travaglini@arm.com      Invoke(&foo, &Foo::Concat7);
42313481Sgiacomo.travaglini@arm.com  EXPECT_EQ("1234567",
42413481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
42513481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
42613481Sgiacomo.travaglini@arm.com                                 CharPtr("7"))));
42713481Sgiacomo.travaglini@arm.com}
42813481Sgiacomo.travaglini@arm.com
42913481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 8-argument method.
43013481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodThatTakes8Arguments) {
43113481Sgiacomo.travaglini@arm.com  Foo foo;
43213481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
43313481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*, const char*)> a =
43413481Sgiacomo.travaglini@arm.com      Invoke(&foo, &Foo::Concat8);
43513481Sgiacomo.travaglini@arm.com  EXPECT_EQ("12345678",
43613481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
43713481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
43813481Sgiacomo.travaglini@arm.com                                 CharPtr("7"), CharPtr("8"))));
43913481Sgiacomo.travaglini@arm.com}
44013481Sgiacomo.travaglini@arm.com
44113481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 9-argument method.
44213481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodThatTakes9Arguments) {
44313481Sgiacomo.travaglini@arm.com  Foo foo;
44413481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
44513481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*, const char*,
44613481Sgiacomo.travaglini@arm.com                const char*)> a = Invoke(&foo, &Foo::Concat9);
44713481Sgiacomo.travaglini@arm.com  EXPECT_EQ("123456789",
44813481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
44913481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
45013481Sgiacomo.travaglini@arm.com                                 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
45113481Sgiacomo.travaglini@arm.com}
45213481Sgiacomo.travaglini@arm.com
45313481Sgiacomo.travaglini@arm.com// Tests using Invoke() with a 10-argument method.
45413481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodThatTakes10Arguments) {
45513481Sgiacomo.travaglini@arm.com  Foo foo;
45613481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*,
45713481Sgiacomo.travaglini@arm.com                const char*, const char*, const char*, const char*,
45813481Sgiacomo.travaglini@arm.com                const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
45913481Sgiacomo.travaglini@arm.com  EXPECT_EQ("1234567890",
46013481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
46113481Sgiacomo.travaglini@arm.com                                 CharPtr("4"), CharPtr("5"), CharPtr("6"),
46213481Sgiacomo.travaglini@arm.com                                 CharPtr("7"), CharPtr("8"), CharPtr("9"),
46313481Sgiacomo.travaglini@arm.com                                 CharPtr("0"))));
46413481Sgiacomo.travaglini@arm.com}
46513481Sgiacomo.travaglini@arm.com
46613481Sgiacomo.travaglini@arm.com// Tests using Invoke(f) as an action of a compatible type.
46713481Sgiacomo.travaglini@arm.comTEST(InvokeMethodTest, MethodWithCompatibleType) {
46813481Sgiacomo.travaglini@arm.com  Foo foo;
46913481Sgiacomo.travaglini@arm.com  Action<long(int, short, char, bool)> a =  // NOLINT
47013481Sgiacomo.travaglini@arm.com      Invoke(&foo, &Foo::SumOf4);
47113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4444, a.Perform(make_tuple(4000, Short(300), Char(20), true)));
47213481Sgiacomo.travaglini@arm.com}
47313481Sgiacomo.travaglini@arm.com
47413481Sgiacomo.travaglini@arm.com// Tests using WithoutArgs with an action that takes no argument.
47513481Sgiacomo.travaglini@arm.comTEST(WithoutArgsTest, NoArg) {
47613481Sgiacomo.travaglini@arm.com  Action<int(int n)> a = WithoutArgs(Invoke(Nullary));  // NOLINT
47713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a.Perform(make_tuple(2)));
47813481Sgiacomo.travaglini@arm.com}
47913481Sgiacomo.travaglini@arm.com
48013481Sgiacomo.travaglini@arm.com// Tests using WithArg with an action that takes 1 argument.
48113481Sgiacomo.travaglini@arm.comTEST(WithArgTest, OneArg) {
48213481Sgiacomo.travaglini@arm.com  Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary));  // NOLINT
48313481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(b.Perform(make_tuple(1.5, -1)));
48413481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(b.Perform(make_tuple(1.5, 1)));
48513481Sgiacomo.travaglini@arm.com}
48613481Sgiacomo.travaglini@arm.com
48713481Sgiacomo.travaglini@arm.comTEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
48813481Sgiacomo.travaglini@arm.com  const Action<int(int)> a = ReturnArg<0>();
48913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(5, a.Perform(make_tuple(5)));
49013481Sgiacomo.travaglini@arm.com}
49113481Sgiacomo.travaglini@arm.com
49213481Sgiacomo.travaglini@arm.comTEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
49313481Sgiacomo.travaglini@arm.com  const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
49413481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
49513481Sgiacomo.travaglini@arm.com}
49613481Sgiacomo.travaglini@arm.com
49713481Sgiacomo.travaglini@arm.comTEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
49813481Sgiacomo.travaglini@arm.com  const Action<string(int, int, string, int)> a = ReturnArg<2>();
49913481Sgiacomo.travaglini@arm.com  EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
50013481Sgiacomo.travaglini@arm.com}
50113481Sgiacomo.travaglini@arm.com
50213481Sgiacomo.travaglini@arm.comTEST(SaveArgActionTest, WorksForSameType) {
50313481Sgiacomo.travaglini@arm.com  int result = 0;
50413481Sgiacomo.travaglini@arm.com  const Action<void(int n)> a1 = SaveArg<0>(&result);
50513481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(5));
50613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(5, result);
50713481Sgiacomo.travaglini@arm.com}
50813481Sgiacomo.travaglini@arm.com
50913481Sgiacomo.travaglini@arm.comTEST(SaveArgActionTest, WorksForCompatibleType) {
51013481Sgiacomo.travaglini@arm.com  int result = 0;
51113481Sgiacomo.travaglini@arm.com  const Action<void(bool, char)> a1 = SaveArg<1>(&result);
51213481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(true, 'a'));
51313481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', result);
51413481Sgiacomo.travaglini@arm.com}
51513481Sgiacomo.travaglini@arm.com
51613481Sgiacomo.travaglini@arm.comTEST(SaveArgPointeeActionTest, WorksForSameType) {
51713481Sgiacomo.travaglini@arm.com  int result = 0;
51813481Sgiacomo.travaglini@arm.com  const int value = 5;
51913481Sgiacomo.travaglini@arm.com  const Action<void(const int*)> a1 = SaveArgPointee<0>(&result);
52013481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(&value));
52113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(5, result);
52213481Sgiacomo.travaglini@arm.com}
52313481Sgiacomo.travaglini@arm.com
52413481Sgiacomo.travaglini@arm.comTEST(SaveArgPointeeActionTest, WorksForCompatibleType) {
52513481Sgiacomo.travaglini@arm.com  int result = 0;
52613481Sgiacomo.travaglini@arm.com  char value = 'a';
52713481Sgiacomo.travaglini@arm.com  const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result);
52813481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(true, &value));
52913481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', result);
53013481Sgiacomo.travaglini@arm.com}
53113481Sgiacomo.travaglini@arm.com
53213481Sgiacomo.travaglini@arm.comTEST(SaveArgPointeeActionTest, WorksForLinkedPtr) {
53313481Sgiacomo.travaglini@arm.com  int result = 0;
53413481Sgiacomo.travaglini@arm.com  linked_ptr<int> value(new int(5));
53513481Sgiacomo.travaglini@arm.com  const Action<void(linked_ptr<int>)> a1 = SaveArgPointee<0>(&result);
53613481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(value));
53713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(5, result);
53813481Sgiacomo.travaglini@arm.com}
53913481Sgiacomo.travaglini@arm.com
54013481Sgiacomo.travaglini@arm.comTEST(SetArgRefereeActionTest, WorksForSameType) {
54113481Sgiacomo.travaglini@arm.com  int value = 0;
54213481Sgiacomo.travaglini@arm.com  const Action<void(int&)> a1 = SetArgReferee<0>(1);
54313481Sgiacomo.travaglini@arm.com  a1.Perform(tuple<int&>(value));
54413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, value);
54513481Sgiacomo.travaglini@arm.com}
54613481Sgiacomo.travaglini@arm.com
54713481Sgiacomo.travaglini@arm.comTEST(SetArgRefereeActionTest, WorksForCompatibleType) {
54813481Sgiacomo.travaglini@arm.com  int value = 0;
54913481Sgiacomo.travaglini@arm.com  const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
55013481Sgiacomo.travaglini@arm.com  a1.Perform(tuple<int, int&>(0, value));
55113481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', value);
55213481Sgiacomo.travaglini@arm.com}
55313481Sgiacomo.travaglini@arm.com
55413481Sgiacomo.travaglini@arm.comTEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
55513481Sgiacomo.travaglini@arm.com  int value = 0;
55613481Sgiacomo.travaglini@arm.com  const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
55713481Sgiacomo.travaglini@arm.com  a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
55813481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', value);
55913481Sgiacomo.travaglini@arm.com}
56013481Sgiacomo.travaglini@arm.com
56113481Sgiacomo.travaglini@arm.com// A class that can be used to verify that its destructor is called: it will set
56213481Sgiacomo.travaglini@arm.com// the bool provided to the constructor to true when destroyed.
56313481Sgiacomo.travaglini@arm.comclass DeletionTester {
56413481Sgiacomo.travaglini@arm.com public:
56513481Sgiacomo.travaglini@arm.com  explicit DeletionTester(bool* is_deleted)
56613481Sgiacomo.travaglini@arm.com    : is_deleted_(is_deleted) {
56713481Sgiacomo.travaglini@arm.com    // Make sure the bit is set to false.
56813481Sgiacomo.travaglini@arm.com    *is_deleted_ = false;
56913481Sgiacomo.travaglini@arm.com  }
57013481Sgiacomo.travaglini@arm.com
57113481Sgiacomo.travaglini@arm.com  ~DeletionTester() {
57213481Sgiacomo.travaglini@arm.com    *is_deleted_ = true;
57313481Sgiacomo.travaglini@arm.com  }
57413481Sgiacomo.travaglini@arm.com
57513481Sgiacomo.travaglini@arm.com private:
57613481Sgiacomo.travaglini@arm.com  bool* is_deleted_;
57713481Sgiacomo.travaglini@arm.com};
57813481Sgiacomo.travaglini@arm.com
57913481Sgiacomo.travaglini@arm.comTEST(DeleteArgActionTest, OneArg) {
58013481Sgiacomo.travaglini@arm.com  bool is_deleted = false;
58113481Sgiacomo.travaglini@arm.com  DeletionTester* t = new DeletionTester(&is_deleted);
58213481Sgiacomo.travaglini@arm.com  const Action<void(DeletionTester*)> a1 = DeleteArg<0>();      // NOLINT
58313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(is_deleted);
58413481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(t));
58513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(is_deleted);
58613481Sgiacomo.travaglini@arm.com}
58713481Sgiacomo.travaglini@arm.com
58813481Sgiacomo.travaglini@arm.comTEST(DeleteArgActionTest, TenArgs) {
58913481Sgiacomo.travaglini@arm.com  bool is_deleted = false;
59013481Sgiacomo.travaglini@arm.com  DeletionTester* t = new DeletionTester(&is_deleted);
59113481Sgiacomo.travaglini@arm.com  const Action<void(bool, int, int, const char*, bool,
59213481Sgiacomo.travaglini@arm.com                    int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
59313481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(is_deleted);
59413481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
59513481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(is_deleted);
59613481Sgiacomo.travaglini@arm.com}
59713481Sgiacomo.travaglini@arm.com
59813481Sgiacomo.travaglini@arm.com#if GTEST_HAS_EXCEPTIONS
59913481Sgiacomo.travaglini@arm.com
60013481Sgiacomo.travaglini@arm.comTEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
60113481Sgiacomo.travaglini@arm.com  const Action<void(int n)> a = Throw('a');
60213481Sgiacomo.travaglini@arm.com  EXPECT_THROW(a.Perform(make_tuple(0)), char);
60313481Sgiacomo.travaglini@arm.com}
60413481Sgiacomo.travaglini@arm.com
60513481Sgiacomo.travaglini@arm.comclass MyException {};
60613481Sgiacomo.travaglini@arm.com
60713481Sgiacomo.travaglini@arm.comTEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
60813481Sgiacomo.travaglini@arm.com  const Action<double(char ch)> a = Throw(MyException());
60913481Sgiacomo.travaglini@arm.com  EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
61013481Sgiacomo.travaglini@arm.com}
61113481Sgiacomo.travaglini@arm.com
61213481Sgiacomo.travaglini@arm.comTEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
61313481Sgiacomo.travaglini@arm.com  const Action<double()> a = Throw(MyException());
61413481Sgiacomo.travaglini@arm.com  EXPECT_THROW(a.Perform(make_tuple()), MyException);
61513481Sgiacomo.travaglini@arm.com}
61613481Sgiacomo.travaglini@arm.com
61713481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_EXCEPTIONS
61813481Sgiacomo.travaglini@arm.com
61913481Sgiacomo.travaglini@arm.com// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
62013481Sgiacomo.travaglini@arm.com// pointed to by the N-th (0-based) argument to values in range [first, last).
62113481Sgiacomo.travaglini@arm.comTEST(SetArrayArgumentTest, SetsTheNthArray) {
62213481Sgiacomo.travaglini@arm.com  typedef void MyFunction(bool, int*, char*);
62313481Sgiacomo.travaglini@arm.com  int numbers[] = { 1, 2, 3 };
62413481Sgiacomo.travaglini@arm.com  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
62513481Sgiacomo.travaglini@arm.com
62613481Sgiacomo.travaglini@arm.com  int n[4] = {};
62713481Sgiacomo.travaglini@arm.com  int* pn = n;
62813481Sgiacomo.travaglini@arm.com  char ch[4] = {};
62913481Sgiacomo.travaglini@arm.com  char* pch = ch;
63013481Sgiacomo.travaglini@arm.com  a.Perform(make_tuple(true, pn, pch));
63113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, n[0]);
63213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n[1]);
63313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, n[2]);
63413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[3]);
63513481Sgiacomo.travaglini@arm.com  EXPECT_EQ('\0', ch[0]);
63613481Sgiacomo.travaglini@arm.com  EXPECT_EQ('\0', ch[1]);
63713481Sgiacomo.travaglini@arm.com  EXPECT_EQ('\0', ch[2]);
63813481Sgiacomo.travaglini@arm.com  EXPECT_EQ('\0', ch[3]);
63913481Sgiacomo.travaglini@arm.com
64013481Sgiacomo.travaglini@arm.com  // Tests first and last are iterators.
64113481Sgiacomo.travaglini@arm.com  std::string letters = "abc";
64213481Sgiacomo.travaglini@arm.com  a = SetArrayArgument<2>(letters.begin(), letters.end());
64313481Sgiacomo.travaglini@arm.com  std::fill_n(n, 4, 0);
64413481Sgiacomo.travaglini@arm.com  std::fill_n(ch, 4, '\0');
64513481Sgiacomo.travaglini@arm.com  a.Perform(make_tuple(true, pn, pch));
64613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[0]);
64713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[1]);
64813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[2]);
64913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[3]);
65013481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', ch[0]);
65113481Sgiacomo.travaglini@arm.com  EXPECT_EQ('b', ch[1]);
65213481Sgiacomo.travaglini@arm.com  EXPECT_EQ('c', ch[2]);
65313481Sgiacomo.travaglini@arm.com  EXPECT_EQ('\0', ch[3]);
65413481Sgiacomo.travaglini@arm.com}
65513481Sgiacomo.travaglini@arm.com
65613481Sgiacomo.travaglini@arm.com// Tests SetArrayArgument<N>(first, last) where first == last.
65713481Sgiacomo.travaglini@arm.comTEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
65813481Sgiacomo.travaglini@arm.com  typedef void MyFunction(bool, int*);
65913481Sgiacomo.travaglini@arm.com  int numbers[] = { 1, 2, 3 };
66013481Sgiacomo.travaglini@arm.com  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
66113481Sgiacomo.travaglini@arm.com
66213481Sgiacomo.travaglini@arm.com  int n[4] = {};
66313481Sgiacomo.travaglini@arm.com  int* pn = n;
66413481Sgiacomo.travaglini@arm.com  a.Perform(make_tuple(true, pn));
66513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[0]);
66613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[1]);
66713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[2]);
66813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, n[3]);
66913481Sgiacomo.travaglini@arm.com}
67013481Sgiacomo.travaglini@arm.com
67113481Sgiacomo.travaglini@arm.com// Tests SetArrayArgument<N>(first, last) where *first is convertible
67213481Sgiacomo.travaglini@arm.com// (but not equal) to the argument type.
67313481Sgiacomo.travaglini@arm.comTEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
67413481Sgiacomo.travaglini@arm.com  typedef void MyFunction(bool, int*);
67513481Sgiacomo.travaglini@arm.com  char chars[] = { 97, 98, 99 };
67613481Sgiacomo.travaglini@arm.com  Action<MyFunction> a = SetArrayArgument<1>(chars, chars + 3);
67713481Sgiacomo.travaglini@arm.com
67813481Sgiacomo.travaglini@arm.com  int codes[4] = { 111, 222, 333, 444 };
67913481Sgiacomo.travaglini@arm.com  int* pcodes = codes;
68013481Sgiacomo.travaglini@arm.com  a.Perform(make_tuple(true, pcodes));
68113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(97, codes[0]);
68213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(98, codes[1]);
68313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(99, codes[2]);
68413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(444, codes[3]);
68513481Sgiacomo.travaglini@arm.com}
68613481Sgiacomo.travaglini@arm.com
68713481Sgiacomo.travaglini@arm.com// Test SetArrayArgument<N>(first, last) with iterator as argument.
68813481Sgiacomo.travaglini@arm.comTEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
68913481Sgiacomo.travaglini@arm.com  typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
69013481Sgiacomo.travaglini@arm.com  std::string letters = "abc";
69113481Sgiacomo.travaglini@arm.com  Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
69213481Sgiacomo.travaglini@arm.com
69313481Sgiacomo.travaglini@arm.com  std::string s;
69413481Sgiacomo.travaglini@arm.com  a.Perform(make_tuple(true, back_inserter(s)));
69513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(letters, s);
69613481Sgiacomo.travaglini@arm.com}
69713481Sgiacomo.travaglini@arm.com
69813481Sgiacomo.travaglini@arm.comTEST(ReturnPointeeTest, Works) {
69913481Sgiacomo.travaglini@arm.com  int n = 42;
70013481Sgiacomo.travaglini@arm.com  const Action<int()> a = ReturnPointee(&n);
70113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(42, a.Perform(make_tuple()));
70213481Sgiacomo.travaglini@arm.com
70313481Sgiacomo.travaglini@arm.com  n = 43;
70413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(43, a.Perform(make_tuple()));
70513481Sgiacomo.travaglini@arm.com}
70613481Sgiacomo.travaglini@arm.com
70713481Sgiacomo.travaglini@arm.com}  // namespace gmock_generated_actions_test
70813481Sgiacomo.travaglini@arm.com}  // namespace testing
709