1f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Copyright 2007, Google Inc.
2f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// All rights reserved.
3f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
4f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Redistribution and use in source and binary forms, with or without
5f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// modification, are permitted provided that the following conditions are
6f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// met:
7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//     * Redistributions of source code must retain the above copyright
9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// notice, this list of conditions and the following disclaimer.
10f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//     * Redistributions in binary form must reproduce the above
11f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// copyright notice, this list of conditions and the following disclaimer
12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// in the documentation and/or other materials provided with the
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// distribution.
14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//     * Neither the name of Google Inc. nor the names of its
15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// contributors may be used to endorse or promote products derived from
16f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// this software without specific prior written permission.
17f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
18f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Author: wan@google.com (Zhanyong Wan)
31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
32f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Google Mock - a framework for writing C++ mock classes.
33f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//
34f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// This file tests the built-in actions generated by a script.
35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gmock/gmock-generated-actions.h"
37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <functional>
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <sstream>
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <string>
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gmock/gmock.h"
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "gtest/gtest.h"
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace testing {
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace gmock_generated_actions_test {
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing ::std::plus;
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing ::std::string;
49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::get;
50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::make_tuple;
51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::tuple;
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::tuple_element;
53f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::_;
54f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::Action;
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::ActionInterface;
56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::ByRef;
57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::DoAll;
58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::Invoke;
59f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::Return;
60f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::ReturnNew;
61f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::SetArgPointee;
62f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::StaticAssertTypeEq;
63f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::Unused;
64f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochusing testing::WithArgs;
65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// For suppressing compiler warnings on conversion possibly losing precision.
67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochinline short Short(short n) { return n; }  // NOLINT
68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochinline char Char(char ch) { return ch; }
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Sample functions and functors for testing various actions.
71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint Nullary() { return 1; }
72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass NullaryFunctor {
74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int operator()() { return 2; }
76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool g_done = false;
79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool Unary(int x) { return x < 0; }
81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char* Plus1(const char* s) { return s + 1; }
83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool ByConstRef(const string& s) { return s == "Hi"; }
85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst double g_double = 0;
87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
89f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring ByNonConstRef(string& s) { return s += "+"; }  // NOLINT
90f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
91f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct UnaryFunctor {
92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int operator()(bool x) { return x ? 1 : -1; }
93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochconst char* Binary(const char* input, short n) { return input + n; }  // NOLINT
96f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
97f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid VoidBinary(int, char) { g_done = true; }
98f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
99f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint Ternary(int x, char y, short z) { return x + y + z; }  // NOLINT
100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid VoidTernary(int, char, bool) { g_done = true; }
102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring Concat4(const char* s1, const char* s2, const char* s3,
106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s4) {
107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return string(s1) + s2 + s3 + s4;
108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct SumOf5Functor {
113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int operator()(int a, int b, int c, int d, int e) {
114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return a + b + c + d + e;
115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring Concat5(const char* s1, const char* s2, const char* s3,
119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s4, const char* s5) {
120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return string(s1) + s2 + s3 + s4 + s5;
121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint SumOf6(int a, int b, int c, int d, int e, int f) {
124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return a + b + c + d + e + f;
125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct SumOf6Functor {
128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int operator()(int a, int b, int c, int d, int e, int f) {
129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return a + b + c + d + e + f;
130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring Concat6(const char* s1, const char* s2, const char* s3,
134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s4, const char* s5, const char* s6) {
135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return string(s1) + s2 + s3 + s4 + s5 + s6;
136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring Concat7(const char* s1, const char* s2, const char* s3,
139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s4, const char* s5, const char* s6,
140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s7) {
141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring Concat8(const char* s1, const char* s2, const char* s3,
145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s4, const char* s5, const char* s6,
146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s7, const char* s8) {
147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring Concat9(const char* s1, const char* s2, const char* s3,
151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s4, const char* s5, const char* s6,
152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               const char* s7, const char* s8, const char* s9) {
153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstring Concat10(const char* s1, const char* s2, const char* s3,
157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                const char* s4, const char* s5, const char* s6,
158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                const char* s7, const char* s8, const char* s9,
159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                const char* s10) {
160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// A helper that turns the type of a C-string literal from const
164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// char[N] to const char*.
165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochinline const char* CharPtr(const char* s) { return s; }
166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests InvokeArgument<N>(...).
168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a nullary function.
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Function0) {
171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int, int(*)())> a = InvokeArgument<1>();  // NOLINT
172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary)));
173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a unary function.
176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Functor1) {
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(UnaryFunctor)> a = InvokeArgument<0>(true);  // NOLINT
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor())));
179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 5-ary function.
182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Function5) {
183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int(*)(int, int, int, int, int))> a =  // NOLINT
184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>(10000, 2000, 300, 40, 5);
185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5)));
186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 5-ary functor.
189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Functor5) {
190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(SumOf5Functor)> a =  // NOLINT
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>(10000, 2000, 300, 40, 5);
192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor())));
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 6-ary function.
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Function6) {
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int(*)(int, int, int, int, int, int))> a =  // NOLINT
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6)));
200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 6-ary functor.
203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Functor6) {
204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(SumOf6Functor)> a =  // NOLINT
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor())));
207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 7-ary function.
210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Function7) {
211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(string(*)(const char*, const char*, const char*,
212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*, const char*, const char*,
213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*))> a =
214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("1234567", a.Perform(make_tuple(&Concat7)));
216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 8-ary function.
219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Function8) {
220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(string(*)(const char*, const char*, const char*,
221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*, const char*, const char*,
222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*, const char*))> a =
223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("12345678", a.Perform(make_tuple(&Concat8)));
225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 9-ary function.
228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Function9) {
229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(string(*)(const char*, const char*, const char*,
230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*, const char*, const char*,
231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*, const char*, const char*))> a =
232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("123456789", a.Perform(make_tuple(&Concat9)));
234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a 10-ary function.
237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, Function10) {
238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(string(*)(const char*, const char*, const char*,
239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*, const char*, const char*,
240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*, const char*, const char*,
241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          const char*))> a =
242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10)));
244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a function that takes a pointer argument.
247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, ByPointerFunction) {
248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<const char*(const char*(*)(const char* input, short n))> a =  // NOLINT
249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));
250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a function that takes a const char*
254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// by passing it a C-string literal.
255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<const char*(const char*(*)(const char* input, short n))> a =  // NOLINT
257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>("Hi", Short(1));
258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with a function that takes a const reference.
262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, ByConstReferenceFunction) {
263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<bool(bool(*function)(const string& s))> a =  // NOLINT
264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>(string("Hi"));
265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // When action 'a' is constructed, it makes a copy of the temporary
266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // string object passed to it, so it's OK to use 'a' later, when the
267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // temporary object has already died.
268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_TRUE(a.Perform(make_tuple(&ByConstRef)));
269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using InvokeArgument with ByRef() and a function that takes a
272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// const reference.
273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
274f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<bool(bool(*)(const double& x))> a =  // NOLINT
275f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InvokeArgument<0>(ByRef(g_double));
276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // The above line calls ByRef() on a const value.
277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
278f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
279f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  double x = 0;
280f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a = InvokeArgument<0>(ByRef(x));  // This calls ByRef() on a non-const.
281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs and with an action that takes 1 argument.
285f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, OneArg) {
286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary));  // NOLINT
287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
289f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 2 arguments.
292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, TwoArgs) {
293f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<const char*(const char* s, double x, short n)> a =
294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 2>(Invoke(Binary));
295f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const char s[] = "Hello";
296f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, Short(2))));
297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 3 arguments.
300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, ThreeArgs) {
301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int, double, char, short)> a =  // NOLINT
302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 2, 3>(Invoke(Ternary));
303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, Char(20), Short(3))));
304f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 4 arguments.
307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, FourArgs) {
308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(const char*, const char*, double, const char*, const char*)> a =
309f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<4, 3, 1, 0>(Invoke(Concat4));
310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5,
311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         CharPtr("3"), CharPtr("4"))));
312f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 5 arguments.
315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, FiveArgs) {
316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(const char*, const char*, const char*,
317f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                const char*, const char*)> a =
318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5));
319f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("43210",
320f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
321f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 CharPtr("3"), CharPtr("4"))));
322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
323f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
324f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 6 arguments.
325f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, SixArgs) {
326f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(const char*, const char*, const char*)> a =
327f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6));
328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("012210",
329f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"))));
330f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
331f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
332f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 7 arguments.
333f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, SevenArgs) {
334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(const char*, const char*, const char*, const char*)> a =
335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7));
336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("0123210",
337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 CharPtr("3"))));
339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 8 arguments.
342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, EightArgs) {
343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(const char*, const char*, const char*, const char*)> a =
344f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8));
345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("01230123",
346f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 CharPtr("3"))));
348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 9 arguments.
351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, NineArgs) {
352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(const char*, const char*, const char*, const char*)> a =
353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9));
354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("012312323",
355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 CharPtr("3"))));
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that takes 10 arguments.
360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, TenArgs) {
361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<string(const char*, const char*, const char*, const char*)> a =
362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10));
363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("0123210123",
364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 CharPtr("3"))));
366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that is not Invoke().
369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass SubstractAction : public ActionInterface<int(int, int)> {  // NOLINT
370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  virtual int Perform(const tuple<int, int>& args) {
372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return get<0>(args) - get<1>(args);
373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, NonInvokeAction) {
377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(const string&, int, int)> a =  // NOLINT
378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<2, 1>(MakeAction(new SubstractAction));
379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(8, a.Perform(make_tuple(string("hi"), 2, 10)));
380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs to pass all original arguments in the original order.
383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, Identity) {
384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int x, char y, short z)> a =  // NOLINT
385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 1, 2>(Invoke(Ternary));
386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(123, a.Perform(make_tuple(100, Char(20), Short(3))));
387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with repeated arguments.
390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, RepeatedArguments) {
391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(bool, int m, int n)> a =  // NOLINT
392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10)));
394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with reversed argument order.
397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, ReversedArgumentOrder) {
398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<const char*(short n, const char* input)> a =  // NOLINT
399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<1, 0>(Invoke(Binary));
400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const char s[] = "Hello";
401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(s + 2, a.Perform(make_tuple(Short(2), CharPtr(s))));
402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
403f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
404f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with compatible, but not identical, argument types.
405f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, ArgsOfCompatibleTypes) {
406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<long(short x, char y, double z, char c)> a =  // NOLINT
407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      WithArgs<0, 1, 3>(Invoke(Ternary));
408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(123, a.Perform(make_tuple(Short(100), Char(20), 5.6, Char(3))));
409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using WithArgs with an action that returns void.
412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(WithArgsTest, VoidAction) {
413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  g_done = false;
415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a.Perform(make_tuple(1.5, 'a', 3));
416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_TRUE(g_done);
417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2).
420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, TwoActions) {
421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int n = 0;
422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*)> a = DoAll(SetArgPointee<0>(1),  // NOLINT
423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              Return(2));
424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, a.Perform(make_tuple(&n)));
425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, n);
426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, a3).
429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, ThreeActions) {
430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
431f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1),  // NOLINT
432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    SetArgPointee<1>(2),
433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    Return(3));
434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, a.Perform(make_tuple(&m, &n)));
435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, a3, a4).
440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, FourActions) {
441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char ch = '\0';
443f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*, char*)> a =  // NOLINT
444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DoAll(SetArgPointee<0>(1),
445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<1>(2),
446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<2>('a'),
447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Return(3));
448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch)));
449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('a', ch);
452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, a3, a4, a5).
455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, FiveActions) {
456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
457f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char a = '\0', b = '\0';
458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*, char*, char*)> action =  // NOLINT
459f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DoAll(SetArgPointee<0>(1),
460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<1>(2),
461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<2>('a'),
462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<3>('b'),
463f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Return(3));
464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b)));
465f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
466f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
467f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('a', a);
468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('b', b);
469f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
470f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
471f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, ..., a6).
472f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, SixActions) {
473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char a = '\0', b = '\0', c = '\0';
475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*, char*, char*, char*)> action =  // NOLINT
476f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DoAll(SetArgPointee<0>(1),
477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<1>(2),
478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<2>('a'),
479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<3>('b'),
480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<4>('c'),
481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Return(3));
482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c)));
483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('a', a);
486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('b', b);
487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('c', c);
488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, ..., a7).
491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, SevenActions) {
492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char a = '\0', b = '\0', c = '\0', d = '\0';
494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*, char*, char*, char*, char*)> action =  // NOLINT
495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DoAll(SetArgPointee<0>(1),
496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<1>(2),
497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<2>('a'),
498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<3>('b'),
499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<4>('c'),
500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<5>('d'),
501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Return(3));
502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d)));
503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('a', a);
506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('b', b);
507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('c', c);
508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('d', d);
509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, ..., a8).
512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, EightActions) {
513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
514f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*, char*, char*, char*, char*,  // NOLINT
516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             char*)> action =
517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DoAll(SetArgPointee<0>(1),
518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<1>(2),
519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<2>('a'),
520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<3>('b'),
521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<4>('c'),
522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<5>('d'),
523f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<6>('e'),
524f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Return(3));
525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e)));
526f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
527f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('a', a);
529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('b', b);
530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('c', c);
531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('d', d);
532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('e', e);
533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, ..., a9).
536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, NineActions) {
537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*, char*, char*, char*, char*,  // NOLINT
540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             char*, char*)> action =
541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DoAll(SetArgPointee<0>(1),
542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<1>(2),
543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<2>('a'),
544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<3>('b'),
545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<4>('c'),
546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<5>('d'),
547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<6>('e'),
548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<7>('f'),
549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Return(3));
550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('a', a);
554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('b', b);
555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('c', c);
556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('d', d);
557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('e', e);
558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('f', f);
559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
561f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests DoAll(a1, a2, ..., a10).
562f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(DoAllTest, TenActions) {
563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int m = 0, n = 0;
564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char a = '\0', b = '\0', c = '\0', d = '\0';
565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char e = '\0', f = '\0', g = '\0';
566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int*, int*, char*, char*, char*, char*,  // NOLINT
567f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             char*, char*, char*)> action =
568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DoAll(SetArgPointee<0>(1),
569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<1>(2),
570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<2>('a'),
571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<3>('b'),
572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<4>('c'),
573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<5>('d'),
574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<6>('e'),
575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<7>('f'),
576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            SetArgPointee<8>('g'),
577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            Return(3));
578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, m);
580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(2, n);
581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('a', a);
582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('b', b);
583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('c', c);
584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('d', d);
585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('e', e);
586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('f', f);
587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ('g', g);
588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// The ACTION*() macros trigger warning C4100 (unreferenced formal
591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// parameter) in MSVC with -W4.  Unfortunately they cannot be fixed in
592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// the macro definition, as the warnings are generated when the macro
593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// is expanded and macro expansion cannot contain #pragma.  Therefore
594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// we suppress them here.
595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#ifdef _MSC_VER
596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# pragma warning(push)
597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# pragma warning(disable:4100)
598f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#endif
599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests the ACTION*() macro family.
601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION() can define an action that doesn't reference the
603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// mock function arguments.
604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(Return5) { return 5; }
605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, WorksWhenNotReferencingArguments) {
607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<double()> a1 = Return5();
608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple()));
609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(double, bool)> a2 = Return5();
611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(5, a2.Perform(make_tuple(1, true)));
612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION() can define an action that returns void.
615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(IncrementArg1) { (*arg1)++; }
616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, WorksWhenReturningVoid) {
618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<void(int, int*)> a1 = IncrementArg1();
619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int n = 0;
620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a1.Perform(make_tuple(5, &n));
621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, n);
622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that the body of ACTION() can reference the type of the
625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// argument.
626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(IncrementArg2) {
627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  StaticAssertTypeEq<int*, arg2_type>();
628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  arg2_type temp = arg2;
629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (*temp)++;
630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, CanReferenceArgumentType) {
633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<void(int, bool, int*)> a1 = IncrementArg2();
634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int n = 0;
635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a1.Perform(make_tuple(5, false, &n));
636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, n);
637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that the body of ACTION() can reference the argument tuple
640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// via args_type and args.
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(Sum2) {
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  StaticAssertTypeEq<tuple<int, char, int*>, args_type>();
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  args_type args_copy = args;
644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return get<0>(args_copy) + get<1>(args_copy);
645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, CanReferenceArgumentTuple) {
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int, char, int*)> a1 = Sum2();
649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int dummy = 0;
650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(11, a1.Perform(make_tuple(5, Char(6), &dummy)));
651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that the body of ACTION() can reference the mock function
654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// type.
655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochint Dummy(bool flag) { return flag? 1 : 0; }
656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(InvokeDummy) {
658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  StaticAssertTypeEq<int(bool), function_type>();
659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  function_type* fp = &Dummy;
660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return (*fp)(true);
661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, CanReferenceMockFunctionType) {
664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(bool)> a1 = InvokeDummy();
665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a1.Perform(make_tuple(true)));
666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a1.Perform(make_tuple(false)));
667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that the body of ACTION() can reference the mock function's
670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// return type.
671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(InvokeDummy2) {
672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  StaticAssertTypeEq<int, return_type>();
673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return_type result = Dummy(true);
674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return result;
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(bool)> a1 = InvokeDummy2();
679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a1.Perform(make_tuple(true)));
680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a1.Perform(make_tuple(false)));
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION() works for arguments passed by const reference.
684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(ReturnAddrOfConstBoolReferenceArg) {
685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  StaticAssertTypeEq<const bool&, arg1_type>();
686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return &arg1;
687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, WorksForConstReferenceArg) {
690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();
691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const bool b = false;
692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(&b, a.Perform(tuple<int, const bool&>(0, b)));
693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION() works for arguments passed by non-const reference.
696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(ReturnAddrOfIntReferenceArg) {
697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  StaticAssertTypeEq<int&, arg0_type>();
698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return &arg0;
699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, WorksForNonConstReferenceArg) {
702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();
703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int n = 0;
704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(&n, a.Perform(tuple<int&, bool, int>(n, true, 1)));
705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION() can be used in a namespace.
708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace action_test {
709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(Sum) { return arg0 + arg1; }
710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace action_test
711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, WorksInNamespace) {
713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int, int)> a1 = action_test::Sum();
714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, a1.Perform(make_tuple(1, 2)));
715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that the same ACTION definition works for mock functions with
718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// different argument numbers.
719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(PlusTwo) { return arg0 + 2; }
720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {
722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = PlusTwo();
723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(4, a1.Perform(make_tuple(2)));
724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<double(float, void*)> a2 = PlusTwo();
726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int dummy;
727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_DOUBLE_EQ(6, a2.Perform(make_tuple(4.0f, &dummy)));
728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_P can define a parameterized action.
731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P(Plus, n) { return arg0 + n; }
732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPMacroTest, DefinesParameterizedAction) {
734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int m, bool t)> a1 = Plus(9);
735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10, a1.Perform(make_tuple(1, true)));
736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that the body of ACTION_P can reference the argument types
739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// and the parameter type.
740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P(TypedPlus, n) {
741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  arg0_type t1 = arg0;
742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  n_type t2 = n;
743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return t1 + t2;
744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {
747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(char m, bool t)> a1 = TypedPlus(9);
748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10, a1.Perform(make_tuple(Char(1), true)));
749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that a parameterized action can be used in any mock function
752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// whose type is compatible.
753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPMacroTest, WorksInCompatibleMockFunction) {
754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<std::string(const std::string& s)> a1 = Plus("tail");
755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const std::string re = "re";
756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("retail", a1.Perform(make_tuple(re)));
757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that we can use ACTION*() to define actions overloaded on the
760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// number of parameters.
761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }
763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P(OverloadedAction, default_value) {
765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return arg0 ? arg1 : default_value;
766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P2(OverloadedAction, true_value, false_value) {
769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return arg0 ? true_value : false_value;
770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionMacroTest, CanDefineOverloadedActions) {
773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef Action<const char*(bool, const char*)> MyAction;
774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const MyAction a1 = OverloadedAction();
776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("hello", a1.Perform(make_tuple(false, CharPtr("world"))));
777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("world", a1.Perform(make_tuple(true, CharPtr("world"))));
778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const MyAction a2 = OverloadedAction("hi");
780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("hi", a2.Perform(make_tuple(false, CharPtr("world"))));
781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("world", a2.Perform(make_tuple(true, CharPtr("world"))));
782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const MyAction a3 = OverloadedAction("hi", "you");
784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("hi", a3.Perform(make_tuple(true, CharPtr("world"))));
785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_STREQ("you", a3.Perform(make_tuple(false, CharPtr("world"))));
786f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests ACTION_Pn where n >= 3.
789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }
791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor3Parameters) {
793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);
794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_DOUBLE_EQ(3123.4, a1.Perform(make_tuple(3000, true)));
795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");
797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const std::string re = "re";
798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("retail->", a2.Perform(make_tuple(re)));
799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }
802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor4Parameters) {
804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = Plus(1, 2, 3, 4);
805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(make_tuple(10)));
806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }
809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor5Parameters) {
811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);
812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(make_tuple(10)));
813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {
816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return arg0 + p0 + p1 + p2 + p3 + p4 + p5;
817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor6Parameters) {
820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);
821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(make_tuple(10)));
822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {
825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;
826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor7Parameters) {
829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);
830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(make_tuple(10)));
831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {
834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor8Parameters) {
838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);
839f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, a1.Perform(make_tuple(10)));
840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {
843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;
844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor9Parameters) {
847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);
848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, a1.Perform(make_tuple(10)));
849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
850f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {
852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  arg0_type t0 = arg0;
853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  last_param_type t9 = last_param;
854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;
855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, WorksFor10Parameters) {
858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,
860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            a1.Perform(make_tuple(10)));
861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that the action body can promote the parameter types.
864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P2(PadArgument, prefix, suffix) {
866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // The following lines promote the two parameters to desired types.
867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  std::string prefix_str(prefix);
868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  char suffix_char = static_cast<char>(suffix);
869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return prefix_str + arg0 + suffix_char;
870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, SimpleTypePromotion) {
873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<std::string(const char*)> no_promo =
874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      PadArgument(std::string("foo"), 'r');
875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<std::string(const char*)> promo =
876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      PadArgument("foo", static_cast<int>('r'));
877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba"))));
878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba"))));
879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that we can partially restrict parameter types using a
882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// straight-forward pattern.
883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Defines a generic action that doesn't restrict the types of its
885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// parameters.
886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P3(ConcatImpl, a, b, c) {
887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  std::stringstream ss;
888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ss << a << b << c;
889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return ss.str();
890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Next, we try to restrict that either the first parameter is a
893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// string, or the second parameter is an int.
894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Defines a partially specialized wrapper that restricts the first
896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// parameter to std::string.
897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T1, typename T2>
898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ConcatImplActionP3 is the class template ACTION_P3 uses to
899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// implement ConcatImpl.  We shouldn't change the name as this
900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// pattern requires the user to use it directly.
901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochConcatImplActionP3<std::string, T1, T2>
902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochConcat(const std::string& a, T1 b, T2 c) {
903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GTEST_INTENTIONAL_CONST_COND_PUSH_()
904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (true) {
905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GTEST_INTENTIONAL_CONST_COND_POP_()
906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // This branch verifies that ConcatImpl() can be invoked without
907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // explicit template arguments.
908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return ConcatImpl(a, b, c);
909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // This branch verifies that ConcatImpl() can also be invoked with
911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // explicit template arguments.  It doesn't really need to be
912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    // executed as this is a compile-time verification.
913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return ConcatImpl<std::string, T1, T2>(a, b, c);
914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Defines another partially specialized wrapper that restricts the
918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// second parameter to int.
919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T1, typename T2>
920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochConcatImplActionP3<T1, int, T2>
921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochConcat(T1 a, int b, T2 c) {
922f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return ConcatImpl(a, b, c);
923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
924f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
925f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {
926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<const std::string()> a1 = Concat("Hello", "1", 2);
927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("Hello12", a1.Perform(make_tuple()));
928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a1 = Concat(1, 2, 3);
930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ("123", a1.Perform(make_tuple()));
931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Verifies the type of an ACTION*.
934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(DoFoo) {}
936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P(DoFoo, p) {}
937f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P2(DoFoo, p0, p1) {}
938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, TypesAreCorrect) {
940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // DoFoo() must be assignable to a DoFooAction variable.
941f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DoFooAction a0 = DoFoo();
942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // DoFoo(1) must be assignable to a DoFooActionP variable.
944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DoFooActionP<int> a1 = DoFoo(1);
945f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
946f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk
947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // variable, and so on.
948f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DoFooActionP2<int, char> a2 = DoFoo(1, '2');
949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');
950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');
951f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');
952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');
953f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP7<int, int, int, int, int, int, char> a7 =
954f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Plus(1, 2, 3, 4, 5, 6, '7');
955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP8<int, int, int, int, int, int, int, char> a8 =
956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Plus(1, 2, 3, 4, 5, 6, 7, '8');
957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =
958f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');
959f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =
960f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
961f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Avoid "unused variable" warnings.
963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a0;
964f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a1;
965f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a2;
966f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a3;
967f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a4;
968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a5;
969f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a6;
970f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a7;
971f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a8;
972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a9;
973f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  (void)a10;
974f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
975f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
976f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that an ACTION_P*() action can be explicitly instantiated
977f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// with reference-typed parameters.
978f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
979f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P(Plus1, x) { return x; }
980f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P2(Plus2, x, y) { return x + y; }
981f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P3(Plus3, x, y, z) { return x + y + z; }
982f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
983f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
987f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int x = 1, y = 2, z = 3;
988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const tuple<> empty = make_tuple();
989f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<int()> a = Plus1<int&>(x);
991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a.Perform(empty));
992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a = Plus2<const int&, int&>(x, y);
994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, a.Perform(empty));
995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
996f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a = Plus3<int&, const int&, int&>(x, y, z);
997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(6, a.Perform(empty));
998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
1000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,
1001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7],
1002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              n[8], n[9]);
1003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(55, a.Perform(empty));
1004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass NullaryConstructorClass {
1007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
1008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NullaryConstructorClass() : value_(123) {}
1009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int value_;
1010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
1011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using ReturnNew() with a nullary constructor.
1013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ReturnNewTest, NoArgs) {
1014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<NullaryConstructorClass*()> a = ReturnNew<NullaryConstructorClass>();
1015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NullaryConstructorClass* c = a.Perform(make_tuple());
1016f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(123, c->value_);
1017f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete c;
1018f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1020f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass UnaryConstructorClass {
1021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
1022f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit UnaryConstructorClass(int value) : value_(value) {}
1023f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int value_;
1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using ReturnNew() with a unary constructor.
1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ReturnNewTest, Unary) {
1028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000);
1029f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UnaryConstructorClass* c = a.Perform(make_tuple());
1030f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(4000, c->value_);
1031f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete c;
1032f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1033f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1034f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) {
1035f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<UnaryConstructorClass*(bool, int)> a =
1036f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ReturnNew<UnaryConstructorClass>(4000);
1037f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UnaryConstructorClass* c = a.Perform(make_tuple(false, 5));
1038f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(4000, c->value_);
1039f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete c;
1040f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1041f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1042f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) {
1043f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<const UnaryConstructorClass*()> a =
1044f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ReturnNew<UnaryConstructorClass>(4000);
1045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const UnaryConstructorClass* c = a.Perform(make_tuple());
1046f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(4000, c->value_);
1047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete c;
1048f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1050f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass TenArgConstructorClass {
1051f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
1052f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5,
1053f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                         int a6, int a7, int a8, int a9, int a10)
1054f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {
1055f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1056f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int value_;
1057f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
1058f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1059f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests using ReturnNew() with a 10-argument constructor.
1060f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
1061f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Action<TenArgConstructorClass*()> a =
1062f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ReturnNew<TenArgConstructorClass>(1000000000, 200000000, 30000000,
1063f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                        4000000, 500000, 60000,
1064f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                        7000, 800, 90, 0);
1065f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TenArgConstructorClass* c = a.Perform(make_tuple());
1066f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1234567890, c->value_);
1067f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete c;
1068f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1069f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1070f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_TEMPLATE works when there is no value parameter.
1071f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(CreateNew,
1072f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_1_TEMPLATE_PARAMS(typename, T),
1073f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_0_VALUE_PARAMS()) {
1074f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return new T;
1075f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1076f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1077f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionTemplateTest, WorksWithoutValueParam) {
1078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int*()> a = CreateNew<int>();
1079f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int* p = a.Perform(make_tuple());
1080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete p;
1081f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1082f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1083f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_TEMPLATE works when there are value parameters.
1084f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(CreateNew,
1085f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_1_TEMPLATE_PARAMS(typename, T),
1086f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_1_VALUE_PARAMS(a0)) {
1087f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return new T(a0);
1088f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1089f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1090f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionTemplateTest, WorksWithValueParams) {
1091f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int*()> a = CreateNew<int>(42);
1092f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int* p = a.Perform(make_tuple());
1093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(42, *p);
1094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete p;
1095f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1096f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1097f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_TEMPLATE works for integral template parameters.
1098f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(MyDeleteArg,
1099f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_1_TEMPLATE_PARAMS(int, k),
1100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_0_VALUE_PARAMS()) {
1101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  delete get<k>(args);
1102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Resets a bool variable in the destructor.
1105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass BoolResetter {
1106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
1107f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit BoolResetter(bool* value) : value_(value) {}
1108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ~BoolResetter() { *value_ = false; }
1109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool* value_;
1111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
1112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
1114f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
1115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int n = 0;
1116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool b = true;
1117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BoolResetter* resetter = new BoolResetter(&b);
1118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  a.Perform(make_tuple(&n, resetter));
1119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_FALSE(b);  // Verifies that resetter is deleted.
1120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_TEMPLATES works for template template parameters.
1123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(ReturnSmartPointer,
1124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,
1125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                      Pointer),
1126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_1_VALUE_PARAMS(pointee)) {
1127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return Pointer<pointee_type>(new pointee_type(pointee));
1128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {
1131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  using ::testing::internal::linked_ptr;
1132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42);
1133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  linked_ptr<int> p = a.Perform(make_tuple());
1134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(42, *p);
1135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_TEMPLATE works for 10 template parameters.
1138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <typename T1, typename T2, typename T3, int k4, bool k5,
1139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          unsigned int k6, typename T7, typename T8, typename T9>
1140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct GiantTemplate {
1141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
1142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit GiantTemplate(int a_value) : value(a_value) {}
1143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int value;
1144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
1145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(ReturnGiant,
1147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_10_TEMPLATE_PARAMS(
1148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    typename, T1,
1149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    typename, T2,
1150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    typename, T3,
1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    int, k4,
1152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    bool, k5,
1153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    unsigned int, k6,
1154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    class, T7,
1155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    class, T8,
1156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    class, T9,
1157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    template <typename T> class, T10),
1158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_1_VALUE_PARAMS(value)) {
1159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);
1160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionTemplateTest, WorksFor10TemplateParameters) {
1163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  using ::testing::internal::linked_ptr;
1164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  typedef GiantTemplate<linked_ptr<int>, bool, double, 5,
1165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      true, 6, char, unsigned, int> Giant;
1166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<Giant()> a = ReturnGiant<
1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42);
1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Giant giant = a.Perform(make_tuple());
1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(42, giant.value);
1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_TEMPLATE works for 10 value parameters.
1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(ReturnSum,
1174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_1_TEMPLATE_PARAMS(typename, Number),
1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {
1176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
1177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionTemplateTest, WorksFor10ValueParameters) {
1180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
1181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(55, a.Perform(make_tuple()));
1182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded
1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// on the number of value parameters.
1186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION(ReturnSum) { return 0; }
1188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_P(ReturnSum, x) { return x; }
1190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(ReturnSum,
1192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_1_TEMPLATE_PARAMS(typename, Number),
1193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_2_VALUE_PARAMS(v1, v2)) {
1194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return static_cast<Number>(v1) + v2;
1195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(ReturnSum,
1198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_1_TEMPLATE_PARAMS(typename, Number),
1199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_3_VALUE_PARAMS(v1, v2, v3)) {
1200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return static_cast<Number>(v1) + v2 + v3;
1201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochACTION_TEMPLATE(ReturnSum,
1204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),
1205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {
1206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return static_cast<Number>(v1) + v2 + v3 + v4 + k;
1207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochTEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
1210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int()> a0 = ReturnSum();
1211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int()> a1 = ReturnSum(1);
1212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int()> a2 = ReturnSum<int>(1, 2);
1213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
1214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
1215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(0, a0.Perform(make_tuple()));
1216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(1, a1.Perform(make_tuple()));
1217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(3, a2.Perform(make_tuple()));
1218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(6, a3.Perform(make_tuple()));
1219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EXPECT_EQ(12345, a4.Perform(make_tuple()));
1220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#ifdef _MSC_VER
1223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch# pragma warning(pop)
1224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#endif
1225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace gmock_generated_actions_test
1227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace testing
1228