Path: blob/main/contrib/googletest/googlemock/test/gmock-more-actions_test.cc
48255 views
// Copyright 2007, Google Inc.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are5// met:6//7// * Redistributions of source code must retain the above copyright8// notice, this list of conditions and the following disclaimer.9// * Redistributions in binary form must reproduce the above10// copyright notice, this list of conditions and the following disclaimer11// in the documentation and/or other materials provided with the12// distribution.13// * Neither the name of Google Inc. nor the names of its14// contributors may be used to endorse or promote products derived from15// this software without specific prior written permission.16//17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2829// Google Mock - a framework for writing C++ mock classes.30//31// This file tests the built-in actions in gmock-actions.h.3233#include "gmock/gmock-more-actions.h"3435#include <algorithm>36#include <functional>37#include <iterator>38#include <memory>39#include <sstream>40#include <string>41#include <tuple>42#include <vector>4344#include "gmock/gmock.h"45#include "gtest/gtest-spi.h"46#include "gtest/gtest.h"4748GTEST_DISABLE_MSC_WARNINGS_PUSH_(4577)4950namespace testing {51namespace gmock_more_actions_test {5253using ::std::plus;54using ::std::string;55using testing::Action;56using testing::DeleteArg;57using testing::Invoke;58using testing::ReturnArg;59using testing::ReturnPointee;60using testing::SaveArg;61using testing::SaveArgPointee;62using testing::SetArgReferee;63using testing::Unused;64using testing::WithArg;65using testing::WithoutArgs;6667// For suppressing compiler warnings on conversion possibly losing precision.68inline short Short(short n) { return n; } // NOLINT69inline char Char(char ch) { return ch; }7071// Sample functions and functors for testing Invoke() and etc.72int Nullary() { return 1; }7374bool g_done = false;7576bool Unary(int x) { return x < 0; }7778bool ByConstRef(const std::string& s) { return s == "Hi"; }7980const double g_double = 0;81bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }8283struct UnaryFunctor {84int operator()(bool x) { return x ? 1 : -1; }85};8687struct UnaryMoveOnlyFunctor : UnaryFunctor {88UnaryMoveOnlyFunctor() = default;89UnaryMoveOnlyFunctor(const UnaryMoveOnlyFunctor&) = delete;90UnaryMoveOnlyFunctor(UnaryMoveOnlyFunctor&&) = default;91};9293struct OneShotUnaryFunctor {94int operator()(bool x) && { return x ? 1 : -1; }95};9697const char* Binary(const char* input, short n) { return input + n; } // NOLINT9899int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT100101int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }102103int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }104105int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }106107struct SumOf5Functor {108int operator()(int a, int b, int c, int d, int e) {109return a + b + c + d + e;110}111};112113int SumOf6(int a, int b, int c, int d, int e, int f) {114return a + b + c + d + e + f;115}116117struct SumOf6Functor {118int operator()(int a, int b, int c, int d, int e, int f) {119return a + b + c + d + e + f;120}121};122123std::string Concat7(const char* s1, const char* s2, const char* s3,124const char* s4, const char* s5, const char* s6,125const char* s7) {126return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7;127}128129std::string Concat8(const char* s1, const char* s2, const char* s3,130const char* s4, const char* s5, const char* s6,131const char* s7, const char* s8) {132return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;133}134135std::string Concat9(const char* s1, const char* s2, const char* s3,136const char* s4, const char* s5, const char* s6,137const char* s7, const char* s8, const char* s9) {138return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;139}140141std::string Concat10(const char* s1, const char* s2, const char* s3,142const char* s4, const char* s5, const char* s6,143const char* s7, const char* s8, const char* s9,144const char* s10) {145return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;146}147148class Foo {149public:150Foo() : value_(123) {}151152int Nullary() const { return value_; }153154short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT155156std::string Binary(const std::string& str, char c) const { return str + c; }157158int Ternary(int x, bool y, char z) { return value_ + x + y * z; }159160int SumOf4(int a, int b, int c, int d) const {161return a + b + c + d + value_;162}163164int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }165166int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }167168int SumOf6(int a, int b, int c, int d, int e, int f) {169return a + b + c + d + e + f;170}171172std::string Concat7(const char* s1, const char* s2, const char* s3,173const char* s4, const char* s5, const char* s6,174const char* s7) {175return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7;176}177178std::string Concat8(const char* s1, const char* s2, const char* s3,179const char* s4, const char* s5, const char* s6,180const char* s7, const char* s8) {181return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;182}183184std::string Concat9(const char* s1, const char* s2, const char* s3,185const char* s4, const char* s5, const char* s6,186const char* s7, const char* s8, const char* s9) {187return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;188}189190std::string Concat10(const char* s1, const char* s2, const char* s3,191const char* s4, const char* s5, const char* s6,192const char* s7, const char* s8, const char* s9,193const char* s10) {194return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;195}196197private:198int value_;199};200201// Tests using Invoke() with a nullary function.202TEST(InvokeTest, Nullary) {203Action<int()> a = Invoke(Nullary); // NOLINT204EXPECT_EQ(1, a.Perform(std::make_tuple()));205}206207// Tests using Invoke() with a unary function.208TEST(InvokeTest, Unary) {209Action<bool(int)> a = Invoke(Unary); // NOLINT210EXPECT_FALSE(a.Perform(std::make_tuple(1)));211EXPECT_TRUE(a.Perform(std::make_tuple(-1)));212}213214// Tests using Invoke() with a binary function.215TEST(InvokeTest, Binary) {216Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT217const char* p = "Hello";218EXPECT_EQ(p + 2, a.Perform(std::make_tuple(p, Short(2))));219}220221// Tests using Invoke() with a ternary function.222TEST(InvokeTest, Ternary) {223Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT224EXPECT_EQ(6, a.Perform(std::make_tuple(1, '\2', Short(3))));225}226227// Tests using Invoke() with a 4-argument function.228TEST(InvokeTest, FunctionThatTakes4Arguments) {229Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT230EXPECT_EQ(1234, a.Perform(std::make_tuple(1000, 200, 30, 4)));231}232233// Tests using Invoke() with a 5-argument function.234TEST(InvokeTest, FunctionThatTakes5Arguments) {235Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT236EXPECT_EQ(12345, a.Perform(std::make_tuple(10000, 2000, 300, 40, 5)));237}238239// Tests using Invoke() with a 6-argument function.240TEST(InvokeTest, FunctionThatTakes6Arguments) {241Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT242EXPECT_EQ(123456,243a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6)));244}245246// A helper that turns the type of a C-string literal from const247// char[N] to const char*.248inline const char* CharPtr(const char* s) { return s; }249250// Tests using Invoke() with a 7-argument function.251TEST(InvokeTest, FunctionThatTakes7Arguments) {252Action<std::string(const char*, const char*, const char*, const char*,253const char*, const char*, const char*)>254a = Invoke(Concat7);255EXPECT_EQ("1234567",256a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),257CharPtr("4"), CharPtr("5"), CharPtr("6"),258CharPtr("7"))));259}260261// Tests using Invoke() with a 8-argument function.262TEST(InvokeTest, FunctionThatTakes8Arguments) {263Action<std::string(const char*, const char*, const char*, const char*,264const char*, const char*, const char*, const char*)>265a = Invoke(Concat8);266EXPECT_EQ("12345678",267a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),268CharPtr("4"), CharPtr("5"), CharPtr("6"),269CharPtr("7"), CharPtr("8"))));270}271272// Tests using Invoke() with a 9-argument function.273TEST(InvokeTest, FunctionThatTakes9Arguments) {274Action<std::string(const char*, const char*, const char*, const char*,275const char*, const char*, const char*, const char*,276const char*)>277a = Invoke(Concat9);278EXPECT_EQ("123456789", a.Perform(std::make_tuple(279CharPtr("1"), CharPtr("2"), CharPtr("3"),280CharPtr("4"), CharPtr("5"), CharPtr("6"),281CharPtr("7"), CharPtr("8"), CharPtr("9"))));282}283284// Tests using Invoke() with a 10-argument function.285TEST(InvokeTest, FunctionThatTakes10Arguments) {286Action<std::string(const char*, const char*, const char*, const char*,287const char*, const char*, const char*, const char*,288const char*, const char*)>289a = Invoke(Concat10);290EXPECT_EQ("1234567890",291a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),292CharPtr("4"), CharPtr("5"), CharPtr("6"),293CharPtr("7"), CharPtr("8"), CharPtr("9"),294CharPtr("0"))));295}296297// Tests using Invoke() with functions with parameters declared as Unused.298TEST(InvokeTest, FunctionWithUnusedParameters) {299Action<int(int, int, double, const std::string&)> a1 = Invoke(SumOfFirst2);300std::tuple<int, int, double, std::string> dummy =301std::make_tuple(10, 2, 5.6, std::string("hi"));302EXPECT_EQ(12, a1.Perform(dummy));303304Action<int(int, int, bool, int*)> a2 = Invoke(SumOfFirst2);305EXPECT_EQ(30623, a2.Perform(std::make_tuple(20, 3, true, static_cast<int*>(nullptr))));307}308309// Tests using Invoke() with methods with parameters declared as Unused.310TEST(InvokeTest, MethodWithUnusedParameters) {311Foo foo;312Action<int(std::string, bool, int, int)> a1 = Invoke(&foo, &Foo::SumOfLast2);313EXPECT_EQ(12, a1.Perform(std::make_tuple(CharPtr("hi"), true, 10, 2)));314315Action<int(char, double, int, int)> a2 = Invoke(&foo, &Foo::SumOfLast2);316EXPECT_EQ(23, a2.Perform(std::make_tuple('a', 2.5, 20, 3)));317}318319// Tests using Invoke() with a functor.320TEST(InvokeTest, Functor) {321Action<long(long, int)> a = Invoke(plus<long>()); // NOLINT322EXPECT_EQ(3L, a.Perform(std::make_tuple(1, 2)));323}324325// Tests using Invoke(f) as an action of a compatible type.326TEST(InvokeTest, FunctionWithCompatibleType) {327Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT328EXPECT_EQ(4321, a.Perform(std::make_tuple(4000, Short(300), Char(20), true)));329}330331// Tests using Invoke() with an object pointer and a method pointer.332333// Tests using Invoke() with a nullary method.334TEST(InvokeMethodTest, Nullary) {335Foo foo;336Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT337EXPECT_EQ(123, a.Perform(std::make_tuple()));338}339340// Tests using Invoke() with a unary method.341TEST(InvokeMethodTest, Unary) {342Foo foo;343Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT344EXPECT_EQ(4123, a.Perform(std::make_tuple(4000)));345}346347// Tests using Invoke() with a binary method.348TEST(InvokeMethodTest, Binary) {349Foo foo;350Action<std::string(const std::string&, char)> a = Invoke(&foo, &Foo::Binary);351std::string s("Hell");352std::tuple<std::string, char> dummy = std::make_tuple(s, 'o');353EXPECT_EQ("Hello", a.Perform(dummy));354}355356// Tests using Invoke() with a ternary method.357TEST(InvokeMethodTest, Ternary) {358Foo foo;359Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT360EXPECT_EQ(1124, a.Perform(std::make_tuple(1000, true, Char(1))));361}362363// Tests using Invoke() with a 4-argument method.364TEST(InvokeMethodTest, MethodThatTakes4Arguments) {365Foo foo;366Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT367EXPECT_EQ(1357, a.Perform(std::make_tuple(1000, 200, 30, 4)));368}369370// Tests using Invoke() with a 5-argument method.371TEST(InvokeMethodTest, MethodThatTakes5Arguments) {372Foo foo;373Action<int(int, int, int, int, int)> a =374Invoke(&foo, &Foo::SumOf5); // NOLINT375EXPECT_EQ(12345, a.Perform(std::make_tuple(10000, 2000, 300, 40, 5)));376}377378// Tests using Invoke() with a 6-argument method.379TEST(InvokeMethodTest, MethodThatTakes6Arguments) {380Foo foo;381Action<int(int, int, int, int, int, int)> a = // NOLINT382Invoke(&foo, &Foo::SumOf6);383EXPECT_EQ(123456,384a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6)));385}386387// Tests using Invoke() with a 7-argument method.388TEST(InvokeMethodTest, MethodThatTakes7Arguments) {389Foo foo;390Action<std::string(const char*, const char*, const char*, const char*,391const char*, const char*, const char*)>392a = Invoke(&foo, &Foo::Concat7);393EXPECT_EQ("1234567",394a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),395CharPtr("4"), CharPtr("5"), CharPtr("6"),396CharPtr("7"))));397}398399// Tests using Invoke() with a 8-argument method.400TEST(InvokeMethodTest, MethodThatTakes8Arguments) {401Foo foo;402Action<std::string(const char*, const char*, const char*, const char*,403const char*, const char*, const char*, const char*)>404a = Invoke(&foo, &Foo::Concat8);405EXPECT_EQ("12345678",406a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),407CharPtr("4"), CharPtr("5"), CharPtr("6"),408CharPtr("7"), CharPtr("8"))));409}410411// Tests using Invoke() with a 9-argument method.412TEST(InvokeMethodTest, MethodThatTakes9Arguments) {413Foo foo;414Action<std::string(const char*, const char*, const char*, const char*,415const char*, const char*, const char*, const char*,416const char*)>417a = Invoke(&foo, &Foo::Concat9);418EXPECT_EQ("123456789", a.Perform(std::make_tuple(419CharPtr("1"), CharPtr("2"), CharPtr("3"),420CharPtr("4"), CharPtr("5"), CharPtr("6"),421CharPtr("7"), CharPtr("8"), CharPtr("9"))));422}423424// Tests using Invoke() with a 10-argument method.425TEST(InvokeMethodTest, MethodThatTakes10Arguments) {426Foo foo;427Action<std::string(const char*, const char*, const char*, const char*,428const char*, const char*, const char*, const char*,429const char*, const char*)>430a = Invoke(&foo, &Foo::Concat10);431EXPECT_EQ("1234567890",432a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),433CharPtr("4"), CharPtr("5"), CharPtr("6"),434CharPtr("7"), CharPtr("8"), CharPtr("9"),435CharPtr("0"))));436}437438// Tests using Invoke(f) as an action of a compatible type.439TEST(InvokeMethodTest, MethodWithCompatibleType) {440Foo foo;441Action<long(int, short, char, bool)> a = // NOLINT442Invoke(&foo, &Foo::SumOf4);443EXPECT_EQ(4444, a.Perform(std::make_tuple(4000, Short(300), Char(20), true)));444}445446// Tests using WithoutArgs with an action that takes no argument.447TEST(WithoutArgsTest, NoArg) {448Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT449EXPECT_EQ(1, a.Perform(std::make_tuple(2)));450}451452// Tests using WithArg with an action that takes 1 argument.453TEST(WithArgTest, OneArg) {454Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT455EXPECT_TRUE(b.Perform(std::make_tuple(1.5, -1)));456EXPECT_FALSE(b.Perform(std::make_tuple(1.5, 1)));457}458459TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {460const Action<int(int)> a = ReturnArg<0>();461EXPECT_EQ(5, a.Perform(std::make_tuple(5)));462}463464TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {465const Action<bool(bool, bool, bool)> a = ReturnArg<0>();466EXPECT_TRUE(a.Perform(std::make_tuple(true, false, false)));467}468469TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {470const Action<std::string(int, int, std::string, int)> a = ReturnArg<2>();471EXPECT_EQ("seven", a.Perform(std::make_tuple(5, 6, std::string("seven"), 8)));472}473474TEST(ReturnArgActionTest, WorksForNonConstRefArg0) {475const Action<std::string&(std::string&)> a = ReturnArg<0>();476std::string s = "12345";477EXPECT_EQ(&s, &a.Perform(std::forward_as_tuple(s)));478}479480TEST(SaveArgActionTest, WorksForSameType) {481int result = 0;482const Action<void(int n)> a1 = SaveArg<0>(&result);483a1.Perform(std::make_tuple(5));484EXPECT_EQ(5, result);485}486487TEST(SaveArgActionTest, WorksForCompatibleType) {488int result = 0;489const Action<void(bool, char)> a1 = SaveArg<1>(&result);490a1.Perform(std::make_tuple(true, 'a'));491EXPECT_EQ('a', result);492}493494TEST(SaveArgPointeeActionTest, WorksForSameType) {495int result = 0;496const int value = 5;497const Action<void(const int*)> a1 = SaveArgPointee<0>(&result);498a1.Perform(std::make_tuple(&value));499EXPECT_EQ(5, result);500}501502TEST(SaveArgPointeeActionTest, WorksForCompatibleType) {503int result = 0;504char value = 'a';505const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result);506a1.Perform(std::make_tuple(true, &value));507EXPECT_EQ('a', result);508}509510TEST(SetArgRefereeActionTest, WorksForSameType) {511int value = 0;512const Action<void(int&)> a1 = SetArgReferee<0>(1);513a1.Perform(std::tuple<int&>(value));514EXPECT_EQ(1, value);515}516517TEST(SetArgRefereeActionTest, WorksForCompatibleType) {518int value = 0;519const Action<void(int, int&)> a1 = SetArgReferee<1>('a');520a1.Perform(std::tuple<int, int&>(0, value));521EXPECT_EQ('a', value);522}523524TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {525int value = 0;526const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');527a1.Perform(std::tuple<bool, int, int&, const char*>(true, 0, value, "hi"));528EXPECT_EQ('a', value);529}530531// A class that can be used to verify that its destructor is called: it will set532// the bool provided to the constructor to true when destroyed.533class DeletionTester {534public:535explicit DeletionTester(bool* is_deleted) : is_deleted_(is_deleted) {536// Make sure the bit is set to false.537*is_deleted_ = false;538}539540~DeletionTester() { *is_deleted_ = true; }541542private:543bool* is_deleted_;544};545546TEST(DeleteArgActionTest, OneArg) {547bool is_deleted = false;548DeletionTester* t = new DeletionTester(&is_deleted);549const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT550EXPECT_FALSE(is_deleted);551a1.Perform(std::make_tuple(t));552EXPECT_TRUE(is_deleted);553}554555TEST(DeleteArgActionTest, TenArgs) {556bool is_deleted = false;557DeletionTester* t = new DeletionTester(&is_deleted);558const Action<void(bool, int, int, const char*, bool, int, int, int, int,559DeletionTester*)>560a1 = DeleteArg<9>();561EXPECT_FALSE(is_deleted);562a1.Perform(std::make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));563EXPECT_TRUE(is_deleted);564}565566#if GTEST_HAS_EXCEPTIONS567568TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {569const Action<void(int n)> a = Throw('a');570EXPECT_THROW(a.Perform(std::make_tuple(0)), char);571}572573class MyException {};574575TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {576const Action<double(char ch)> a = Throw(MyException());577EXPECT_THROW(a.Perform(std::make_tuple('0')), MyException);578}579580TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {581const Action<double()> a = Throw(MyException());582EXPECT_THROW(a.Perform(std::make_tuple()), MyException);583}584585class Object {586public:587virtual ~Object() {}588virtual void Func() {}589};590591class MockObject : public Object {592public:593~MockObject() override {}594MOCK_METHOD(void, Func, (), (override));595};596597TEST(ThrowActionTest, Times0) {598EXPECT_NONFATAL_FAILURE(599[] {600try {601MockObject m;602ON_CALL(m, Func()).WillByDefault([] { throw "something"; });603EXPECT_CALL(m, Func()).Times(0);604m.Func();605} catch (...) {606// Exception is caught but Times(0) still triggers a failure.607}608}(),609"");610}611612#endif // GTEST_HAS_EXCEPTIONS613614// Tests that SetArrayArgument<N>(first, last) sets the elements of the array615// pointed to by the N-th (0-based) argument to values in range [first, last).616TEST(SetArrayArgumentTest, SetsTheNthArray) {617using MyFunction = void(bool, int*, char*);618int numbers[] = {1, 2, 3};619Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);620621int n[4] = {};622int* pn = n;623char ch[4] = {};624char* pch = ch;625a.Perform(std::make_tuple(true, pn, pch));626EXPECT_EQ(1, n[0]);627EXPECT_EQ(2, n[1]);628EXPECT_EQ(3, n[2]);629EXPECT_EQ(0, n[3]);630EXPECT_EQ('\0', ch[0]);631EXPECT_EQ('\0', ch[1]);632EXPECT_EQ('\0', ch[2]);633EXPECT_EQ('\0', ch[3]);634635// Tests first and last are iterators.636std::string letters = "abc";637a = SetArrayArgument<2>(letters.begin(), letters.end());638std::fill_n(n, 4, 0);639std::fill_n(ch, 4, '\0');640a.Perform(std::make_tuple(true, pn, pch));641EXPECT_EQ(0, n[0]);642EXPECT_EQ(0, n[1]);643EXPECT_EQ(0, n[2]);644EXPECT_EQ(0, n[3]);645EXPECT_EQ('a', ch[0]);646EXPECT_EQ('b', ch[1]);647EXPECT_EQ('c', ch[2]);648EXPECT_EQ('\0', ch[3]);649}650651// Tests SetArrayArgument<N>(first, last) where first == last.652TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {653using MyFunction = void(bool, int*);654int numbers[] = {1, 2, 3};655Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);656657int n[4] = {};658int* pn = n;659a.Perform(std::make_tuple(true, pn));660EXPECT_EQ(0, n[0]);661EXPECT_EQ(0, n[1]);662EXPECT_EQ(0, n[2]);663EXPECT_EQ(0, n[3]);664}665666// Tests SetArrayArgument<N>(first, last) where *first is convertible667// (but not equal) to the argument type.668TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {669using MyFunction = void(bool, int*);670char chars[] = {97, 98, 99};671Action<MyFunction> a = SetArrayArgument<1>(chars, chars + 3);672673int codes[4] = {111, 222, 333, 444};674int* pcodes = codes;675a.Perform(std::make_tuple(true, pcodes));676EXPECT_EQ(97, codes[0]);677EXPECT_EQ(98, codes[1]);678EXPECT_EQ(99, codes[2]);679EXPECT_EQ(444, codes[3]);680}681682// Test SetArrayArgument<N>(first, last) with iterator as argument.683TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {684using MyFunction = void(bool, std::back_insert_iterator<std::string>);685std::string letters = "abc";686Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());687688std::string s;689a.Perform(std::make_tuple(true, std::back_inserter(s)));690EXPECT_EQ(letters, s);691}692693TEST(ReturnPointeeTest, Works) {694int n = 42;695const Action<int()> a = ReturnPointee(&n);696EXPECT_EQ(42, a.Perform(std::make_tuple()));697698n = 43;699EXPECT_EQ(43, a.Perform(std::make_tuple()));700}701702// Tests InvokeArgument<N>(...).703704// Tests using InvokeArgument with a nullary function.705TEST(InvokeArgumentTest, Function0) {706Action<int(int, int (*)())> a = InvokeArgument<1>(); // NOLINT707EXPECT_EQ(1, a.Perform(std::make_tuple(2, &Nullary)));708}709710// Tests using InvokeArgument with a unary functor.711TEST(InvokeArgumentTest, Functor1) {712Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT713EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryFunctor())));714}715716// Tests using InvokeArgument with a unary move-only functor.717TEST(InvokeArgumentTest, Functor1MoveOnly) {718Action<int(UnaryMoveOnlyFunctor)> a = InvokeArgument<0>(true); // NOLINT719EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryMoveOnlyFunctor())));720}721722// Tests using InvokeArgument with a one-shot unary functor.723TEST(InvokeArgumentTest, OneShotFunctor1) {724Action<int(OneShotUnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT725EXPECT_EQ(1, a.Perform(std::make_tuple(OneShotUnaryFunctor())));726}727728// Tests using InvokeArgument with a 5-ary function.729TEST(InvokeArgumentTest, Function5) {730Action<int(int (*)(int, int, int, int, int))> a = // NOLINT731InvokeArgument<0>(10000, 2000, 300, 40, 5);732EXPECT_EQ(12345, a.Perform(std::make_tuple(&SumOf5)));733}734735// Tests using InvokeArgument with a 5-ary functor.736TEST(InvokeArgumentTest, Functor5) {737Action<int(SumOf5Functor)> a = // NOLINT738InvokeArgument<0>(10000, 2000, 300, 40, 5);739EXPECT_EQ(12345, a.Perform(std::make_tuple(SumOf5Functor())));740}741742// Tests using InvokeArgument with a 6-ary function.743TEST(InvokeArgumentTest, Function6) {744Action<int(int (*)(int, int, int, int, int, int))> a = // NOLINT745InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);746EXPECT_EQ(123456, a.Perform(std::make_tuple(&SumOf6)));747}748749// Tests using InvokeArgument with a 6-ary functor.750TEST(InvokeArgumentTest, Functor6) {751Action<int(SumOf6Functor)> a = // NOLINT752InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);753EXPECT_EQ(123456, a.Perform(std::make_tuple(SumOf6Functor())));754}755756// Tests using InvokeArgument with a 7-ary function.757TEST(InvokeArgumentTest, Function7) {758Action<std::string(std::string(*)(const char*, const char*, const char*,759const char*, const char*, const char*,760const char*))>761a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");762EXPECT_EQ("1234567", a.Perform(std::make_tuple(&Concat7)));763}764765// Tests using InvokeArgument with a 8-ary function.766TEST(InvokeArgumentTest, Function8) {767Action<std::string(std::string(*)(const char*, const char*, const char*,768const char*, const char*, const char*,769const char*, const char*))>770a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");771EXPECT_EQ("12345678", a.Perform(std::make_tuple(&Concat8)));772}773774// Tests using InvokeArgument with a 9-ary function.775TEST(InvokeArgumentTest, Function9) {776Action<std::string(std::string(*)(const char*, const char*, const char*,777const char*, const char*, const char*,778const char*, const char*, const char*))>779a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");780EXPECT_EQ("123456789", a.Perform(std::make_tuple(&Concat9)));781}782783// Tests using InvokeArgument with a 10-ary function.784TEST(InvokeArgumentTest, Function10) {785Action<std::string(std::string(*)(786const char*, const char*, const char*, const char*, const char*,787const char*, const char*, const char*, const char*, const char*))>788a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");789EXPECT_EQ("1234567890", a.Perform(std::make_tuple(&Concat10)));790}791792// Tests using InvokeArgument with a function that takes a pointer argument.793TEST(InvokeArgumentTest, ByPointerFunction) {794Action<const char*(const char* (*)(const char* input, short n))> // NOLINT795a = InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));796EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));797}798799// Tests using InvokeArgument with a function that takes a const char*800// by passing it a C-string literal.801TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {802Action<const char*(const char* (*)(const char* input, short n))> // NOLINT803a = InvokeArgument<0>("Hi", Short(1));804EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));805}806807// Tests using InvokeArgument with a function that takes a const reference.808TEST(InvokeArgumentTest, ByConstReferenceFunction) {809Action<bool(bool (*function)(const std::string& s))> a = // NOLINT810InvokeArgument<0>(std::string("Hi"));811// When action 'a' is constructed, it makes a copy of the temporary812// string object passed to it, so it's OK to use 'a' later, when the813// temporary object has already died.814EXPECT_TRUE(a.Perform(std::make_tuple(&ByConstRef)));815}816817// Tests using InvokeArgument with ByRef() and a function that takes a818// const reference.819TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {820Action<bool(bool (*)(const double& x))> a = // NOLINT821InvokeArgument<0>(ByRef(g_double));822// The above line calls ByRef() on a const value.823EXPECT_TRUE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));824825double x = 0;826a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const.827EXPECT_FALSE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));828}829830TEST(InvokeArgumentTest, MoveOnlyType) {831struct Marker {};832struct {833// Method takes a unique_ptr (to a type we don't care about), and an834// invocable type.835MOCK_METHOD(bool, MockMethod,836(std::unique_ptr<Marker>, std::function<int()>), ());837} mock;838839ON_CALL(mock, MockMethod(_, _)).WillByDefault(InvokeArgument<1>());840841// This compiles, but is a little opaque as a workaround:842ON_CALL(mock, MockMethod(_, _))843.WillByDefault(WithArg<1>(InvokeArgument<0>()));844}845846// Tests DoAll(a1, a2).847TEST(DoAllTest, TwoActions) {848int n = 0;849Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT850Return(2));851EXPECT_EQ(2, a.Perform(std::make_tuple(&n)));852EXPECT_EQ(1, n);853}854855// Tests DoAll(a1, a2, a3).856TEST(DoAllTest, ThreeActions) {857int m = 0, n = 0;858Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT859SetArgPointee<1>(2), Return(3));860EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n)));861EXPECT_EQ(1, m);862EXPECT_EQ(2, n);863}864865// Tests DoAll(a1, a2, a3, a4).866TEST(DoAllTest, FourActions) {867int m = 0, n = 0;868char ch = '\0';869Action<int(int*, int*, char*)> a = // NOLINT870DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),871Return(3));872EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n, &ch)));873EXPECT_EQ(1, m);874EXPECT_EQ(2, n);875EXPECT_EQ('a', ch);876}877878// Tests DoAll(a1, a2, a3, a4, a5).879TEST(DoAllTest, FiveActions) {880int m = 0, n = 0;881char a = '\0', b = '\0';882Action<int(int*, int*, char*, char*)> action = // NOLINT883DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),884SetArgPointee<3>('b'), Return(3));885EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b)));886EXPECT_EQ(1, m);887EXPECT_EQ(2, n);888EXPECT_EQ('a', a);889EXPECT_EQ('b', b);890}891892// Tests DoAll(a1, a2, ..., a6).893TEST(DoAllTest, SixActions) {894int m = 0, n = 0;895char a = '\0', b = '\0', c = '\0';896Action<int(int*, int*, char*, char*, char*)> action = // NOLINT897DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),898SetArgPointee<3>('b'), SetArgPointee<4>('c'), Return(3));899EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c)));900EXPECT_EQ(1, m);901EXPECT_EQ(2, n);902EXPECT_EQ('a', a);903EXPECT_EQ('b', b);904EXPECT_EQ('c', c);905}906907// Tests DoAll(a1, a2, ..., a7).908TEST(DoAllTest, SevenActions) {909int m = 0, n = 0;910char a = '\0', b = '\0', c = '\0', d = '\0';911Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT912DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),913SetArgPointee<3>('b'), SetArgPointee<4>('c'), SetArgPointee<5>('d'),914Return(3));915EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d)));916EXPECT_EQ(1, m);917EXPECT_EQ(2, n);918EXPECT_EQ('a', a);919EXPECT_EQ('b', b);920EXPECT_EQ('c', c);921EXPECT_EQ('d', d);922}923924// Tests DoAll(a1, a2, ..., a8).925TEST(DoAllTest, EightActions) {926int m = 0, n = 0;927char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';928Action<int(int*, int*, char*, char*, char*, char*, // NOLINT929char*)>930action =931DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),932SetArgPointee<3>('b'), SetArgPointee<4>('c'),933SetArgPointee<5>('d'), SetArgPointee<6>('e'), Return(3));934EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e)));935EXPECT_EQ(1, m);936EXPECT_EQ(2, n);937EXPECT_EQ('a', a);938EXPECT_EQ('b', b);939EXPECT_EQ('c', c);940EXPECT_EQ('d', d);941EXPECT_EQ('e', e);942}943944// Tests DoAll(a1, a2, ..., a9).945TEST(DoAllTest, NineActions) {946int m = 0, n = 0;947char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';948Action<int(int*, int*, char*, char*, char*, char*, // NOLINT949char*, char*)>950action = DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2),951SetArgPointee<2>('a'), SetArgPointee<3>('b'),952SetArgPointee<4>('c'), SetArgPointee<5>('d'),953SetArgPointee<6>('e'), SetArgPointee<7>('f'), Return(3));954EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));955EXPECT_EQ(1, m);956EXPECT_EQ(2, n);957EXPECT_EQ('a', a);958EXPECT_EQ('b', b);959EXPECT_EQ('c', c);960EXPECT_EQ('d', d);961EXPECT_EQ('e', e);962EXPECT_EQ('f', f);963}964965// Tests DoAll(a1, a2, ..., a10).966TEST(DoAllTest, TenActions) {967int m = 0, n = 0;968char a = '\0', b = '\0', c = '\0', d = '\0';969char e = '\0', f = '\0', g = '\0';970Action<int(int*, int*, char*, char*, char*, char*, // NOLINT971char*, char*, char*)>972action =973DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),974SetArgPointee<3>('b'), SetArgPointee<4>('c'),975SetArgPointee<5>('d'), SetArgPointee<6>('e'),976SetArgPointee<7>('f'), SetArgPointee<8>('g'), Return(3));977EXPECT_EQ(9783, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));979EXPECT_EQ(1, m);980EXPECT_EQ(2, n);981EXPECT_EQ('a', a);982EXPECT_EQ('b', b);983EXPECT_EQ('c', c);984EXPECT_EQ('d', d);985EXPECT_EQ('e', e);986EXPECT_EQ('f', f);987EXPECT_EQ('g', g);988}989990TEST(DoAllTest, NoArgs) {991bool ran_first = false;992Action<bool()> a =993DoAll([&] { ran_first = true; }, [&] { return ran_first; });994EXPECT_TRUE(a.Perform({}));995}996997TEST(DoAllTest, MoveOnlyArgs) {998bool ran_first = false;999Action<int(std::unique_ptr<int>)> a =1000DoAll(InvokeWithoutArgs([&] { ran_first = true; }),1001[](std::unique_ptr<int> p) { return *p; });1002EXPECT_EQ(7, a.Perform(std::make_tuple(std::unique_ptr<int>(new int(7)))));1003EXPECT_TRUE(ran_first);1004}10051006TEST(DoAllTest, ImplicitlyConvertsActionArguments) {1007bool ran_first = false;1008// Action<void(std::vector<int>)> isn't an1009// Action<void(const std::vector<int>&) but can be converted.1010Action<void(std::vector<int>)> first = [&] { ran_first = true; };1011Action<int(std::vector<int>)> a =1012DoAll(first, [](std::vector<int> arg) { return arg.front(); });1013EXPECT_EQ(7, a.Perform(std::make_tuple(std::vector<int>{7})));1014EXPECT_TRUE(ran_first);1015}10161017// The ACTION*() macros trigger warning C4100 (unreferenced formal1018// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in1019// the macro definition, as the warnings are generated when the macro1020// is expanded and macro expansion cannot contain #pragma. Therefore1021// we suppress them here.1022// Also suppress C4503 decorated name length exceeded, name was truncated1023GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503)1024// Tests the ACTION*() macro family.10251026// Tests that ACTION() can define an action that doesn't reference the1027// mock function arguments.1028ACTION(Return5) { return 5; }10291030TEST(ActionMacroTest, WorksWhenNotReferencingArguments) {1031Action<double()> a1 = Return5();1032EXPECT_DOUBLE_EQ(5, a1.Perform(std::make_tuple()));10331034Action<int(double, bool)> a2 = Return5();1035EXPECT_EQ(5, a2.Perform(std::make_tuple(1, true)));1036}10371038// Tests that ACTION() can define an action that returns void.1039ACTION(IncrementArg1) { (*arg1)++; }10401041TEST(ActionMacroTest, WorksWhenReturningVoid) {1042Action<void(int, int*)> a1 = IncrementArg1();1043int n = 0;1044a1.Perform(std::make_tuple(5, &n));1045EXPECT_EQ(1, n);1046}10471048// Tests that the body of ACTION() can reference the type of the1049// argument.1050ACTION(IncrementArg2) {1051StaticAssertTypeEq<int*, arg2_type>();1052arg2_type temp = arg2;1053(*temp)++;1054}10551056TEST(ActionMacroTest, CanReferenceArgumentType) {1057Action<void(int, bool, int*)> a1 = IncrementArg2();1058int n = 0;1059a1.Perform(std::make_tuple(5, false, &n));1060EXPECT_EQ(1, n);1061}10621063// Tests that the body of ACTION() can reference the argument tuple1064// via args_type and args.1065ACTION(Sum2) {1066StaticAssertTypeEq<std::tuple<int, char, int*>, args_type>();1067args_type args_copy = args;1068return std::get<0>(args_copy) + std::get<1>(args_copy);1069}10701071TEST(ActionMacroTest, CanReferenceArgumentTuple) {1072Action<int(int, char, int*)> a1 = Sum2();1073int dummy = 0;1074EXPECT_EQ(11, a1.Perform(std::make_tuple(5, Char(6), &dummy)));1075}10761077namespace {10781079// Tests that the body of ACTION() can reference the mock function1080// type.1081int Dummy(bool flag) { return flag ? 1 : 0; }10821083} // namespace10841085ACTION(InvokeDummy) {1086StaticAssertTypeEq<int(bool), function_type>();1087function_type* fp = &Dummy;1088return (*fp)(true);1089}10901091TEST(ActionMacroTest, CanReferenceMockFunctionType) {1092Action<int(bool)> a1 = InvokeDummy();1093EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));1094EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));1095}10961097// Tests that the body of ACTION() can reference the mock function's1098// return type.1099ACTION(InvokeDummy2) {1100StaticAssertTypeEq<int, return_type>();1101return_type result = Dummy(true);1102return result;1103}11041105TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {1106Action<int(bool)> a1 = InvokeDummy2();1107EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));1108EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));1109}11101111// Tests that ACTION() works for arguments passed by const reference.1112ACTION(ReturnAddrOfConstBoolReferenceArg) {1113StaticAssertTypeEq<const bool&, arg1_type>();1114return &arg1;1115}11161117TEST(ActionMacroTest, WorksForConstReferenceArg) {1118Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();1119const bool b = false;1120EXPECT_EQ(&b, a.Perform(std::tuple<int, const bool&>(0, b)));1121}11221123// Tests that ACTION() works for arguments passed by non-const reference.1124ACTION(ReturnAddrOfIntReferenceArg) {1125StaticAssertTypeEq<int&, arg0_type>();1126return &arg0;1127}11281129TEST(ActionMacroTest, WorksForNonConstReferenceArg) {1130Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();1131int n = 0;1132EXPECT_EQ(&n, a.Perform(std::tuple<int&, bool, int>(n, true, 1)));1133}11341135// Tests that ACTION() can be used in a namespace.1136namespace action_test {1137ACTION(Sum) { return arg0 + arg1; }1138} // namespace action_test11391140TEST(ActionMacroTest, WorksInNamespace) {1141Action<int(int, int)> a1 = action_test::Sum();1142EXPECT_EQ(3, a1.Perform(std::make_tuple(1, 2)));1143}11441145// Tests that the same ACTION definition works for mock functions with1146// different argument numbers.1147ACTION(PlusTwo) { return arg0 + 2; }11481149TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {1150Action<int(int)> a1 = PlusTwo();1151EXPECT_EQ(4, a1.Perform(std::make_tuple(2)));11521153Action<double(float, void*)> a2 = PlusTwo();1154int dummy;1155EXPECT_DOUBLE_EQ(6, a2.Perform(std::make_tuple(4.0f, &dummy)));1156}11571158// Tests that ACTION_P can define a parameterized action.1159ACTION_P(Plus, n) { return arg0 + n; }11601161TEST(ActionPMacroTest, DefinesParameterizedAction) {1162Action<int(int m, bool t)> a1 = Plus(9);1163EXPECT_EQ(10, a1.Perform(std::make_tuple(1, true)));1164}11651166// Tests that the body of ACTION_P can reference the argument types1167// and the parameter type.1168ACTION_P(TypedPlus, n) {1169arg0_type t1 = arg0;1170n_type t2 = n;1171return t1 + t2;1172}11731174TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {1175Action<int(char m, bool t)> a1 = TypedPlus(9);1176EXPECT_EQ(10, a1.Perform(std::make_tuple(Char(1), true)));1177}11781179// Tests that a parameterized action can be used in any mock function1180// whose type is compatible.1181TEST(ActionPMacroTest, WorksInCompatibleMockFunction) {1182Action<std::string(const std::string& s)> a1 = Plus("tail");1183const std::string re = "re";1184std::tuple<const std::string> dummy = std::make_tuple(re);1185EXPECT_EQ("retail", a1.Perform(dummy));1186}11871188// Tests that we can use ACTION*() to define actions overloaded on the1189// number of parameters.11901191ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }11921193ACTION_P(OverloadedAction, default_value) {1194return arg0 ? arg1 : default_value;1195}11961197ACTION_P2(OverloadedAction, true_value, false_value) {1198return arg0 ? true_value : false_value;1199}12001201TEST(ActionMacroTest, CanDefineOverloadedActions) {1202using MyAction = Action<const char*(bool, const char*)>;12031204const MyAction a1 = OverloadedAction();1205EXPECT_STREQ("hello", a1.Perform(std::make_tuple(false, CharPtr("world"))));1206EXPECT_STREQ("world", a1.Perform(std::make_tuple(true, CharPtr("world"))));12071208const MyAction a2 = OverloadedAction("hi");1209EXPECT_STREQ("hi", a2.Perform(std::make_tuple(false, CharPtr("world"))));1210EXPECT_STREQ("world", a2.Perform(std::make_tuple(true, CharPtr("world"))));12111212const MyAction a3 = OverloadedAction("hi", "you");1213EXPECT_STREQ("hi", a3.Perform(std::make_tuple(true, CharPtr("world"))));1214EXPECT_STREQ("you", a3.Perform(std::make_tuple(false, CharPtr("world"))));1215}12161217// Tests ACTION_Pn where n >= 3.12181219ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }12201221TEST(ActionPnMacroTest, WorksFor3Parameters) {1222Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);1223EXPECT_DOUBLE_EQ(3123.4, a1.Perform(std::make_tuple(3000, true)));12241225Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");1226const std::string re = "re";1227std::tuple<const std::string> dummy = std::make_tuple(re);1228EXPECT_EQ("retail->", a2.Perform(dummy));1229}12301231ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }12321233TEST(ActionPnMacroTest, WorksFor4Parameters) {1234Action<int(int)> a1 = Plus(1, 2, 3, 4);1235EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(std::make_tuple(10)));1236}12371238ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }12391240TEST(ActionPnMacroTest, WorksFor5Parameters) {1241Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);1242EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(std::make_tuple(10)));1243}12441245ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {1246return arg0 + p0 + p1 + p2 + p3 + p4 + p5;1247}12481249TEST(ActionPnMacroTest, WorksFor6Parameters) {1250Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);1251EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(std::make_tuple(10)));1252}12531254ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {1255return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;1256}12571258TEST(ActionPnMacroTest, WorksFor7Parameters) {1259Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);1260EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(std::make_tuple(10)));1261}12621263ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {1264return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;1265}12661267TEST(ActionPnMacroTest, WorksFor8Parameters) {1268Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);1269EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,1270a1.Perform(std::make_tuple(10)));1271}12721273ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {1274return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;1275}12761277TEST(ActionPnMacroTest, WorksFor9Parameters) {1278Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);1279EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9,1280a1.Perform(std::make_tuple(10)));1281}12821283ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {1284arg0_type t0 = arg0;1285last_param_type t9 = last_param;1286return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;1287}12881289TEST(ActionPnMacroTest, WorksFor10Parameters) {1290Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);1291EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,1292a1.Perform(std::make_tuple(10)));1293}12941295// Tests that the action body can promote the parameter types.12961297ACTION_P2(PadArgument, prefix, suffix) {1298// The following lines promote the two parameters to desired types.1299std::string prefix_str(prefix);1300char suffix_char = static_cast<char>(suffix);1301return prefix_str + arg0 + suffix_char;1302}13031304TEST(ActionPnMacroTest, SimpleTypePromotion) {1305Action<std::string(const char*)> no_promo =1306PadArgument(std::string("foo"), 'r');1307Action<std::string(const char*)> promo =1308PadArgument("foo", static_cast<int>('r'));1309EXPECT_EQ("foobar", no_promo.Perform(std::make_tuple(CharPtr("ba"))));1310EXPECT_EQ("foobar", promo.Perform(std::make_tuple(CharPtr("ba"))));1311}13121313// Tests that we can partially restrict parameter types using a1314// straight-forward pattern.13151316// Defines a generic action that doesn't restrict the types of its1317// parameters.1318ACTION_P3(ConcatImpl, a, b, c) {1319std::stringstream ss;1320ss << a << b << c;1321return ss.str();1322}13231324// Next, we try to restrict that either the first parameter is a1325// string, or the second parameter is an int.13261327// Defines a partially specialized wrapper that restricts the first1328// parameter to std::string.1329template <typename T1, typename T2>1330// ConcatImplActionP3 is the class template ACTION_P3 uses to1331// implement ConcatImpl. We shouldn't change the name as this1332// pattern requires the user to use it directly.1333ConcatImplActionP3<std::string, T1, T2> Concat(const std::string& a, T1 b,1334T2 c) {1335GTEST_INTENTIONAL_CONST_COND_PUSH_()1336if (true) {1337GTEST_INTENTIONAL_CONST_COND_POP_()1338// This branch verifies that ConcatImpl() can be invoked without1339// explicit template arguments.1340return ConcatImpl(a, b, c);1341} else {1342// This branch verifies that ConcatImpl() can also be invoked with1343// explicit template arguments. It doesn't really need to be1344// executed as this is a compile-time verification.1345return ConcatImpl<std::string, T1, T2>(a, b, c);1346}1347}13481349// Defines another partially specialized wrapper that restricts the1350// second parameter to int.1351template <typename T1, typename T2>1352ConcatImplActionP3<T1, int, T2> Concat(T1 a, int b, T2 c) {1353return ConcatImpl(a, b, c);1354}13551356TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {1357Action<const std::string()> a1 = Concat("Hello", "1", 2);1358EXPECT_EQ("Hello12", a1.Perform(std::make_tuple()));13591360a1 = Concat(1, 2, 3);1361EXPECT_EQ("123", a1.Perform(std::make_tuple()));1362}13631364// Verifies the type of an ACTION*.13651366ACTION(DoFoo) {}1367ACTION_P(DoFoo, p) {}1368ACTION_P2(DoFoo, p0, p1) {}13691370TEST(ActionPnMacroTest, TypesAreCorrect) {1371// DoFoo() must be assignable to a DoFooAction variable.1372DoFooAction a0 = DoFoo();13731374// DoFoo(1) must be assignable to a DoFooActionP variable.1375DoFooActionP<int> a1 = DoFoo(1);13761377// DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk1378// variable, and so on.1379DoFooActionP2<int, char> a2 = DoFoo(1, '2');1380PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');1381PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');1382PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');1383PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');1384PlusActionP7<int, int, int, int, int, int, char> a7 =1385Plus(1, 2, 3, 4, 5, 6, '7');1386PlusActionP8<int, int, int, int, int, int, int, char> a8 =1387Plus(1, 2, 3, 4, 5, 6, 7, '8');1388PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =1389Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');1390PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =1391Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');13921393// Avoid "unused variable" warnings.1394(void)a0;1395(void)a1;1396(void)a2;1397(void)a3;1398(void)a4;1399(void)a5;1400(void)a6;1401(void)a7;1402(void)a8;1403(void)a9;1404(void)a10;1405}14061407// Tests that an ACTION_P*() action can be explicitly instantiated1408// with reference-typed parameters.14091410ACTION_P(Plus1, x) { return x; }1411ACTION_P2(Plus2, x, y) { return x + y; }1412ACTION_P3(Plus3, x, y, z) { return x + y + z; }1413ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {1414return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;1415}14161417TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {1418int x = 1, y = 2, z = 3;1419const std::tuple<> empty = std::make_tuple();14201421Action<int()> a = Plus1<int&>(x);1422EXPECT_EQ(1, a.Perform(empty));14231424a = Plus2<const int&, int&>(x, y);1425EXPECT_EQ(3, a.Perform(empty));14261427a = Plus3<int&, const int&, int&>(x, y, z);1428EXPECT_EQ(6, a.Perform(empty));14291430int n[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};1431a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,1432int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6],1433n[7], n[8], n[9]);1434EXPECT_EQ(55, a.Perform(empty));1435}14361437class TenArgConstructorClass {1438public:1439TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7,1440int a8, int a9, int a10)1441: value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {}1442int value_;1443};14441445// Tests that ACTION_TEMPLATE works when there is no value parameter.1446ACTION_TEMPLATE(CreateNew, HAS_1_TEMPLATE_PARAMS(typename, T),1447AND_0_VALUE_PARAMS()) {1448return new T;1449}14501451TEST(ActionTemplateTest, WorksWithoutValueParam) {1452const Action<int*()> a = CreateNew<int>();1453int* p = a.Perform(std::make_tuple());1454delete p;1455}14561457// Tests that ACTION_TEMPLATE works when there are value parameters.1458ACTION_TEMPLATE(CreateNew, HAS_1_TEMPLATE_PARAMS(typename, T),1459AND_1_VALUE_PARAMS(a0)) {1460return new T(a0);1461}14621463TEST(ActionTemplateTest, WorksWithValueParams) {1464const Action<int*()> a = CreateNew<int>(42);1465int* p = a.Perform(std::make_tuple());1466EXPECT_EQ(42, *p);1467delete p;1468}14691470// Tests that ACTION_TEMPLATE works for integral template parameters.1471ACTION_TEMPLATE(MyDeleteArg, HAS_1_TEMPLATE_PARAMS(int, k),1472AND_0_VALUE_PARAMS()) {1473delete std::get<k>(args);1474}14751476// Resets a bool variable in the destructor.1477class BoolResetter {1478public:1479explicit BoolResetter(bool* value) : value_(value) {}1480~BoolResetter() { *value_ = false; }14811482private:1483bool* value_;1484};14851486TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {1487const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();1488int n = 0;1489bool b = true;1490auto* resetter = new BoolResetter(&b);1491a.Perform(std::make_tuple(&n, resetter));1492EXPECT_FALSE(b); // Verifies that resetter is deleted.1493}14941495// Tests that ACTION_TEMPLATES works for template template parameters.1496ACTION_TEMPLATE(ReturnSmartPointer,1497HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,1498Pointer),1499AND_1_VALUE_PARAMS(pointee)) {1500return Pointer<pointee_type>(new pointee_type(pointee));1501}15021503TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {1504const Action<std::shared_ptr<int>()> a =1505ReturnSmartPointer<std::shared_ptr>(42);1506std::shared_ptr<int> p = a.Perform(std::make_tuple());1507EXPECT_EQ(42, *p);1508}15091510// Tests that ACTION_TEMPLATE works for 10 template parameters.1511template <typename T1, typename T2, typename T3, int k4, bool k5,1512unsigned int k6, typename T7, typename T8, typename T9>1513struct GiantTemplate {1514public:1515explicit GiantTemplate(int a_value) : value(a_value) {}1516int value;1517};15181519ACTION_TEMPLATE(ReturnGiant,1520HAS_10_TEMPLATE_PARAMS(typename, T1, typename, T2, typename, T3,1521int, k4, bool, k5, unsigned int, k6,1522class, T7, class, T8, class, T9,1523template <typename T> class, T10),1524AND_1_VALUE_PARAMS(value)) {1525return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);1526}15271528TEST(ActionTemplateTest, WorksFor10TemplateParameters) {1529using Giant = GiantTemplate<std::shared_ptr<int>, bool, double, 5, true, 6,1530char, unsigned, int>;1531const Action<Giant()> a = ReturnGiant<int, bool, double, 5, true, 6, char,1532unsigned, int, std::shared_ptr>(42);1533Giant giant = a.Perform(std::make_tuple());1534EXPECT_EQ(42, giant.value);1535}15361537// Tests that ACTION_TEMPLATE works for 10 value parameters.1538ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),1539AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {1540return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;1541}15421543TEST(ActionTemplateTest, WorksFor10ValueParameters) {1544const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);1545EXPECT_EQ(55, a.Perform(std::make_tuple()));1546}15471548// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded1549// on the number of value parameters.15501551ACTION(ReturnSum) { return 0; }15521553ACTION_P(ReturnSum, x) { return x; }15541555ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),1556AND_2_VALUE_PARAMS(v1, v2)) {1557return static_cast<Number>(v1) + v2;1558}15591560ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),1561AND_3_VALUE_PARAMS(v1, v2, v3)) {1562return static_cast<Number>(v1) + v2 + v3;1563}15641565ACTION_TEMPLATE(ReturnSum, HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),1566AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {1567return static_cast<Number>(v1) + v2 + v3 + v4 + k;1568}15691570TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {1571const Action<int()> a0 = ReturnSum();1572const Action<int()> a1 = ReturnSum(1);1573const Action<int()> a2 = ReturnSum<int>(1, 2);1574const Action<int()> a3 = ReturnSum<int>(1, 2, 3);1575const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);1576EXPECT_EQ(0, a0.Perform(std::make_tuple()));1577EXPECT_EQ(1, a1.Perform(std::make_tuple()));1578EXPECT_EQ(3, a2.Perform(std::make_tuple()));1579EXPECT_EQ(6, a3.Perform(std::make_tuple()));1580EXPECT_EQ(12345, a4.Perform(std::make_tuple()));1581}15821583} // namespace gmock_more_actions_test1584} // namespace testing15851586GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 45031587GTEST_DISABLE_MSC_WARNINGS_POP_() // 4577158815891590