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 generated by a script.
3513481Sgiacomo.travaglini@arm.com
3613481Sgiacomo.travaglini@arm.com#include "gmock/gmock-generated-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
4413481Sgiacomo.travaglini@arm.comnamespace testing {
4513481Sgiacomo.travaglini@arm.comnamespace gmock_generated_actions_test {
4613481Sgiacomo.travaglini@arm.com
4713481Sgiacomo.travaglini@arm.comusing ::std::plus;
4813481Sgiacomo.travaglini@arm.comusing ::std::string;
4913481Sgiacomo.travaglini@arm.comusing testing::get;
5013481Sgiacomo.travaglini@arm.comusing testing::make_tuple;
5113481Sgiacomo.travaglini@arm.comusing testing::tuple;
5213481Sgiacomo.travaglini@arm.comusing testing::tuple_element;
5313481Sgiacomo.travaglini@arm.comusing testing::_;
5413481Sgiacomo.travaglini@arm.comusing testing::Action;
5513481Sgiacomo.travaglini@arm.comusing testing::ActionInterface;
5613481Sgiacomo.travaglini@arm.comusing testing::ByRef;
5713481Sgiacomo.travaglini@arm.comusing testing::DoAll;
5813481Sgiacomo.travaglini@arm.comusing testing::Invoke;
5913481Sgiacomo.travaglini@arm.comusing testing::Return;
6013481Sgiacomo.travaglini@arm.comusing testing::ReturnNew;
6113481Sgiacomo.travaglini@arm.comusing testing::SetArgPointee;
6213481Sgiacomo.travaglini@arm.comusing testing::StaticAssertTypeEq;
6313481Sgiacomo.travaglini@arm.comusing testing::Unused;
6413481Sgiacomo.travaglini@arm.comusing testing::WithArgs;
6513481Sgiacomo.travaglini@arm.com
6613481Sgiacomo.travaglini@arm.com// For suppressing compiler warnings on conversion possibly losing precision.
6713481Sgiacomo.travaglini@arm.cominline short Short(short n) { return n; }  // NOLINT
6813481Sgiacomo.travaglini@arm.cominline char Char(char ch) { return ch; }
6913481Sgiacomo.travaglini@arm.com
7013481Sgiacomo.travaglini@arm.com// Sample functions and functors for testing various actions.
7113481Sgiacomo.travaglini@arm.comint Nullary() { return 1; }
7213481Sgiacomo.travaglini@arm.com
7313481Sgiacomo.travaglini@arm.comclass NullaryFunctor {
7413481Sgiacomo.travaglini@arm.com public:
7513481Sgiacomo.travaglini@arm.com  int operator()() { return 2; }
7613481Sgiacomo.travaglini@arm.com};
7713481Sgiacomo.travaglini@arm.com
7813481Sgiacomo.travaglini@arm.combool g_done = false;
7913481Sgiacomo.travaglini@arm.com
8013481Sgiacomo.travaglini@arm.combool Unary(int x) { return x < 0; }
8113481Sgiacomo.travaglini@arm.com
8213481Sgiacomo.travaglini@arm.comconst char* Plus1(const char* s) { return s + 1; }
8313481Sgiacomo.travaglini@arm.com
8413481Sgiacomo.travaglini@arm.combool ByConstRef(const string& s) { return s == "Hi"; }
8513481Sgiacomo.travaglini@arm.com
8613481Sgiacomo.travaglini@arm.comconst double g_double = 0;
8713481Sgiacomo.travaglini@arm.combool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
8813481Sgiacomo.travaglini@arm.com
8913481Sgiacomo.travaglini@arm.comstring ByNonConstRef(string& s) { return s += "+"; }  // NOLINT
9013481Sgiacomo.travaglini@arm.com
9113481Sgiacomo.travaglini@arm.comstruct UnaryFunctor {
9213481Sgiacomo.travaglini@arm.com  int operator()(bool x) { return x ? 1 : -1; }
9313481Sgiacomo.travaglini@arm.com};
9413481Sgiacomo.travaglini@arm.com
9513481Sgiacomo.travaglini@arm.comconst char* Binary(const char* input, short n) { return input + n; }  // NOLINT
9613481Sgiacomo.travaglini@arm.com
9713481Sgiacomo.travaglini@arm.comvoid VoidBinary(int, char) { g_done = true; }
9813481Sgiacomo.travaglini@arm.com
9913481Sgiacomo.travaglini@arm.comint Ternary(int x, char y, short z) { return x + y + z; }  // NOLINT
10013481Sgiacomo.travaglini@arm.com
10113481Sgiacomo.travaglini@arm.comvoid VoidTernary(int, char, bool) { g_done = true; }
10213481Sgiacomo.travaglini@arm.com
10313481Sgiacomo.travaglini@arm.comint SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
10413481Sgiacomo.travaglini@arm.com
10513481Sgiacomo.travaglini@arm.comstring Concat4(const char* s1, const char* s2, const char* s3,
10613481Sgiacomo.travaglini@arm.com               const char* s4) {
10713481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4;
10813481Sgiacomo.travaglini@arm.com}
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.comint SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
11113481Sgiacomo.travaglini@arm.com
11213481Sgiacomo.travaglini@arm.comstruct SumOf5Functor {
11313481Sgiacomo.travaglini@arm.com  int operator()(int a, int b, int c, int d, int e) {
11413481Sgiacomo.travaglini@arm.com    return a + b + c + d + e;
11513481Sgiacomo.travaglini@arm.com  }
11613481Sgiacomo.travaglini@arm.com};
11713481Sgiacomo.travaglini@arm.com
11813481Sgiacomo.travaglini@arm.comstring Concat5(const char* s1, const char* s2, const char* s3,
11913481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5) {
12013481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5;
12113481Sgiacomo.travaglini@arm.com}
12213481Sgiacomo.travaglini@arm.com
12313481Sgiacomo.travaglini@arm.comint SumOf6(int a, int b, int c, int d, int e, int f) {
12413481Sgiacomo.travaglini@arm.com  return a + b + c + d + e + f;
12513481Sgiacomo.travaglini@arm.com}
12613481Sgiacomo.travaglini@arm.com
12713481Sgiacomo.travaglini@arm.comstruct SumOf6Functor {
12813481Sgiacomo.travaglini@arm.com  int operator()(int a, int b, int c, int d, int e, int f) {
12913481Sgiacomo.travaglini@arm.com    return a + b + c + d + e + f;
13013481Sgiacomo.travaglini@arm.com  }
13113481Sgiacomo.travaglini@arm.com};
13213481Sgiacomo.travaglini@arm.com
13313481Sgiacomo.travaglini@arm.comstring Concat6(const char* s1, const char* s2, const char* s3,
13413481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5, const char* s6) {
13513481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6;
13613481Sgiacomo.travaglini@arm.com}
13713481Sgiacomo.travaglini@arm.com
13813481Sgiacomo.travaglini@arm.comstring Concat7(const char* s1, const char* s2, const char* s3,
13913481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5, const char* s6,
14013481Sgiacomo.travaglini@arm.com               const char* s7) {
14113481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
14213481Sgiacomo.travaglini@arm.com}
14313481Sgiacomo.travaglini@arm.com
14413481Sgiacomo.travaglini@arm.comstring Concat8(const char* s1, const char* s2, const char* s3,
14513481Sgiacomo.travaglini@arm.com               const char* s4, const char* s5, const char* s6,
14613481Sgiacomo.travaglini@arm.com               const char* s7, const char* s8) {
14713481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
14813481Sgiacomo.travaglini@arm.com}
14913481Sgiacomo.travaglini@arm.com
15013481Sgiacomo.travaglini@arm.comstring Concat9(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               const char* s7, const char* s8, const char* s9) {
15313481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
15413481Sgiacomo.travaglini@arm.com}
15513481Sgiacomo.travaglini@arm.com
15613481Sgiacomo.travaglini@arm.comstring Concat10(const char* s1, const char* s2, const char* s3,
15713481Sgiacomo.travaglini@arm.com                const char* s4, const char* s5, const char* s6,
15813481Sgiacomo.travaglini@arm.com                const char* s7, const char* s8, const char* s9,
15913481Sgiacomo.travaglini@arm.com                const char* s10) {
16013481Sgiacomo.travaglini@arm.com  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
16113481Sgiacomo.travaglini@arm.com}
16213481Sgiacomo.travaglini@arm.com
16313481Sgiacomo.travaglini@arm.com// A helper that turns the type of a C-string literal from const
16413481Sgiacomo.travaglini@arm.com// char[N] to const char*.
16513481Sgiacomo.travaglini@arm.cominline const char* CharPtr(const char* s) { return s; }
16613481Sgiacomo.travaglini@arm.com
16713481Sgiacomo.travaglini@arm.com// Tests InvokeArgument<N>(...).
16813481Sgiacomo.travaglini@arm.com
16913481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a nullary function.
17013481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Function0) {
17113481Sgiacomo.travaglini@arm.com  Action<int(int, int(*)())> a = InvokeArgument<1>();  // NOLINT
17213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary)));
17313481Sgiacomo.travaglini@arm.com}
17413481Sgiacomo.travaglini@arm.com
17513481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a unary function.
17613481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Functor1) {
17713481Sgiacomo.travaglini@arm.com  Action<int(UnaryFunctor)> a = InvokeArgument<0>(true);  // NOLINT
17813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor())));
17913481Sgiacomo.travaglini@arm.com}
18013481Sgiacomo.travaglini@arm.com
18113481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 5-ary function.
18213481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Function5) {
18313481Sgiacomo.travaglini@arm.com  Action<int(int(*)(int, int, int, int, int))> a =  // NOLINT
18413481Sgiacomo.travaglini@arm.com      InvokeArgument<0>(10000, 2000, 300, 40, 5);
18513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5)));
18613481Sgiacomo.travaglini@arm.com}
18713481Sgiacomo.travaglini@arm.com
18813481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 5-ary functor.
18913481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Functor5) {
19013481Sgiacomo.travaglini@arm.com  Action<int(SumOf5Functor)> a =  // NOLINT
19113481Sgiacomo.travaglini@arm.com      InvokeArgument<0>(10000, 2000, 300, 40, 5);
19213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor())));
19313481Sgiacomo.travaglini@arm.com}
19413481Sgiacomo.travaglini@arm.com
19513481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 6-ary function.
19613481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Function6) {
19713481Sgiacomo.travaglini@arm.com  Action<int(int(*)(int, int, int, int, int, int))> a =  // NOLINT
19813481Sgiacomo.travaglini@arm.com      InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
19913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6)));
20013481Sgiacomo.travaglini@arm.com}
20113481Sgiacomo.travaglini@arm.com
20213481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 6-ary functor.
20313481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Functor6) {
20413481Sgiacomo.travaglini@arm.com  Action<int(SumOf6Functor)> a =  // NOLINT
20513481Sgiacomo.travaglini@arm.com      InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
20613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor())));
20713481Sgiacomo.travaglini@arm.com}
20813481Sgiacomo.travaglini@arm.com
20913481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 7-ary function.
21013481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Function7) {
21113481Sgiacomo.travaglini@arm.com  Action<string(string(*)(const char*, const char*, const char*,
21213481Sgiacomo.travaglini@arm.com                          const char*, const char*, const char*,
21313481Sgiacomo.travaglini@arm.com                          const char*))> a =
21413481Sgiacomo.travaglini@arm.com      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
21513481Sgiacomo.travaglini@arm.com  EXPECT_EQ("1234567", a.Perform(make_tuple(&Concat7)));
21613481Sgiacomo.travaglini@arm.com}
21713481Sgiacomo.travaglini@arm.com
21813481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 8-ary function.
21913481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Function8) {
22013481Sgiacomo.travaglini@arm.com  Action<string(string(*)(const char*, const char*, const char*,
22113481Sgiacomo.travaglini@arm.com                          const char*, const char*, const char*,
22213481Sgiacomo.travaglini@arm.com                          const char*, const char*))> a =
22313481Sgiacomo.travaglini@arm.com      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
22413481Sgiacomo.travaglini@arm.com  EXPECT_EQ("12345678", a.Perform(make_tuple(&Concat8)));
22513481Sgiacomo.travaglini@arm.com}
22613481Sgiacomo.travaglini@arm.com
22713481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 9-ary function.
22813481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Function9) {
22913481Sgiacomo.travaglini@arm.com  Action<string(string(*)(const char*, const char*, const char*,
23013481Sgiacomo.travaglini@arm.com                          const char*, const char*, const char*,
23113481Sgiacomo.travaglini@arm.com                          const char*, const char*, const char*))> a =
23213481Sgiacomo.travaglini@arm.com      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
23313481Sgiacomo.travaglini@arm.com  EXPECT_EQ("123456789", a.Perform(make_tuple(&Concat9)));
23413481Sgiacomo.travaglini@arm.com}
23513481Sgiacomo.travaglini@arm.com
23613481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a 10-ary function.
23713481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, Function10) {
23813481Sgiacomo.travaglini@arm.com  Action<string(string(*)(const char*, const char*, const char*,
23913481Sgiacomo.travaglini@arm.com                          const char*, const char*, const char*,
24013481Sgiacomo.travaglini@arm.com                          const char*, const char*, const char*,
24113481Sgiacomo.travaglini@arm.com                          const char*))> a =
24213481Sgiacomo.travaglini@arm.com      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
24313481Sgiacomo.travaglini@arm.com  EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10)));
24413481Sgiacomo.travaglini@arm.com}
24513481Sgiacomo.travaglini@arm.com
24613481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a function that takes a pointer argument.
24713481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, ByPointerFunction) {
24813481Sgiacomo.travaglini@arm.com  Action<const char*(const char*(*)(const char* input, short n))> a =  // NOLINT
24913481Sgiacomo.travaglini@arm.com      InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));
25013481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
25113481Sgiacomo.travaglini@arm.com}
25213481Sgiacomo.travaglini@arm.com
25313481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a function that takes a const char*
25413481Sgiacomo.travaglini@arm.com// by passing it a C-string literal.
25513481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
25613481Sgiacomo.travaglini@arm.com  Action<const char*(const char*(*)(const char* input, short n))> a =  // NOLINT
25713481Sgiacomo.travaglini@arm.com      InvokeArgument<0>("Hi", Short(1));
25813481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
25913481Sgiacomo.travaglini@arm.com}
26013481Sgiacomo.travaglini@arm.com
26113481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with a function that takes a const reference.
26213481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, ByConstReferenceFunction) {
26313481Sgiacomo.travaglini@arm.com  Action<bool(bool(*function)(const string& s))> a =  // NOLINT
26413481Sgiacomo.travaglini@arm.com      InvokeArgument<0>(string("Hi"));
26513481Sgiacomo.travaglini@arm.com  // When action 'a' is constructed, it makes a copy of the temporary
26613481Sgiacomo.travaglini@arm.com  // string object passed to it, so it's OK to use 'a' later, when the
26713481Sgiacomo.travaglini@arm.com  // temporary object has already died.
26813481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(a.Perform(make_tuple(&ByConstRef)));
26913481Sgiacomo.travaglini@arm.com}
27013481Sgiacomo.travaglini@arm.com
27113481Sgiacomo.travaglini@arm.com// Tests using InvokeArgument with ByRef() and a function that takes a
27213481Sgiacomo.travaglini@arm.com// const reference.
27313481Sgiacomo.travaglini@arm.comTEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
27413481Sgiacomo.travaglini@arm.com  Action<bool(bool(*)(const double& x))> a =  // NOLINT
27513481Sgiacomo.travaglini@arm.com      InvokeArgument<0>(ByRef(g_double));
27613481Sgiacomo.travaglini@arm.com  // The above line calls ByRef() on a const value.
27713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
27813481Sgiacomo.travaglini@arm.com
27913481Sgiacomo.travaglini@arm.com  double x = 0;
28013481Sgiacomo.travaglini@arm.com  a = InvokeArgument<0>(ByRef(x));  // This calls ByRef() on a non-const.
28113481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
28213481Sgiacomo.travaglini@arm.com}
28313481Sgiacomo.travaglini@arm.com
28413481Sgiacomo.travaglini@arm.com// Tests using WithArgs and with an action that takes 1 argument.
28513481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, OneArg) {
28613481Sgiacomo.travaglini@arm.com  Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary));  // NOLINT
28713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
28813481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
28913481Sgiacomo.travaglini@arm.com}
29013481Sgiacomo.travaglini@arm.com
29113481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 2 arguments.
29213481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, TwoArgs) {
29313481Sgiacomo.travaglini@arm.com  Action<const char*(const char* s, double x, short n)> a =
29413481Sgiacomo.travaglini@arm.com      WithArgs<0, 2>(Invoke(Binary));
29513481Sgiacomo.travaglini@arm.com  const char s[] = "Hello";
29613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, Short(2))));
29713481Sgiacomo.travaglini@arm.com}
29813481Sgiacomo.travaglini@arm.com
29913481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 3 arguments.
30013481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, ThreeArgs) {
30113481Sgiacomo.travaglini@arm.com  Action<int(int, double, char, short)> a =  // NOLINT
30213481Sgiacomo.travaglini@arm.com      WithArgs<0, 2, 3>(Invoke(Ternary));
30313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, Char(20), Short(3))));
30413481Sgiacomo.travaglini@arm.com}
30513481Sgiacomo.travaglini@arm.com
30613481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 4 arguments.
30713481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, FourArgs) {
30813481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, double, const char*, const char*)> a =
30913481Sgiacomo.travaglini@arm.com      WithArgs<4, 3, 1, 0>(Invoke(Concat4));
31013481Sgiacomo.travaglini@arm.com  EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5,
31113481Sgiacomo.travaglini@arm.com                                         CharPtr("3"), CharPtr("4"))));
31213481Sgiacomo.travaglini@arm.com}
31313481Sgiacomo.travaglini@arm.com
31413481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 5 arguments.
31513481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, FiveArgs) {
31613481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*,
31713481Sgiacomo.travaglini@arm.com                const char*, const char*)> a =
31813481Sgiacomo.travaglini@arm.com      WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5));
31913481Sgiacomo.travaglini@arm.com  EXPECT_EQ("43210",
32013481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
32113481Sgiacomo.travaglini@arm.com                                 CharPtr("3"), CharPtr("4"))));
32213481Sgiacomo.travaglini@arm.com}
32313481Sgiacomo.travaglini@arm.com
32413481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 6 arguments.
32513481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, SixArgs) {
32613481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*)> a =
32713481Sgiacomo.travaglini@arm.com      WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6));
32813481Sgiacomo.travaglini@arm.com  EXPECT_EQ("012210",
32913481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"))));
33013481Sgiacomo.travaglini@arm.com}
33113481Sgiacomo.travaglini@arm.com
33213481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 7 arguments.
33313481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, SevenArgs) {
33413481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*)> a =
33513481Sgiacomo.travaglini@arm.com      WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7));
33613481Sgiacomo.travaglini@arm.com  EXPECT_EQ("0123210",
33713481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
33813481Sgiacomo.travaglini@arm.com                                 CharPtr("3"))));
33913481Sgiacomo.travaglini@arm.com}
34013481Sgiacomo.travaglini@arm.com
34113481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 8 arguments.
34213481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, EightArgs) {
34313481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*)> a =
34413481Sgiacomo.travaglini@arm.com      WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8));
34513481Sgiacomo.travaglini@arm.com  EXPECT_EQ("01230123",
34613481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
34713481Sgiacomo.travaglini@arm.com                                 CharPtr("3"))));
34813481Sgiacomo.travaglini@arm.com}
34913481Sgiacomo.travaglini@arm.com
35013481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 9 arguments.
35113481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, NineArgs) {
35213481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*)> a =
35313481Sgiacomo.travaglini@arm.com      WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9));
35413481Sgiacomo.travaglini@arm.com  EXPECT_EQ("012312323",
35513481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
35613481Sgiacomo.travaglini@arm.com                                 CharPtr("3"))));
35713481Sgiacomo.travaglini@arm.com}
35813481Sgiacomo.travaglini@arm.com
35913481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that takes 10 arguments.
36013481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, TenArgs) {
36113481Sgiacomo.travaglini@arm.com  Action<string(const char*, const char*, const char*, const char*)> a =
36213481Sgiacomo.travaglini@arm.com      WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10));
36313481Sgiacomo.travaglini@arm.com  EXPECT_EQ("0123210123",
36413481Sgiacomo.travaglini@arm.com            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
36513481Sgiacomo.travaglini@arm.com                                 CharPtr("3"))));
36613481Sgiacomo.travaglini@arm.com}
36713481Sgiacomo.travaglini@arm.com
36813481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that is not Invoke().
36913481Sgiacomo.travaglini@arm.comclass SubstractAction : public ActionInterface<int(int, int)> {  // NOLINT
37013481Sgiacomo.travaglini@arm.com public:
37113481Sgiacomo.travaglini@arm.com  virtual int Perform(const tuple<int, int>& args) {
37213481Sgiacomo.travaglini@arm.com    return get<0>(args) - get<1>(args);
37313481Sgiacomo.travaglini@arm.com  }
37413481Sgiacomo.travaglini@arm.com};
37513481Sgiacomo.travaglini@arm.com
37613481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, NonInvokeAction) {
37713481Sgiacomo.travaglini@arm.com  Action<int(const string&, int, int)> a =  // NOLINT
37813481Sgiacomo.travaglini@arm.com      WithArgs<2, 1>(MakeAction(new SubstractAction));
37913481Sgiacomo.travaglini@arm.com  string s("hello");
38013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(8, a.Perform(tuple<const string&, int, int>(s, 2, 10)));
38113481Sgiacomo.travaglini@arm.com}
38213481Sgiacomo.travaglini@arm.com
38313481Sgiacomo.travaglini@arm.com// Tests using WithArgs to pass all original arguments in the original order.
38413481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, Identity) {
38513481Sgiacomo.travaglini@arm.com  Action<int(int x, char y, short z)> a =  // NOLINT
38613481Sgiacomo.travaglini@arm.com      WithArgs<0, 1, 2>(Invoke(Ternary));
38713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123, a.Perform(make_tuple(100, Char(20), Short(3))));
38813481Sgiacomo.travaglini@arm.com}
38913481Sgiacomo.travaglini@arm.com
39013481Sgiacomo.travaglini@arm.com// Tests using WithArgs with repeated arguments.
39113481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, RepeatedArguments) {
39213481Sgiacomo.travaglini@arm.com  Action<int(bool, int m, int n)> a =  // NOLINT
39313481Sgiacomo.travaglini@arm.com      WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
39413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10)));
39513481Sgiacomo.travaglini@arm.com}
39613481Sgiacomo.travaglini@arm.com
39713481Sgiacomo.travaglini@arm.com// Tests using WithArgs with reversed argument order.
39813481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, ReversedArgumentOrder) {
39913481Sgiacomo.travaglini@arm.com  Action<const char*(short n, const char* input)> a =  // NOLINT
40013481Sgiacomo.travaglini@arm.com      WithArgs<1, 0>(Invoke(Binary));
40113481Sgiacomo.travaglini@arm.com  const char s[] = "Hello";
40213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(s + 2, a.Perform(make_tuple(Short(2), CharPtr(s))));
40313481Sgiacomo.travaglini@arm.com}
40413481Sgiacomo.travaglini@arm.com
40513481Sgiacomo.travaglini@arm.com// Tests using WithArgs with compatible, but not identical, argument types.
40613481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, ArgsOfCompatibleTypes) {
40713481Sgiacomo.travaglini@arm.com  Action<long(short x, char y, double z, char c)> a =  // NOLINT
40813481Sgiacomo.travaglini@arm.com      WithArgs<0, 1, 3>(Invoke(Ternary));
40913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123, a.Perform(make_tuple(Short(100), Char(20), 5.6, Char(3))));
41013481Sgiacomo.travaglini@arm.com}
41113481Sgiacomo.travaglini@arm.com
41213481Sgiacomo.travaglini@arm.com// Tests using WithArgs with an action that returns void.
41313481Sgiacomo.travaglini@arm.comTEST(WithArgsTest, VoidAction) {
41413481Sgiacomo.travaglini@arm.com  Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
41513481Sgiacomo.travaglini@arm.com  g_done = false;
41613481Sgiacomo.travaglini@arm.com  a.Perform(make_tuple(1.5, 'a', 3));
41713481Sgiacomo.travaglini@arm.com  EXPECT_TRUE(g_done);
41813481Sgiacomo.travaglini@arm.com}
41913481Sgiacomo.travaglini@arm.com
42013481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2).
42113481Sgiacomo.travaglini@arm.comTEST(DoAllTest, TwoActions) {
42213481Sgiacomo.travaglini@arm.com  int n = 0;
42313481Sgiacomo.travaglini@arm.com  Action<int(int*)> a = DoAll(SetArgPointee<0>(1),  // NOLINT
42413481Sgiacomo.travaglini@arm.com                              Return(2));
42513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, a.Perform(make_tuple(&n)));
42613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, n);
42713481Sgiacomo.travaglini@arm.com}
42813481Sgiacomo.travaglini@arm.com
42913481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, a3).
43013481Sgiacomo.travaglini@arm.comTEST(DoAllTest, ThreeActions) {
43113481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
43213481Sgiacomo.travaglini@arm.com  Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1),  // NOLINT
43313481Sgiacomo.travaglini@arm.com                                    SetArgPointee<1>(2),
43413481Sgiacomo.travaglini@arm.com                                    Return(3));
43513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, a.Perform(make_tuple(&m, &n)));
43613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
43713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
43813481Sgiacomo.travaglini@arm.com}
43913481Sgiacomo.travaglini@arm.com
44013481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, a3, a4).
44113481Sgiacomo.travaglini@arm.comTEST(DoAllTest, FourActions) {
44213481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
44313481Sgiacomo.travaglini@arm.com  char ch = '\0';
44413481Sgiacomo.travaglini@arm.com  Action<int(int*, int*, char*)> a =  // NOLINT
44513481Sgiacomo.travaglini@arm.com      DoAll(SetArgPointee<0>(1),
44613481Sgiacomo.travaglini@arm.com            SetArgPointee<1>(2),
44713481Sgiacomo.travaglini@arm.com            SetArgPointee<2>('a'),
44813481Sgiacomo.travaglini@arm.com            Return(3));
44913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch)));
45013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
45113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
45213481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', ch);
45313481Sgiacomo.travaglini@arm.com}
45413481Sgiacomo.travaglini@arm.com
45513481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, a3, a4, a5).
45613481Sgiacomo.travaglini@arm.comTEST(DoAllTest, FiveActions) {
45713481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
45813481Sgiacomo.travaglini@arm.com  char a = '\0', b = '\0';
45913481Sgiacomo.travaglini@arm.com  Action<int(int*, int*, char*, char*)> action =  // NOLINT
46013481Sgiacomo.travaglini@arm.com      DoAll(SetArgPointee<0>(1),
46113481Sgiacomo.travaglini@arm.com            SetArgPointee<1>(2),
46213481Sgiacomo.travaglini@arm.com            SetArgPointee<2>('a'),
46313481Sgiacomo.travaglini@arm.com            SetArgPointee<3>('b'),
46413481Sgiacomo.travaglini@arm.com            Return(3));
46513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b)));
46613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
46713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
46813481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', a);
46913481Sgiacomo.travaglini@arm.com  EXPECT_EQ('b', b);
47013481Sgiacomo.travaglini@arm.com}
47113481Sgiacomo.travaglini@arm.com
47213481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, ..., a6).
47313481Sgiacomo.travaglini@arm.comTEST(DoAllTest, SixActions) {
47413481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
47513481Sgiacomo.travaglini@arm.com  char a = '\0', b = '\0', c = '\0';
47613481Sgiacomo.travaglini@arm.com  Action<int(int*, int*, char*, char*, char*)> action =  // NOLINT
47713481Sgiacomo.travaglini@arm.com      DoAll(SetArgPointee<0>(1),
47813481Sgiacomo.travaglini@arm.com            SetArgPointee<1>(2),
47913481Sgiacomo.travaglini@arm.com            SetArgPointee<2>('a'),
48013481Sgiacomo.travaglini@arm.com            SetArgPointee<3>('b'),
48113481Sgiacomo.travaglini@arm.com            SetArgPointee<4>('c'),
48213481Sgiacomo.travaglini@arm.com            Return(3));
48313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c)));
48413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
48513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
48613481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', a);
48713481Sgiacomo.travaglini@arm.com  EXPECT_EQ('b', b);
48813481Sgiacomo.travaglini@arm.com  EXPECT_EQ('c', c);
48913481Sgiacomo.travaglini@arm.com}
49013481Sgiacomo.travaglini@arm.com
49113481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, ..., a7).
49213481Sgiacomo.travaglini@arm.comTEST(DoAllTest, SevenActions) {
49313481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
49413481Sgiacomo.travaglini@arm.com  char a = '\0', b = '\0', c = '\0', d = '\0';
49513481Sgiacomo.travaglini@arm.com  Action<int(int*, int*, char*, char*, char*, char*)> action =  // NOLINT
49613481Sgiacomo.travaglini@arm.com      DoAll(SetArgPointee<0>(1),
49713481Sgiacomo.travaglini@arm.com            SetArgPointee<1>(2),
49813481Sgiacomo.travaglini@arm.com            SetArgPointee<2>('a'),
49913481Sgiacomo.travaglini@arm.com            SetArgPointee<3>('b'),
50013481Sgiacomo.travaglini@arm.com            SetArgPointee<4>('c'),
50113481Sgiacomo.travaglini@arm.com            SetArgPointee<5>('d'),
50213481Sgiacomo.travaglini@arm.com            Return(3));
50313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d)));
50413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
50513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
50613481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', a);
50713481Sgiacomo.travaglini@arm.com  EXPECT_EQ('b', b);
50813481Sgiacomo.travaglini@arm.com  EXPECT_EQ('c', c);
50913481Sgiacomo.travaglini@arm.com  EXPECT_EQ('d', d);
51013481Sgiacomo.travaglini@arm.com}
51113481Sgiacomo.travaglini@arm.com
51213481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, ..., a8).
51313481Sgiacomo.travaglini@arm.comTEST(DoAllTest, EightActions) {
51413481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
51513481Sgiacomo.travaglini@arm.com  char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
51613481Sgiacomo.travaglini@arm.com  Action<int(int*, int*, char*, char*, char*, char*,  // NOLINT
51713481Sgiacomo.travaglini@arm.com             char*)> action =
51813481Sgiacomo.travaglini@arm.com      DoAll(SetArgPointee<0>(1),
51913481Sgiacomo.travaglini@arm.com            SetArgPointee<1>(2),
52013481Sgiacomo.travaglini@arm.com            SetArgPointee<2>('a'),
52113481Sgiacomo.travaglini@arm.com            SetArgPointee<3>('b'),
52213481Sgiacomo.travaglini@arm.com            SetArgPointee<4>('c'),
52313481Sgiacomo.travaglini@arm.com            SetArgPointee<5>('d'),
52413481Sgiacomo.travaglini@arm.com            SetArgPointee<6>('e'),
52513481Sgiacomo.travaglini@arm.com            Return(3));
52613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e)));
52713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
52813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
52913481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', a);
53013481Sgiacomo.travaglini@arm.com  EXPECT_EQ('b', b);
53113481Sgiacomo.travaglini@arm.com  EXPECT_EQ('c', c);
53213481Sgiacomo.travaglini@arm.com  EXPECT_EQ('d', d);
53313481Sgiacomo.travaglini@arm.com  EXPECT_EQ('e', e);
53413481Sgiacomo.travaglini@arm.com}
53513481Sgiacomo.travaglini@arm.com
53613481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, ..., a9).
53713481Sgiacomo.travaglini@arm.comTEST(DoAllTest, NineActions) {
53813481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
53913481Sgiacomo.travaglini@arm.com  char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
54013481Sgiacomo.travaglini@arm.com  Action<int(int*, int*, char*, char*, char*, char*,  // NOLINT
54113481Sgiacomo.travaglini@arm.com             char*, char*)> action =
54213481Sgiacomo.travaglini@arm.com      DoAll(SetArgPointee<0>(1),
54313481Sgiacomo.travaglini@arm.com            SetArgPointee<1>(2),
54413481Sgiacomo.travaglini@arm.com            SetArgPointee<2>('a'),
54513481Sgiacomo.travaglini@arm.com            SetArgPointee<3>('b'),
54613481Sgiacomo.travaglini@arm.com            SetArgPointee<4>('c'),
54713481Sgiacomo.travaglini@arm.com            SetArgPointee<5>('d'),
54813481Sgiacomo.travaglini@arm.com            SetArgPointee<6>('e'),
54913481Sgiacomo.travaglini@arm.com            SetArgPointee<7>('f'),
55013481Sgiacomo.travaglini@arm.com            Return(3));
55113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
55213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
55313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
55413481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', a);
55513481Sgiacomo.travaglini@arm.com  EXPECT_EQ('b', b);
55613481Sgiacomo.travaglini@arm.com  EXPECT_EQ('c', c);
55713481Sgiacomo.travaglini@arm.com  EXPECT_EQ('d', d);
55813481Sgiacomo.travaglini@arm.com  EXPECT_EQ('e', e);
55913481Sgiacomo.travaglini@arm.com  EXPECT_EQ('f', f);
56013481Sgiacomo.travaglini@arm.com}
56113481Sgiacomo.travaglini@arm.com
56213481Sgiacomo.travaglini@arm.com// Tests DoAll(a1, a2, ..., a10).
56313481Sgiacomo.travaglini@arm.comTEST(DoAllTest, TenActions) {
56413481Sgiacomo.travaglini@arm.com  int m = 0, n = 0;
56513481Sgiacomo.travaglini@arm.com  char a = '\0', b = '\0', c = '\0', d = '\0';
56613481Sgiacomo.travaglini@arm.com  char e = '\0', f = '\0', g = '\0';
56713481Sgiacomo.travaglini@arm.com  Action<int(int*, int*, char*, char*, char*, char*,  // NOLINT
56813481Sgiacomo.travaglini@arm.com             char*, char*, char*)> action =
56913481Sgiacomo.travaglini@arm.com      DoAll(SetArgPointee<0>(1),
57013481Sgiacomo.travaglini@arm.com            SetArgPointee<1>(2),
57113481Sgiacomo.travaglini@arm.com            SetArgPointee<2>('a'),
57213481Sgiacomo.travaglini@arm.com            SetArgPointee<3>('b'),
57313481Sgiacomo.travaglini@arm.com            SetArgPointee<4>('c'),
57413481Sgiacomo.travaglini@arm.com            SetArgPointee<5>('d'),
57513481Sgiacomo.travaglini@arm.com            SetArgPointee<6>('e'),
57613481Sgiacomo.travaglini@arm.com            SetArgPointee<7>('f'),
57713481Sgiacomo.travaglini@arm.com            SetArgPointee<8>('g'),
57813481Sgiacomo.travaglini@arm.com            Return(3));
57913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
58013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, m);
58113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(2, n);
58213481Sgiacomo.travaglini@arm.com  EXPECT_EQ('a', a);
58313481Sgiacomo.travaglini@arm.com  EXPECT_EQ('b', b);
58413481Sgiacomo.travaglini@arm.com  EXPECT_EQ('c', c);
58513481Sgiacomo.travaglini@arm.com  EXPECT_EQ('d', d);
58613481Sgiacomo.travaglini@arm.com  EXPECT_EQ('e', e);
58713481Sgiacomo.travaglini@arm.com  EXPECT_EQ('f', f);
58813481Sgiacomo.travaglini@arm.com  EXPECT_EQ('g', g);
58913481Sgiacomo.travaglini@arm.com}
59013481Sgiacomo.travaglini@arm.com
59113481Sgiacomo.travaglini@arm.com// The ACTION*() macros trigger warning C4100 (unreferenced formal
59213481Sgiacomo.travaglini@arm.com// parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in
59313481Sgiacomo.travaglini@arm.com// the macro definition, as the warnings are generated when the macro
59413481Sgiacomo.travaglini@arm.com// is expanded and macro expansion cannot contain #pragma.  Therefore
59513481Sgiacomo.travaglini@arm.com// we suppress them here.
59613481Sgiacomo.travaglini@arm.com#ifdef _MSC_VER
59713481Sgiacomo.travaglini@arm.com# pragma warning(push)
59813481Sgiacomo.travaglini@arm.com# pragma warning(disable:4100)
59913481Sgiacomo.travaglini@arm.com#endif
60013481Sgiacomo.travaglini@arm.com
60113481Sgiacomo.travaglini@arm.com// Tests the ACTION*() macro family.
60213481Sgiacomo.travaglini@arm.com
60313481Sgiacomo.travaglini@arm.com// Tests that ACTION() can define an action that doesn't reference the
60413481Sgiacomo.travaglini@arm.com// mock function arguments.
60513481Sgiacomo.travaglini@arm.comACTION(Return5) { return 5; }
60613481Sgiacomo.travaglini@arm.com
60713481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, WorksWhenNotReferencingArguments) {
60813481Sgiacomo.travaglini@arm.com  Action<double()> a1 = Return5();
60913481Sgiacomo.travaglini@arm.com  EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple()));
61013481Sgiacomo.travaglini@arm.com
61113481Sgiacomo.travaglini@arm.com  Action<int(double, bool)> a2 = Return5();
61213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(5, a2.Perform(make_tuple(1, true)));
61313481Sgiacomo.travaglini@arm.com}
61413481Sgiacomo.travaglini@arm.com
61513481Sgiacomo.travaglini@arm.com// Tests that ACTION() can define an action that returns void.
61613481Sgiacomo.travaglini@arm.comACTION(IncrementArg1) { (*arg1)++; }
61713481Sgiacomo.travaglini@arm.com
61813481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, WorksWhenReturningVoid) {
61913481Sgiacomo.travaglini@arm.com  Action<void(int, int*)> a1 = IncrementArg1();
62013481Sgiacomo.travaglini@arm.com  int n = 0;
62113481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(5, &n));
62213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, n);
62313481Sgiacomo.travaglini@arm.com}
62413481Sgiacomo.travaglini@arm.com
62513481Sgiacomo.travaglini@arm.com// Tests that the body of ACTION() can reference the type of the
62613481Sgiacomo.travaglini@arm.com// argument.
62713481Sgiacomo.travaglini@arm.comACTION(IncrementArg2) {
62813481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<int*, arg2_type>();
62913481Sgiacomo.travaglini@arm.com  arg2_type temp = arg2;
63013481Sgiacomo.travaglini@arm.com  (*temp)++;
63113481Sgiacomo.travaglini@arm.com}
63213481Sgiacomo.travaglini@arm.com
63313481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, CanReferenceArgumentType) {
63413481Sgiacomo.travaglini@arm.com  Action<void(int, bool, int*)> a1 = IncrementArg2();
63513481Sgiacomo.travaglini@arm.com  int n = 0;
63613481Sgiacomo.travaglini@arm.com  a1.Perform(make_tuple(5, false, &n));
63713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, n);
63813481Sgiacomo.travaglini@arm.com}
63913481Sgiacomo.travaglini@arm.com
64013481Sgiacomo.travaglini@arm.com// Tests that the body of ACTION() can reference the argument tuple
64113481Sgiacomo.travaglini@arm.com// via args_type and args.
64213481Sgiacomo.travaglini@arm.comACTION(Sum2) {
64313481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<tuple<int, char, int*>, args_type>();
64413481Sgiacomo.travaglini@arm.com  args_type args_copy = args;
64513481Sgiacomo.travaglini@arm.com  return get<0>(args_copy) + get<1>(args_copy);
64613481Sgiacomo.travaglini@arm.com}
64713481Sgiacomo.travaglini@arm.com
64813481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, CanReferenceArgumentTuple) {
64913481Sgiacomo.travaglini@arm.com  Action<int(int, char, int*)> a1 = Sum2();
65013481Sgiacomo.travaglini@arm.com  int dummy = 0;
65113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(11, a1.Perform(make_tuple(5, Char(6), &dummy)));
65213481Sgiacomo.travaglini@arm.com}
65313481Sgiacomo.travaglini@arm.com
65413481Sgiacomo.travaglini@arm.com// Tests that the body of ACTION() can reference the mock function
65513481Sgiacomo.travaglini@arm.com// type.
65613481Sgiacomo.travaglini@arm.comint Dummy(bool flag) { return flag? 1 : 0; }
65713481Sgiacomo.travaglini@arm.com
65813481Sgiacomo.travaglini@arm.comACTION(InvokeDummy) {
65913481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<int(bool), function_type>();
66013481Sgiacomo.travaglini@arm.com  function_type* fp = &Dummy;
66113481Sgiacomo.travaglini@arm.com  return (*fp)(true);
66213481Sgiacomo.travaglini@arm.com}
66313481Sgiacomo.travaglini@arm.com
66413481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, CanReferenceMockFunctionType) {
66513481Sgiacomo.travaglini@arm.com  Action<int(bool)> a1 = InvokeDummy();
66613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a1.Perform(make_tuple(true)));
66713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a1.Perform(make_tuple(false)));
66813481Sgiacomo.travaglini@arm.com}
66913481Sgiacomo.travaglini@arm.com
67013481Sgiacomo.travaglini@arm.com// Tests that the body of ACTION() can reference the mock function's
67113481Sgiacomo.travaglini@arm.com// return type.
67213481Sgiacomo.travaglini@arm.comACTION(InvokeDummy2) {
67313481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<int, return_type>();
67413481Sgiacomo.travaglini@arm.com  return_type result = Dummy(true);
67513481Sgiacomo.travaglini@arm.com  return result;
67613481Sgiacomo.travaglini@arm.com}
67713481Sgiacomo.travaglini@arm.com
67813481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {
67913481Sgiacomo.travaglini@arm.com  Action<int(bool)> a1 = InvokeDummy2();
68013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a1.Perform(make_tuple(true)));
68113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a1.Perform(make_tuple(false)));
68213481Sgiacomo.travaglini@arm.com}
68313481Sgiacomo.travaglini@arm.com
68413481Sgiacomo.travaglini@arm.com// Tests that ACTION() works for arguments passed by const reference.
68513481Sgiacomo.travaglini@arm.comACTION(ReturnAddrOfConstBoolReferenceArg) {
68613481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<const bool&, arg1_type>();
68713481Sgiacomo.travaglini@arm.com  return &arg1;
68813481Sgiacomo.travaglini@arm.com}
68913481Sgiacomo.travaglini@arm.com
69013481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, WorksForConstReferenceArg) {
69113481Sgiacomo.travaglini@arm.com  Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();
69213481Sgiacomo.travaglini@arm.com  const bool b = false;
69313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(&b, a.Perform(tuple<int, const bool&>(0, b)));
69413481Sgiacomo.travaglini@arm.com}
69513481Sgiacomo.travaglini@arm.com
69613481Sgiacomo.travaglini@arm.com// Tests that ACTION() works for arguments passed by non-const reference.
69713481Sgiacomo.travaglini@arm.comACTION(ReturnAddrOfIntReferenceArg) {
69813481Sgiacomo.travaglini@arm.com  StaticAssertTypeEq<int&, arg0_type>();
69913481Sgiacomo.travaglini@arm.com  return &arg0;
70013481Sgiacomo.travaglini@arm.com}
70113481Sgiacomo.travaglini@arm.com
70213481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, WorksForNonConstReferenceArg) {
70313481Sgiacomo.travaglini@arm.com  Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();
70413481Sgiacomo.travaglini@arm.com  int n = 0;
70513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(&n, a.Perform(tuple<int&, bool, int>(n, true, 1)));
70613481Sgiacomo.travaglini@arm.com}
70713481Sgiacomo.travaglini@arm.com
70813481Sgiacomo.travaglini@arm.com// Tests that ACTION() can be used in a namespace.
70913481Sgiacomo.travaglini@arm.comnamespace action_test {
71013481Sgiacomo.travaglini@arm.comACTION(Sum) { return arg0 + arg1; }
71113481Sgiacomo.travaglini@arm.com}  // namespace action_test
71213481Sgiacomo.travaglini@arm.com
71313481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, WorksInNamespace) {
71413481Sgiacomo.travaglini@arm.com  Action<int(int, int)> a1 = action_test::Sum();
71513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, a1.Perform(make_tuple(1, 2)));
71613481Sgiacomo.travaglini@arm.com}
71713481Sgiacomo.travaglini@arm.com
71813481Sgiacomo.travaglini@arm.com// Tests that the same ACTION definition works for mock functions with
71913481Sgiacomo.travaglini@arm.com// different argument numbers.
72013481Sgiacomo.travaglini@arm.comACTION(PlusTwo) { return arg0 + 2; }
72113481Sgiacomo.travaglini@arm.com
72213481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {
72313481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = PlusTwo();
72413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4, a1.Perform(make_tuple(2)));
72513481Sgiacomo.travaglini@arm.com
72613481Sgiacomo.travaglini@arm.com  Action<double(float, void*)> a2 = PlusTwo();
72713481Sgiacomo.travaglini@arm.com  int dummy;
72813481Sgiacomo.travaglini@arm.com  EXPECT_DOUBLE_EQ(6, a2.Perform(make_tuple(4.0f, &dummy)));
72913481Sgiacomo.travaglini@arm.com}
73013481Sgiacomo.travaglini@arm.com
73113481Sgiacomo.travaglini@arm.com// Tests that ACTION_P can define a parameterized action.
73213481Sgiacomo.travaglini@arm.comACTION_P(Plus, n) { return arg0 + n; }
73313481Sgiacomo.travaglini@arm.com
73413481Sgiacomo.travaglini@arm.comTEST(ActionPMacroTest, DefinesParameterizedAction) {
73513481Sgiacomo.travaglini@arm.com  Action<int(int m, bool t)> a1 = Plus(9);
73613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10, a1.Perform(make_tuple(1, true)));
73713481Sgiacomo.travaglini@arm.com}
73813481Sgiacomo.travaglini@arm.com
73913481Sgiacomo.travaglini@arm.com// Tests that the body of ACTION_P can reference the argument types
74013481Sgiacomo.travaglini@arm.com// and the parameter type.
74113481Sgiacomo.travaglini@arm.comACTION_P(TypedPlus, n) {
74213481Sgiacomo.travaglini@arm.com  arg0_type t1 = arg0;
74313481Sgiacomo.travaglini@arm.com  n_type t2 = n;
74413481Sgiacomo.travaglini@arm.com  return t1 + t2;
74513481Sgiacomo.travaglini@arm.com}
74613481Sgiacomo.travaglini@arm.com
74713481Sgiacomo.travaglini@arm.comTEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {
74813481Sgiacomo.travaglini@arm.com  Action<int(char m, bool t)> a1 = TypedPlus(9);
74913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10, a1.Perform(make_tuple(Char(1), true)));
75013481Sgiacomo.travaglini@arm.com}
75113481Sgiacomo.travaglini@arm.com
75213481Sgiacomo.travaglini@arm.com// Tests that a parameterized action can be used in any mock function
75313481Sgiacomo.travaglini@arm.com// whose type is compatible.
75413481Sgiacomo.travaglini@arm.comTEST(ActionPMacroTest, WorksInCompatibleMockFunction) {
75513481Sgiacomo.travaglini@arm.com  Action<std::string(const std::string& s)> a1 = Plus("tail");
75613481Sgiacomo.travaglini@arm.com  const std::string re = "re";
75713481Sgiacomo.travaglini@arm.com  EXPECT_EQ("retail", a1.Perform(tuple<const std::string&>(re)));
75813481Sgiacomo.travaglini@arm.com}
75913481Sgiacomo.travaglini@arm.com
76013481Sgiacomo.travaglini@arm.com// Tests that we can use ACTION*() to define actions overloaded on the
76113481Sgiacomo.travaglini@arm.com// number of parameters.
76213481Sgiacomo.travaglini@arm.com
76313481Sgiacomo.travaglini@arm.comACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }
76413481Sgiacomo.travaglini@arm.com
76513481Sgiacomo.travaglini@arm.comACTION_P(OverloadedAction, default_value) {
76613481Sgiacomo.travaglini@arm.com  return arg0 ? arg1 : default_value;
76713481Sgiacomo.travaglini@arm.com}
76813481Sgiacomo.travaglini@arm.com
76913481Sgiacomo.travaglini@arm.comACTION_P2(OverloadedAction, true_value, false_value) {
77013481Sgiacomo.travaglini@arm.com  return arg0 ? true_value : false_value;
77113481Sgiacomo.travaglini@arm.com}
77213481Sgiacomo.travaglini@arm.com
77313481Sgiacomo.travaglini@arm.comTEST(ActionMacroTest, CanDefineOverloadedActions) {
77413481Sgiacomo.travaglini@arm.com  typedef Action<const char*(bool, const char*)> MyAction;
77513481Sgiacomo.travaglini@arm.com
77613481Sgiacomo.travaglini@arm.com  const MyAction a1 = OverloadedAction();
77713481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("hello", a1.Perform(make_tuple(false, CharPtr("world"))));
77813481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("world", a1.Perform(make_tuple(true, CharPtr("world"))));
77913481Sgiacomo.travaglini@arm.com
78013481Sgiacomo.travaglini@arm.com  const MyAction a2 = OverloadedAction("hi");
78113481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("hi", a2.Perform(make_tuple(false, CharPtr("world"))));
78213481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("world", a2.Perform(make_tuple(true, CharPtr("world"))));
78313481Sgiacomo.travaglini@arm.com
78413481Sgiacomo.travaglini@arm.com  const MyAction a3 = OverloadedAction("hi", "you");
78513481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("hi", a3.Perform(make_tuple(true, CharPtr("world"))));
78613481Sgiacomo.travaglini@arm.com  EXPECT_STREQ("you", a3.Perform(make_tuple(false, CharPtr("world"))));
78713481Sgiacomo.travaglini@arm.com}
78813481Sgiacomo.travaglini@arm.com
78913481Sgiacomo.travaglini@arm.com// Tests ACTION_Pn where n >= 3.
79013481Sgiacomo.travaglini@arm.com
79113481Sgiacomo.travaglini@arm.comACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }
79213481Sgiacomo.travaglini@arm.com
79313481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor3Parameters) {
79413481Sgiacomo.travaglini@arm.com  Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);
79513481Sgiacomo.travaglini@arm.com  EXPECT_DOUBLE_EQ(3123.4, a1.Perform(make_tuple(3000, true)));
79613481Sgiacomo.travaglini@arm.com
79713481Sgiacomo.travaglini@arm.com  Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");
79813481Sgiacomo.travaglini@arm.com  const std::string re = "re";
79913481Sgiacomo.travaglini@arm.com  EXPECT_EQ("retail->", a2.Perform(tuple<const std::string&>(re)));
80013481Sgiacomo.travaglini@arm.com}
80113481Sgiacomo.travaglini@arm.com
80213481Sgiacomo.travaglini@arm.comACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }
80313481Sgiacomo.travaglini@arm.com
80413481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor4Parameters) {
80513481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = Plus(1, 2, 3, 4);
80613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(make_tuple(10)));
80713481Sgiacomo.travaglini@arm.com}
80813481Sgiacomo.travaglini@arm.com
80913481Sgiacomo.travaglini@arm.comACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }
81013481Sgiacomo.travaglini@arm.com
81113481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor5Parameters) {
81213481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);
81313481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(make_tuple(10)));
81413481Sgiacomo.travaglini@arm.com}
81513481Sgiacomo.travaglini@arm.com
81613481Sgiacomo.travaglini@arm.comACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {
81713481Sgiacomo.travaglini@arm.com  return arg0 + p0 + p1 + p2 + p3 + p4 + p5;
81813481Sgiacomo.travaglini@arm.com}
81913481Sgiacomo.travaglini@arm.com
82013481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor6Parameters) {
82113481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);
82213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(make_tuple(10)));
82313481Sgiacomo.travaglini@arm.com}
82413481Sgiacomo.travaglini@arm.com
82513481Sgiacomo.travaglini@arm.comACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {
82613481Sgiacomo.travaglini@arm.com  return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;
82713481Sgiacomo.travaglini@arm.com}
82813481Sgiacomo.travaglini@arm.com
82913481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor7Parameters) {
83013481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);
83113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(make_tuple(10)));
83213481Sgiacomo.travaglini@arm.com}
83313481Sgiacomo.travaglini@arm.com
83413481Sgiacomo.travaglini@arm.comACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {
83513481Sgiacomo.travaglini@arm.com  return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
83613481Sgiacomo.travaglini@arm.com}
83713481Sgiacomo.travaglini@arm.com
83813481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor8Parameters) {
83913481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);
84013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, a1.Perform(make_tuple(10)));
84113481Sgiacomo.travaglini@arm.com}
84213481Sgiacomo.travaglini@arm.com
84313481Sgiacomo.travaglini@arm.comACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {
84413481Sgiacomo.travaglini@arm.com  return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;
84513481Sgiacomo.travaglini@arm.com}
84613481Sgiacomo.travaglini@arm.com
84713481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor9Parameters) {
84813481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);
84913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, a1.Perform(make_tuple(10)));
85013481Sgiacomo.travaglini@arm.com}
85113481Sgiacomo.travaglini@arm.com
85213481Sgiacomo.travaglini@arm.comACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {
85313481Sgiacomo.travaglini@arm.com  arg0_type t0 = arg0;
85413481Sgiacomo.travaglini@arm.com  last_param_type t9 = last_param;
85513481Sgiacomo.travaglini@arm.com  return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;
85613481Sgiacomo.travaglini@arm.com}
85713481Sgiacomo.travaglini@arm.com
85813481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, WorksFor10Parameters) {
85913481Sgiacomo.travaglini@arm.com  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
86013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,
86113481Sgiacomo.travaglini@arm.com            a1.Perform(make_tuple(10)));
86213481Sgiacomo.travaglini@arm.com}
86313481Sgiacomo.travaglini@arm.com
86413481Sgiacomo.travaglini@arm.com// Tests that the action body can promote the parameter types.
86513481Sgiacomo.travaglini@arm.com
86613481Sgiacomo.travaglini@arm.comACTION_P2(PadArgument, prefix, suffix) {
86713481Sgiacomo.travaglini@arm.com  // The following lines promote the two parameters to desired types.
86813481Sgiacomo.travaglini@arm.com  std::string prefix_str(prefix);
86913481Sgiacomo.travaglini@arm.com  char suffix_char = static_cast<char>(suffix);
87013481Sgiacomo.travaglini@arm.com  return prefix_str + arg0 + suffix_char;
87113481Sgiacomo.travaglini@arm.com}
87213481Sgiacomo.travaglini@arm.com
87313481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, SimpleTypePromotion) {
87413481Sgiacomo.travaglini@arm.com  Action<std::string(const char*)> no_promo =
87513481Sgiacomo.travaglini@arm.com      PadArgument(std::string("foo"), 'r');
87613481Sgiacomo.travaglini@arm.com  Action<std::string(const char*)> promo =
87713481Sgiacomo.travaglini@arm.com      PadArgument("foo", static_cast<int>('r'));
87813481Sgiacomo.travaglini@arm.com  EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba"))));
87913481Sgiacomo.travaglini@arm.com  EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba"))));
88013481Sgiacomo.travaglini@arm.com}
88113481Sgiacomo.travaglini@arm.com
88213481Sgiacomo.travaglini@arm.com// Tests that we can partially restrict parameter types using a
88313481Sgiacomo.travaglini@arm.com// straight-forward pattern.
88413481Sgiacomo.travaglini@arm.com
88513481Sgiacomo.travaglini@arm.com// Defines a generic action that doesn't restrict the types of its
88613481Sgiacomo.travaglini@arm.com// parameters.
88713481Sgiacomo.travaglini@arm.comACTION_P3(ConcatImpl, a, b, c) {
88813481Sgiacomo.travaglini@arm.com  std::stringstream ss;
88913481Sgiacomo.travaglini@arm.com  ss << a << b << c;
89013481Sgiacomo.travaglini@arm.com  return ss.str();
89113481Sgiacomo.travaglini@arm.com}
89213481Sgiacomo.travaglini@arm.com
89313481Sgiacomo.travaglini@arm.com// Next, we try to restrict that either the first parameter is a
89413481Sgiacomo.travaglini@arm.com// string, or the second parameter is an int.
89513481Sgiacomo.travaglini@arm.com
89613481Sgiacomo.travaglini@arm.com// Defines a partially specialized wrapper that restricts the first
89713481Sgiacomo.travaglini@arm.com// parameter to std::string.
89813481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2>
89913481Sgiacomo.travaglini@arm.com// ConcatImplActionP3 is the class template ACTION_P3 uses to
90013481Sgiacomo.travaglini@arm.com// implement ConcatImpl.  We shouldn't change the name as this
90113481Sgiacomo.travaglini@arm.com// pattern requires the user to use it directly.
90213481Sgiacomo.travaglini@arm.comConcatImplActionP3<std::string, T1, T2>
90313481Sgiacomo.travaglini@arm.comConcat(const std::string& a, T1 b, T2 c) {
90413481Sgiacomo.travaglini@arm.com  GTEST_INTENTIONAL_CONST_COND_PUSH_()
90513481Sgiacomo.travaglini@arm.com  if (true) {
90613481Sgiacomo.travaglini@arm.com  GTEST_INTENTIONAL_CONST_COND_POP_()
90713481Sgiacomo.travaglini@arm.com    // This branch verifies that ConcatImpl() can be invoked without
90813481Sgiacomo.travaglini@arm.com    // explicit template arguments.
90913481Sgiacomo.travaglini@arm.com    return ConcatImpl(a, b, c);
91013481Sgiacomo.travaglini@arm.com  } else {
91113481Sgiacomo.travaglini@arm.com    // This branch verifies that ConcatImpl() can also be invoked with
91213481Sgiacomo.travaglini@arm.com    // explicit template arguments.  It doesn't really need to be
91313481Sgiacomo.travaglini@arm.com    // executed as this is a compile-time verification.
91413481Sgiacomo.travaglini@arm.com    return ConcatImpl<std::string, T1, T2>(a, b, c);
91513481Sgiacomo.travaglini@arm.com  }
91613481Sgiacomo.travaglini@arm.com}
91713481Sgiacomo.travaglini@arm.com
91813481Sgiacomo.travaglini@arm.com// Defines another partially specialized wrapper that restricts the
91913481Sgiacomo.travaglini@arm.com// second parameter to int.
92013481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2>
92113481Sgiacomo.travaglini@arm.comConcatImplActionP3<T1, int, T2>
92213481Sgiacomo.travaglini@arm.comConcat(T1 a, int b, T2 c) {
92313481Sgiacomo.travaglini@arm.com  return ConcatImpl(a, b, c);
92413481Sgiacomo.travaglini@arm.com}
92513481Sgiacomo.travaglini@arm.com
92613481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {
92713481Sgiacomo.travaglini@arm.com  Action<const std::string()> a1 = Concat("Hello", "1", 2);
92813481Sgiacomo.travaglini@arm.com  EXPECT_EQ("Hello12", a1.Perform(make_tuple()));
92913481Sgiacomo.travaglini@arm.com
93013481Sgiacomo.travaglini@arm.com  a1 = Concat(1, 2, 3);
93113481Sgiacomo.travaglini@arm.com  EXPECT_EQ("123", a1.Perform(make_tuple()));
93213481Sgiacomo.travaglini@arm.com}
93313481Sgiacomo.travaglini@arm.com
93413481Sgiacomo.travaglini@arm.com// Verifies the type of an ACTION*.
93513481Sgiacomo.travaglini@arm.com
93613481Sgiacomo.travaglini@arm.comACTION(DoFoo) {}
93713481Sgiacomo.travaglini@arm.comACTION_P(DoFoo, p) {}
93813481Sgiacomo.travaglini@arm.comACTION_P2(DoFoo, p0, p1) {}
93913481Sgiacomo.travaglini@arm.com
94013481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, TypesAreCorrect) {
94113481Sgiacomo.travaglini@arm.com  // DoFoo() must be assignable to a DoFooAction variable.
94213481Sgiacomo.travaglini@arm.com  DoFooAction a0 = DoFoo();
94313481Sgiacomo.travaglini@arm.com
94413481Sgiacomo.travaglini@arm.com  // DoFoo(1) must be assignable to a DoFooActionP variable.
94513481Sgiacomo.travaglini@arm.com  DoFooActionP<int> a1 = DoFoo(1);
94613481Sgiacomo.travaglini@arm.com
94713481Sgiacomo.travaglini@arm.com  // DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk
94813481Sgiacomo.travaglini@arm.com  // variable, and so on.
94913481Sgiacomo.travaglini@arm.com  DoFooActionP2<int, char> a2 = DoFoo(1, '2');
95013481Sgiacomo.travaglini@arm.com  PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');
95113481Sgiacomo.travaglini@arm.com  PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');
95213481Sgiacomo.travaglini@arm.com  PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');
95313481Sgiacomo.travaglini@arm.com  PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');
95413481Sgiacomo.travaglini@arm.com  PlusActionP7<int, int, int, int, int, int, char> a7 =
95513481Sgiacomo.travaglini@arm.com      Plus(1, 2, 3, 4, 5, 6, '7');
95613481Sgiacomo.travaglini@arm.com  PlusActionP8<int, int, int, int, int, int, int, char> a8 =
95713481Sgiacomo.travaglini@arm.com      Plus(1, 2, 3, 4, 5, 6, 7, '8');
95813481Sgiacomo.travaglini@arm.com  PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =
95913481Sgiacomo.travaglini@arm.com      Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');
96013481Sgiacomo.travaglini@arm.com  PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =
96113481Sgiacomo.travaglini@arm.com      Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
96213481Sgiacomo.travaglini@arm.com
96313481Sgiacomo.travaglini@arm.com  // Avoid "unused variable" warnings.
96413481Sgiacomo.travaglini@arm.com  (void)a0;
96513481Sgiacomo.travaglini@arm.com  (void)a1;
96613481Sgiacomo.travaglini@arm.com  (void)a2;
96713481Sgiacomo.travaglini@arm.com  (void)a3;
96813481Sgiacomo.travaglini@arm.com  (void)a4;
96913481Sgiacomo.travaglini@arm.com  (void)a5;
97013481Sgiacomo.travaglini@arm.com  (void)a6;
97113481Sgiacomo.travaglini@arm.com  (void)a7;
97213481Sgiacomo.travaglini@arm.com  (void)a8;
97313481Sgiacomo.travaglini@arm.com  (void)a9;
97413481Sgiacomo.travaglini@arm.com  (void)a10;
97513481Sgiacomo.travaglini@arm.com}
97613481Sgiacomo.travaglini@arm.com
97713481Sgiacomo.travaglini@arm.com// Tests that an ACTION_P*() action can be explicitly instantiated
97813481Sgiacomo.travaglini@arm.com// with reference-typed parameters.
97913481Sgiacomo.travaglini@arm.com
98013481Sgiacomo.travaglini@arm.comACTION_P(Plus1, x) { return x; }
98113481Sgiacomo.travaglini@arm.comACTION_P2(Plus2, x, y) { return x + y; }
98213481Sgiacomo.travaglini@arm.comACTION_P3(Plus3, x, y, z) { return x + y + z; }
98313481Sgiacomo.travaglini@arm.comACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
98413481Sgiacomo.travaglini@arm.com  return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
98513481Sgiacomo.travaglini@arm.com}
98613481Sgiacomo.travaglini@arm.com
98713481Sgiacomo.travaglini@arm.comTEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
98813481Sgiacomo.travaglini@arm.com  int x = 1, y = 2, z = 3;
98913481Sgiacomo.travaglini@arm.com  const tuple<> empty = make_tuple();
99013481Sgiacomo.travaglini@arm.com
99113481Sgiacomo.travaglini@arm.com  Action<int()> a = Plus1<int&>(x);
99213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a.Perform(empty));
99313481Sgiacomo.travaglini@arm.com
99413481Sgiacomo.travaglini@arm.com  a = Plus2<const int&, int&>(x, y);
99513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, a.Perform(empty));
99613481Sgiacomo.travaglini@arm.com
99713481Sgiacomo.travaglini@arm.com  a = Plus3<int&, const int&, int&>(x, y, z);
99813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(6, a.Perform(empty));
99913481Sgiacomo.travaglini@arm.com
100013481Sgiacomo.travaglini@arm.com  int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
100113481Sgiacomo.travaglini@arm.com  a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,
100213481Sgiacomo.travaglini@arm.com      int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7],
100313481Sgiacomo.travaglini@arm.com                              n[8], n[9]);
100413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(55, a.Perform(empty));
100513481Sgiacomo.travaglini@arm.com}
100613481Sgiacomo.travaglini@arm.com
100713481Sgiacomo.travaglini@arm.comclass NullaryConstructorClass {
100813481Sgiacomo.travaglini@arm.com public:
100913481Sgiacomo.travaglini@arm.com  NullaryConstructorClass() : value_(123) {}
101013481Sgiacomo.travaglini@arm.com  int value_;
101113481Sgiacomo.travaglini@arm.com};
101213481Sgiacomo.travaglini@arm.com
101313481Sgiacomo.travaglini@arm.com// Tests using ReturnNew() with a nullary constructor.
101413481Sgiacomo.travaglini@arm.comTEST(ReturnNewTest, NoArgs) {
101513481Sgiacomo.travaglini@arm.com  Action<NullaryConstructorClass*()> a = ReturnNew<NullaryConstructorClass>();
101613481Sgiacomo.travaglini@arm.com  NullaryConstructorClass* c = a.Perform(make_tuple());
101713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(123, c->value_);
101813481Sgiacomo.travaglini@arm.com  delete c;
101913481Sgiacomo.travaglini@arm.com}
102013481Sgiacomo.travaglini@arm.com
102113481Sgiacomo.travaglini@arm.comclass UnaryConstructorClass {
102213481Sgiacomo.travaglini@arm.com public:
102313481Sgiacomo.travaglini@arm.com  explicit UnaryConstructorClass(int value) : value_(value) {}
102413481Sgiacomo.travaglini@arm.com  int value_;
102513481Sgiacomo.travaglini@arm.com};
102613481Sgiacomo.travaglini@arm.com
102713481Sgiacomo.travaglini@arm.com// Tests using ReturnNew() with a unary constructor.
102813481Sgiacomo.travaglini@arm.comTEST(ReturnNewTest, Unary) {
102913481Sgiacomo.travaglini@arm.com  Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000);
103013481Sgiacomo.travaglini@arm.com  UnaryConstructorClass* c = a.Perform(make_tuple());
103113481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4000, c->value_);
103213481Sgiacomo.travaglini@arm.com  delete c;
103313481Sgiacomo.travaglini@arm.com}
103413481Sgiacomo.travaglini@arm.com
103513481Sgiacomo.travaglini@arm.comTEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) {
103613481Sgiacomo.travaglini@arm.com  Action<UnaryConstructorClass*(bool, int)> a =
103713481Sgiacomo.travaglini@arm.com      ReturnNew<UnaryConstructorClass>(4000);
103813481Sgiacomo.travaglini@arm.com  UnaryConstructorClass* c = a.Perform(make_tuple(false, 5));
103913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4000, c->value_);
104013481Sgiacomo.travaglini@arm.com  delete c;
104113481Sgiacomo.travaglini@arm.com}
104213481Sgiacomo.travaglini@arm.com
104313481Sgiacomo.travaglini@arm.comTEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) {
104413481Sgiacomo.travaglini@arm.com  Action<const UnaryConstructorClass*()> a =
104513481Sgiacomo.travaglini@arm.com      ReturnNew<UnaryConstructorClass>(4000);
104613481Sgiacomo.travaglini@arm.com  const UnaryConstructorClass* c = a.Perform(make_tuple());
104713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(4000, c->value_);
104813481Sgiacomo.travaglini@arm.com  delete c;
104913481Sgiacomo.travaglini@arm.com}
105013481Sgiacomo.travaglini@arm.com
105113481Sgiacomo.travaglini@arm.comclass TenArgConstructorClass {
105213481Sgiacomo.travaglini@arm.com public:
105313481Sgiacomo.travaglini@arm.com  TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5,
105413481Sgiacomo.travaglini@arm.com                         int a6, int a7, int a8, int a9, int a10)
105513481Sgiacomo.travaglini@arm.com    : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {
105613481Sgiacomo.travaglini@arm.com  }
105713481Sgiacomo.travaglini@arm.com  int value_;
105813481Sgiacomo.travaglini@arm.com};
105913481Sgiacomo.travaglini@arm.com
106013481Sgiacomo.travaglini@arm.com// Tests using ReturnNew() with a 10-argument constructor.
106113481Sgiacomo.travaglini@arm.comTEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
106213481Sgiacomo.travaglini@arm.com  Action<TenArgConstructorClass*()> a =
106313481Sgiacomo.travaglini@arm.com      ReturnNew<TenArgConstructorClass>(1000000000, 200000000, 30000000,
106413481Sgiacomo.travaglini@arm.com                                        4000000, 500000, 60000,
106513481Sgiacomo.travaglini@arm.com                                        7000, 800, 90, 0);
106613481Sgiacomo.travaglini@arm.com  TenArgConstructorClass* c = a.Perform(make_tuple());
106713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1234567890, c->value_);
106813481Sgiacomo.travaglini@arm.com  delete c;
106913481Sgiacomo.travaglini@arm.com}
107013481Sgiacomo.travaglini@arm.com
107113481Sgiacomo.travaglini@arm.com// Tests that ACTION_TEMPLATE works when there is no value parameter.
107213481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(CreateNew,
107313481Sgiacomo.travaglini@arm.com                HAS_1_TEMPLATE_PARAMS(typename, T),
107413481Sgiacomo.travaglini@arm.com                AND_0_VALUE_PARAMS()) {
107513481Sgiacomo.travaglini@arm.com  return new T;
107613481Sgiacomo.travaglini@arm.com}
107713481Sgiacomo.travaglini@arm.com
107813481Sgiacomo.travaglini@arm.comTEST(ActionTemplateTest, WorksWithoutValueParam) {
107913481Sgiacomo.travaglini@arm.com  const Action<int*()> a = CreateNew<int>();
108013481Sgiacomo.travaglini@arm.com  int* p = a.Perform(make_tuple());
108113481Sgiacomo.travaglini@arm.com  delete p;
108213481Sgiacomo.travaglini@arm.com}
108313481Sgiacomo.travaglini@arm.com
108413481Sgiacomo.travaglini@arm.com// Tests that ACTION_TEMPLATE works when there are value parameters.
108513481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(CreateNew,
108613481Sgiacomo.travaglini@arm.com                HAS_1_TEMPLATE_PARAMS(typename, T),
108713481Sgiacomo.travaglini@arm.com                AND_1_VALUE_PARAMS(a0)) {
108813481Sgiacomo.travaglini@arm.com  return new T(a0);
108913481Sgiacomo.travaglini@arm.com}
109013481Sgiacomo.travaglini@arm.com
109113481Sgiacomo.travaglini@arm.comTEST(ActionTemplateTest, WorksWithValueParams) {
109213481Sgiacomo.travaglini@arm.com  const Action<int*()> a = CreateNew<int>(42);
109313481Sgiacomo.travaglini@arm.com  int* p = a.Perform(make_tuple());
109413481Sgiacomo.travaglini@arm.com  EXPECT_EQ(42, *p);
109513481Sgiacomo.travaglini@arm.com  delete p;
109613481Sgiacomo.travaglini@arm.com}
109713481Sgiacomo.travaglini@arm.com
109813481Sgiacomo.travaglini@arm.com// Tests that ACTION_TEMPLATE works for integral template parameters.
109913481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(MyDeleteArg,
110013481Sgiacomo.travaglini@arm.com                HAS_1_TEMPLATE_PARAMS(int, k),
110113481Sgiacomo.travaglini@arm.com                AND_0_VALUE_PARAMS()) {
110213481Sgiacomo.travaglini@arm.com  delete get<k>(args);
110313481Sgiacomo.travaglini@arm.com}
110413481Sgiacomo.travaglini@arm.com
110513481Sgiacomo.travaglini@arm.com// Resets a bool variable in the destructor.
110613481Sgiacomo.travaglini@arm.comclass BoolResetter {
110713481Sgiacomo.travaglini@arm.com public:
110813481Sgiacomo.travaglini@arm.com  explicit BoolResetter(bool* value) : value_(value) {}
110913481Sgiacomo.travaglini@arm.com  ~BoolResetter() { *value_ = false; }
111013481Sgiacomo.travaglini@arm.com private:
111113481Sgiacomo.travaglini@arm.com  bool* value_;
111213481Sgiacomo.travaglini@arm.com};
111313481Sgiacomo.travaglini@arm.com
111413481Sgiacomo.travaglini@arm.comTEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
111513481Sgiacomo.travaglini@arm.com  const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
111613481Sgiacomo.travaglini@arm.com  int n = 0;
111713481Sgiacomo.travaglini@arm.com  bool b = true;
111813481Sgiacomo.travaglini@arm.com  BoolResetter* resetter = new BoolResetter(&b);
111913481Sgiacomo.travaglini@arm.com  a.Perform(make_tuple(&n, resetter));
112013481Sgiacomo.travaglini@arm.com  EXPECT_FALSE(b);  // Verifies that resetter is deleted.
112113481Sgiacomo.travaglini@arm.com}
112213481Sgiacomo.travaglini@arm.com
112313481Sgiacomo.travaglini@arm.com// Tests that ACTION_TEMPLATES works for template template parameters.
112413481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(ReturnSmartPointer,
112513481Sgiacomo.travaglini@arm.com                HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,
112613481Sgiacomo.travaglini@arm.com                                      Pointer),
112713481Sgiacomo.travaglini@arm.com                AND_1_VALUE_PARAMS(pointee)) {
112813481Sgiacomo.travaglini@arm.com  return Pointer<pointee_type>(new pointee_type(pointee));
112913481Sgiacomo.travaglini@arm.com}
113013481Sgiacomo.travaglini@arm.com
113113481Sgiacomo.travaglini@arm.comTEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {
113213481Sgiacomo.travaglini@arm.com  using ::testing::internal::linked_ptr;
113313481Sgiacomo.travaglini@arm.com  const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42);
113413481Sgiacomo.travaglini@arm.com  linked_ptr<int> p = a.Perform(make_tuple());
113513481Sgiacomo.travaglini@arm.com  EXPECT_EQ(42, *p);
113613481Sgiacomo.travaglini@arm.com}
113713481Sgiacomo.travaglini@arm.com
113813481Sgiacomo.travaglini@arm.com// Tests that ACTION_TEMPLATE works for 10 template parameters.
113913481Sgiacomo.travaglini@arm.comtemplate <typename T1, typename T2, typename T3, int k4, bool k5,
114013481Sgiacomo.travaglini@arm.com          unsigned int k6, typename T7, typename T8, typename T9>
114113481Sgiacomo.travaglini@arm.comstruct GiantTemplate {
114213481Sgiacomo.travaglini@arm.com public:
114313481Sgiacomo.travaglini@arm.com  explicit GiantTemplate(int a_value) : value(a_value) {}
114413481Sgiacomo.travaglini@arm.com  int value;
114513481Sgiacomo.travaglini@arm.com};
114613481Sgiacomo.travaglini@arm.com
114713481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(ReturnGiant,
114813481Sgiacomo.travaglini@arm.com                HAS_10_TEMPLATE_PARAMS(
114913481Sgiacomo.travaglini@arm.com                    typename, T1,
115013481Sgiacomo.travaglini@arm.com                    typename, T2,
115113481Sgiacomo.travaglini@arm.com                    typename, T3,
115213481Sgiacomo.travaglini@arm.com                    int, k4,
115313481Sgiacomo.travaglini@arm.com                    bool, k5,
115413481Sgiacomo.travaglini@arm.com                    unsigned int, k6,
115513481Sgiacomo.travaglini@arm.com                    class, T7,
115613481Sgiacomo.travaglini@arm.com                    class, T8,
115713481Sgiacomo.travaglini@arm.com                    class, T9,
115813481Sgiacomo.travaglini@arm.com                    template <typename T> class, T10),
115913481Sgiacomo.travaglini@arm.com                AND_1_VALUE_PARAMS(value)) {
116013481Sgiacomo.travaglini@arm.com  return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);
116113481Sgiacomo.travaglini@arm.com}
116213481Sgiacomo.travaglini@arm.com
116313481Sgiacomo.travaglini@arm.comTEST(ActionTemplateTest, WorksFor10TemplateParameters) {
116413481Sgiacomo.travaglini@arm.com  using ::testing::internal::linked_ptr;
116513481Sgiacomo.travaglini@arm.com  typedef GiantTemplate<linked_ptr<int>, bool, double, 5,
116613481Sgiacomo.travaglini@arm.com      true, 6, char, unsigned, int> Giant;
116713481Sgiacomo.travaglini@arm.com  const Action<Giant()> a = ReturnGiant<
116813481Sgiacomo.travaglini@arm.com      int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42);
116913481Sgiacomo.travaglini@arm.com  Giant giant = a.Perform(make_tuple());
117013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(42, giant.value);
117113481Sgiacomo.travaglini@arm.com}
117213481Sgiacomo.travaglini@arm.com
117313481Sgiacomo.travaglini@arm.com// Tests that ACTION_TEMPLATE works for 10 value parameters.
117413481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(ReturnSum,
117513481Sgiacomo.travaglini@arm.com                HAS_1_TEMPLATE_PARAMS(typename, Number),
117613481Sgiacomo.travaglini@arm.com                AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {
117713481Sgiacomo.travaglini@arm.com  return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
117813481Sgiacomo.travaglini@arm.com}
117913481Sgiacomo.travaglini@arm.com
118013481Sgiacomo.travaglini@arm.comTEST(ActionTemplateTest, WorksFor10ValueParameters) {
118113481Sgiacomo.travaglini@arm.com  const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
118213481Sgiacomo.travaglini@arm.com  EXPECT_EQ(55, a.Perform(make_tuple()));
118313481Sgiacomo.travaglini@arm.com}
118413481Sgiacomo.travaglini@arm.com
118513481Sgiacomo.travaglini@arm.com// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded
118613481Sgiacomo.travaglini@arm.com// on the number of value parameters.
118713481Sgiacomo.travaglini@arm.com
118813481Sgiacomo.travaglini@arm.comACTION(ReturnSum) { return 0; }
118913481Sgiacomo.travaglini@arm.com
119013481Sgiacomo.travaglini@arm.comACTION_P(ReturnSum, x) { return x; }
119113481Sgiacomo.travaglini@arm.com
119213481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(ReturnSum,
119313481Sgiacomo.travaglini@arm.com                HAS_1_TEMPLATE_PARAMS(typename, Number),
119413481Sgiacomo.travaglini@arm.com                AND_2_VALUE_PARAMS(v1, v2)) {
119513481Sgiacomo.travaglini@arm.com  return static_cast<Number>(v1) + v2;
119613481Sgiacomo.travaglini@arm.com}
119713481Sgiacomo.travaglini@arm.com
119813481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(ReturnSum,
119913481Sgiacomo.travaglini@arm.com                HAS_1_TEMPLATE_PARAMS(typename, Number),
120013481Sgiacomo.travaglini@arm.com                AND_3_VALUE_PARAMS(v1, v2, v3)) {
120113481Sgiacomo.travaglini@arm.com  return static_cast<Number>(v1) + v2 + v3;
120213481Sgiacomo.travaglini@arm.com}
120313481Sgiacomo.travaglini@arm.com
120413481Sgiacomo.travaglini@arm.comACTION_TEMPLATE(ReturnSum,
120513481Sgiacomo.travaglini@arm.com                HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),
120613481Sgiacomo.travaglini@arm.com                AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {
120713481Sgiacomo.travaglini@arm.com  return static_cast<Number>(v1) + v2 + v3 + v4 + k;
120813481Sgiacomo.travaglini@arm.com}
120913481Sgiacomo.travaglini@arm.com
121013481Sgiacomo.travaglini@arm.comTEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
121113481Sgiacomo.travaglini@arm.com  const Action<int()> a0 = ReturnSum();
121213481Sgiacomo.travaglini@arm.com  const Action<int()> a1 = ReturnSum(1);
121313481Sgiacomo.travaglini@arm.com  const Action<int()> a2 = ReturnSum<int>(1, 2);
121413481Sgiacomo.travaglini@arm.com  const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
121513481Sgiacomo.travaglini@arm.com  const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
121613481Sgiacomo.travaglini@arm.com  EXPECT_EQ(0, a0.Perform(make_tuple()));
121713481Sgiacomo.travaglini@arm.com  EXPECT_EQ(1, a1.Perform(make_tuple()));
121813481Sgiacomo.travaglini@arm.com  EXPECT_EQ(3, a2.Perform(make_tuple()));
121913481Sgiacomo.travaglini@arm.com  EXPECT_EQ(6, a3.Perform(make_tuple()));
122013481Sgiacomo.travaglini@arm.com  EXPECT_EQ(12345, a4.Perform(make_tuple()));
122113481Sgiacomo.travaglini@arm.com}
122213481Sgiacomo.travaglini@arm.com
122313481Sgiacomo.travaglini@arm.com#ifdef _MSC_VER
122413481Sgiacomo.travaglini@arm.com# pragma warning(pop)
122513481Sgiacomo.travaglini@arm.com#endif
122613481Sgiacomo.travaglini@arm.com
122713481Sgiacomo.travaglini@arm.com}  // namespace gmock_generated_actions_test
122813481Sgiacomo.travaglini@arm.com}  // namespace testing
1229