Path: blob/main/contrib/googletest/googlemock/test/gmock-more-actions_test.cc
110032 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::SaveArgByMove;62using testing::SaveArgPointee;63using testing::SetArgReferee;64using testing::Unused;65using testing::WithArg;66using testing::WithoutArgs;6768// For suppressing compiler warnings on conversion possibly losing precision.69inline short Short(short n) { return n; } // NOLINT70inline char Char(char ch) { return ch; }7172// Sample functions and functors for testing Invoke() and etc.73int Nullary() { return 1; }7475bool g_done = false;7677bool Unary(int x) { return x < 0; }7879bool ByConstRef(const std::string& s) { return s == "Hi"; }8081const double g_double = 0;82bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }8384struct UnaryFunctor {85int operator()(bool x) { return x ? 1 : -1; }86};8788struct UnaryMoveOnlyFunctor : UnaryFunctor {89UnaryMoveOnlyFunctor() = default;90UnaryMoveOnlyFunctor(const UnaryMoveOnlyFunctor&) = delete;91UnaryMoveOnlyFunctor(UnaryMoveOnlyFunctor&&) = default;92};9394struct OneShotUnaryFunctor {95int operator()(bool x) && { return x ? 1 : -1; }96};9798const char* Binary(const char* input, short n) { return input + n; } // NOLINT99100int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT101102int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }103104int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }105106int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }107108struct SumOf5Functor {109int operator()(int a, int b, int c, int d, int e) {110return a + b + c + d + e;111}112};113114int SumOf6(int a, int b, int c, int d, int e, int f) {115return a + b + c + d + e + f;116}117118struct SumOf6Functor {119int operator()(int a, int b, int c, int d, int e, int f) {120return a + b + c + d + e + f;121}122};123124std::string Concat7(const char* s1, const char* s2, const char* s3,125const char* s4, const char* s5, const char* s6,126const char* s7) {127return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7;128}129130std::string Concat8(const char* s1, const char* s2, const char* s3,131const char* s4, const char* s5, const char* s6,132const char* s7, const char* s8) {133return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;134}135136std::string Concat9(const char* s1, const char* s2, const char* s3,137const char* s4, const char* s5, const char* s6,138const char* s7, const char* s8, const char* s9) {139return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;140}141142std::string Concat10(const char* s1, const char* s2, const char* s3,143const char* s4, const char* s5, const char* s6,144const char* s7, const char* s8, const char* s9,145const char* s10) {146return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;147}148149class Foo {150public:151Foo() : value_(123) {}152153int Nullary() const { return value_; }154155short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT156157std::string Binary(const std::string& str, char c) const { return str + c; }158159int Ternary(int x, bool y, char z) { return value_ + x + y * z; }160161int SumOf4(int a, int b, int c, int d) const {162return a + b + c + d + value_;163}164165int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }166167int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }168169int SumOf6(int a, int b, int c, int d, int e, int f) {170return a + b + c + d + e + f;171}172173std::string Concat7(const char* s1, const char* s2, const char* s3,174const char* s4, const char* s5, const char* s6,175const char* s7) {176return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7;177}178179std::string Concat8(const char* s1, const char* s2, const char* s3,180const char* s4, const char* s5, const char* s6,181const char* s7, const char* s8) {182return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;183}184185std::string Concat9(const char* s1, const char* s2, const char* s3,186const char* s4, const char* s5, const char* s6,187const char* s7, const char* s8, const char* s9) {188return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;189}190191std::string Concat10(const char* s1, const char* s2, const char* s3,192const char* s4, const char* s5, const char* s6,193const char* s7, const char* s8, const char* s9,194const char* s10) {195return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;196}197198private:199int value_;200};201202// Tests using Invoke() with a nullary function.203TEST(InvokeTest, Nullary) {204Action<int()> a = Invoke(Nullary); // NOLINT205EXPECT_EQ(1, a.Perform(std::make_tuple()));206}207208// Tests using Invoke() with a unary function.209TEST(InvokeTest, Unary) {210Action<bool(int)> a = Invoke(Unary); // NOLINT211EXPECT_FALSE(a.Perform(std::make_tuple(1)));212EXPECT_TRUE(a.Perform(std::make_tuple(-1)));213}214215// Tests using Invoke() with a binary function.216TEST(InvokeTest, Binary) {217Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT218const char* p = "Hello";219EXPECT_EQ(p + 2, a.Perform(std::make_tuple(p, Short(2))));220}221222// Tests using Invoke() with a ternary function.223TEST(InvokeTest, Ternary) {224Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT225EXPECT_EQ(6, a.Perform(std::make_tuple(1, '\2', Short(3))));226}227228// Tests using Invoke() with a 4-argument function.229TEST(InvokeTest, FunctionThatTakes4Arguments) {230Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT231EXPECT_EQ(1234, a.Perform(std::make_tuple(1000, 200, 30, 4)));232}233234// Tests using Invoke() with a 5-argument function.235TEST(InvokeTest, FunctionThatTakes5Arguments) {236Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT237EXPECT_EQ(12345, a.Perform(std::make_tuple(10000, 2000, 300, 40, 5)));238}239240// Tests using Invoke() with a 6-argument function.241TEST(InvokeTest, FunctionThatTakes6Arguments) {242Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT243EXPECT_EQ(123456,244a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6)));245}246247// A helper that turns the type of a C-string literal from const248// char[N] to const char*.249inline const char* CharPtr(const char* s) { return s; }250251// Tests using Invoke() with a 7-argument function.252TEST(InvokeTest, FunctionThatTakes7Arguments) {253Action<std::string(const char*, const char*, const char*, const char*,254const char*, const char*, const char*)>255a = Invoke(Concat7);256EXPECT_EQ("1234567",257a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),258CharPtr("4"), CharPtr("5"), CharPtr("6"),259CharPtr("7"))));260}261262// Tests using Invoke() with a 8-argument function.263TEST(InvokeTest, FunctionThatTakes8Arguments) {264Action<std::string(const char*, const char*, const char*, const char*,265const char*, const char*, const char*, const char*)>266a = Invoke(Concat8);267EXPECT_EQ("12345678",268a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),269CharPtr("4"), CharPtr("5"), CharPtr("6"),270CharPtr("7"), CharPtr("8"))));271}272273// Tests using Invoke() with a 9-argument function.274TEST(InvokeTest, FunctionThatTakes9Arguments) {275Action<std::string(const char*, const char*, const char*, const char*,276const char*, const char*, const char*, const char*,277const char*)>278a = Invoke(Concat9);279EXPECT_EQ("123456789", a.Perform(std::make_tuple(280CharPtr("1"), CharPtr("2"), CharPtr("3"),281CharPtr("4"), CharPtr("5"), CharPtr("6"),282CharPtr("7"), CharPtr("8"), CharPtr("9"))));283}284285// Tests using Invoke() with a 10-argument function.286TEST(InvokeTest, FunctionThatTakes10Arguments) {287Action<std::string(const char*, const char*, const char*, const char*,288const char*, const char*, const char*, const char*,289const char*, const char*)>290a = Invoke(Concat10);291EXPECT_EQ("1234567890",292a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),293CharPtr("4"), CharPtr("5"), CharPtr("6"),294CharPtr("7"), CharPtr("8"), CharPtr("9"),295CharPtr("0"))));296}297298// Tests using Invoke() with functions with parameters declared as Unused.299TEST(InvokeTest, FunctionWithUnusedParameters) {300Action<int(int, int, double, const std::string&)> a1 = Invoke(SumOfFirst2);301std::tuple<int, int, double, std::string> dummy =302std::make_tuple(10, 2, 5.6, std::string("hi"));303EXPECT_EQ(12, a1.Perform(dummy));304305Action<int(int, int, bool, int*)> a2 = Invoke(SumOfFirst2);306EXPECT_EQ(30723, a2.Perform(std::make_tuple(20, 3, true, static_cast<int*>(nullptr))));308}309310// Tests using Invoke() with methods with parameters declared as Unused.311TEST(InvokeTest, MethodWithUnusedParameters) {312Foo foo;313Action<int(std::string, bool, int, int)> a1 = Invoke(&foo, &Foo::SumOfLast2);314EXPECT_EQ(12, a1.Perform(std::make_tuple(CharPtr("hi"), true, 10, 2)));315316Action<int(char, double, int, int)> a2 = Invoke(&foo, &Foo::SumOfLast2);317EXPECT_EQ(23, a2.Perform(std::make_tuple('a', 2.5, 20, 3)));318}319320// Tests using Invoke() with a functor.321TEST(InvokeTest, Functor) {322Action<long(long, int)> a = Invoke(plus<long>()); // NOLINT323EXPECT_EQ(3L, a.Perform(std::make_tuple(1, 2)));324}325326// Tests using Invoke(f) as an action of a compatible type.327TEST(InvokeTest, FunctionWithCompatibleType) {328Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT329EXPECT_EQ(4321, a.Perform(std::make_tuple(4000, Short(300), Char(20), true)));330}331332// Tests using Invoke() with an object pointer and a method pointer.333334// Tests using Invoke() with a nullary method.335TEST(InvokeMethodTest, Nullary) {336Foo foo;337Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT338EXPECT_EQ(123, a.Perform(std::make_tuple()));339}340341// Tests using Invoke() with a unary method.342TEST(InvokeMethodTest, Unary) {343Foo foo;344Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT345EXPECT_EQ(4123, a.Perform(std::make_tuple(4000)));346}347348// Tests using Invoke() with a binary method.349TEST(InvokeMethodTest, Binary) {350Foo foo;351Action<std::string(const std::string&, char)> a = Invoke(&foo, &Foo::Binary);352std::string s("Hell");353std::tuple<std::string, char> dummy = std::make_tuple(s, 'o');354EXPECT_EQ("Hello", a.Perform(dummy));355}356357// Tests using Invoke() with a ternary method.358TEST(InvokeMethodTest, Ternary) {359Foo foo;360Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT361EXPECT_EQ(1124, a.Perform(std::make_tuple(1000, true, Char(1))));362}363364// Tests using Invoke() with a 4-argument method.365TEST(InvokeMethodTest, MethodThatTakes4Arguments) {366Foo foo;367Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT368EXPECT_EQ(1357, a.Perform(std::make_tuple(1000, 200, 30, 4)));369}370371// Tests using Invoke() with a 5-argument method.372TEST(InvokeMethodTest, MethodThatTakes5Arguments) {373Foo foo;374Action<int(int, int, int, int, int)> a =375Invoke(&foo, &Foo::SumOf5); // NOLINT376EXPECT_EQ(12345, a.Perform(std::make_tuple(10000, 2000, 300, 40, 5)));377}378379// Tests using Invoke() with a 6-argument method.380TEST(InvokeMethodTest, MethodThatTakes6Arguments) {381Foo foo;382Action<int(int, int, int, int, int, int)> a = // NOLINT383Invoke(&foo, &Foo::SumOf6);384EXPECT_EQ(123456,385a.Perform(std::make_tuple(100000, 20000, 3000, 400, 50, 6)));386}387388// Tests using Invoke() with a 7-argument method.389TEST(InvokeMethodTest, MethodThatTakes7Arguments) {390Foo foo;391Action<std::string(const char*, const char*, const char*, const char*,392const char*, const char*, const char*)>393a = Invoke(&foo, &Foo::Concat7);394EXPECT_EQ("1234567",395a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),396CharPtr("4"), CharPtr("5"), CharPtr("6"),397CharPtr("7"))));398}399400// Tests using Invoke() with a 8-argument method.401TEST(InvokeMethodTest, MethodThatTakes8Arguments) {402Foo foo;403Action<std::string(const char*, const char*, const char*, const char*,404const char*, const char*, const char*, const char*)>405a = Invoke(&foo, &Foo::Concat8);406EXPECT_EQ("12345678",407a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),408CharPtr("4"), CharPtr("5"), CharPtr("6"),409CharPtr("7"), CharPtr("8"))));410}411412// Tests using Invoke() with a 9-argument method.413TEST(InvokeMethodTest, MethodThatTakes9Arguments) {414Foo foo;415Action<std::string(const char*, const char*, const char*, const char*,416const char*, const char*, const char*, const char*,417const char*)>418a = Invoke(&foo, &Foo::Concat9);419EXPECT_EQ("123456789", a.Perform(std::make_tuple(420CharPtr("1"), CharPtr("2"), CharPtr("3"),421CharPtr("4"), CharPtr("5"), CharPtr("6"),422CharPtr("7"), CharPtr("8"), CharPtr("9"))));423}424425// Tests using Invoke() with a 10-argument method.426TEST(InvokeMethodTest, MethodThatTakes10Arguments) {427Foo foo;428Action<std::string(const char*, const char*, const char*, const char*,429const char*, const char*, const char*, const char*,430const char*, const char*)>431a = Invoke(&foo, &Foo::Concat10);432EXPECT_EQ("1234567890",433a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),434CharPtr("4"), CharPtr("5"), CharPtr("6"),435CharPtr("7"), CharPtr("8"), CharPtr("9"),436CharPtr("0"))));437}438439// Tests using Invoke(f) as an action of a compatible type.440TEST(InvokeMethodTest, MethodWithCompatibleType) {441Foo foo;442Action<long(int, short, char, bool)> a = // NOLINT443Invoke(&foo, &Foo::SumOf4);444EXPECT_EQ(4444, a.Perform(std::make_tuple(4000, Short(300), Char(20), true)));445}446447// Tests using WithoutArgs with an action that takes no argument.448TEST(WithoutArgsTest, NoArg) {449Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT450EXPECT_EQ(1, a.Perform(std::make_tuple(2)));451}452453// Tests using WithArg with an action that takes 1 argument.454TEST(WithArgTest, OneArg) {455Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT456EXPECT_TRUE(b.Perform(std::make_tuple(1.5, -1)));457EXPECT_FALSE(b.Perform(std::make_tuple(1.5, 1)));458}459460TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {461const Action<int(int)> a = ReturnArg<0>();462EXPECT_EQ(5, a.Perform(std::make_tuple(5)));463}464465TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {466const Action<bool(bool, bool, bool)> a = ReturnArg<0>();467EXPECT_TRUE(a.Perform(std::make_tuple(true, false, false)));468}469470TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {471const Action<std::string(int, int, std::string, int)> a = ReturnArg<2>();472EXPECT_EQ("seven", a.Perform(std::make_tuple(5, 6, std::string("seven"), 8)));473}474475TEST(ReturnArgActionTest, WorksForNonConstRefArg0) {476const Action<std::string&(std::string&)> a = ReturnArg<0>();477std::string s = "12345";478EXPECT_EQ(&s, &a.Perform(std::forward_as_tuple(s)));479}480481TEST(SaveArgActionTest, WorksForSameType) {482int result = 0;483const Action<void(int n)> a1 = SaveArg<0>(&result);484a1.Perform(std::make_tuple(5));485EXPECT_EQ(5, result);486}487488TEST(SaveArgActionTest, WorksForCompatibleType) {489int result = 0;490const Action<void(bool, char)> a1 = SaveArg<1>(&result);491a1.Perform(std::make_tuple(true, 'a'));492EXPECT_EQ('a', result);493}494495struct MoveOnly {496explicit MoveOnly(int v) : i(v) {}497MoveOnly(MoveOnly&& o) {498i = o.i;499o.i = -1;500}501MoveOnly& operator=(MoveOnly&& o) {502i = o.i;503o.i = -1;504return *this;505}506int i;507};508509TEST(SaveArgByMoveActionTest, WorksForSameType) {510MoveOnly result{0};511const Action<void(MoveOnly v)> a1 = SaveArgByMove<0>(&result);512a1.Perform(std::make_tuple(MoveOnly{5}));513EXPECT_EQ(5, result.i);514}515516TEST(SaveArgByMoveActionTest, WorksForCompatibleType) {517MoveOnly result{0};518const Action<void(bool, MoveOnly)> a1 = SaveArgByMove<1>(&result);519a1.Perform(std::make_tuple(true, MoveOnly{7}));520EXPECT_EQ(7, result.i);521}522523TEST(SaveArgPointeeActionTest, WorksForSameType) {524int result = 0;525const int value = 5;526const Action<void(const int*)> a1 = SaveArgPointee<0>(&result);527a1.Perform(std::make_tuple(&value));528EXPECT_EQ(5, result);529}530531TEST(SaveArgPointeeActionTest, WorksForCompatibleType) {532int result = 0;533char value = 'a';534const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result);535a1.Perform(std::make_tuple(true, &value));536EXPECT_EQ('a', result);537}538539TEST(SetArgRefereeActionTest, WorksForSameType) {540int value = 0;541const Action<void(int&)> a1 = SetArgReferee<0>(1);542a1.Perform(std::tuple<int&>(value));543EXPECT_EQ(1, value);544}545546TEST(SetArgRefereeActionTest, WorksForCompatibleType) {547int value = 0;548const Action<void(int, int&)> a1 = SetArgReferee<1>('a');549a1.Perform(std::tuple<int, int&>(0, value));550EXPECT_EQ('a', value);551}552553TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {554int value = 0;555const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');556a1.Perform(std::tuple<bool, int, int&, const char*>(true, 0, value, "hi"));557EXPECT_EQ('a', value);558}559560// A class that can be used to verify that its destructor is called: it will set561// the bool provided to the constructor to true when destroyed.562class DeletionTester {563public:564explicit DeletionTester(bool* is_deleted) : is_deleted_(is_deleted) {565// Make sure the bit is set to false.566*is_deleted_ = false;567}568569~DeletionTester() { *is_deleted_ = true; }570571private:572bool* is_deleted_;573};574575TEST(DeleteArgActionTest, OneArg) {576bool is_deleted = false;577DeletionTester* t = new DeletionTester(&is_deleted);578const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT579EXPECT_FALSE(is_deleted);580a1.Perform(std::make_tuple(t));581EXPECT_TRUE(is_deleted);582}583584TEST(DeleteArgActionTest, TenArgs) {585bool is_deleted = false;586DeletionTester* t = new DeletionTester(&is_deleted);587const Action<void(bool, int, int, const char*, bool, int, int, int, int,588DeletionTester*)>589a1 = DeleteArg<9>();590EXPECT_FALSE(is_deleted);591a1.Perform(std::make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));592EXPECT_TRUE(is_deleted);593}594595#if GTEST_HAS_EXCEPTIONS596597TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {598const Action<void(int n)> a = Throw('a');599EXPECT_THROW(a.Perform(std::make_tuple(0)), char);600}601602class MyException {};603604TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {605const Action<double(char ch)> a = Throw(MyException());606EXPECT_THROW(a.Perform(std::make_tuple('0')), MyException);607}608609TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {610const Action<double()> a = Throw(MyException());611EXPECT_THROW(a.Perform(std::make_tuple()), MyException);612}613614class Object {615public:616virtual ~Object() {}617virtual void Func() {}618};619620class MockObject : public Object {621public:622~MockObject() override {}623MOCK_METHOD(void, Func, (), (override));624};625626TEST(ThrowActionTest, Times0) {627EXPECT_NONFATAL_FAILURE(628[] {629try {630MockObject m;631ON_CALL(m, Func()).WillByDefault([] { throw "something"; });632EXPECT_CALL(m, Func()).Times(0);633m.Func();634} catch (...) {635// Exception is caught but Times(0) still triggers a failure.636}637}(),638"");639}640641#endif // GTEST_HAS_EXCEPTIONS642643// Tests that SetArrayArgument<N>(first, last) sets the elements of the array644// pointed to by the N-th (0-based) argument to values in range [first, last).645TEST(SetArrayArgumentTest, SetsTheNthArray) {646using MyFunction = void(bool, int*, char*);647int numbers[] = {1, 2, 3};648Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);649650int n[4] = {};651int* pn = n;652char ch[4] = {};653char* pch = ch;654a.Perform(std::make_tuple(true, pn, pch));655EXPECT_EQ(1, n[0]);656EXPECT_EQ(2, n[1]);657EXPECT_EQ(3, n[2]);658EXPECT_EQ(0, n[3]);659EXPECT_EQ('\0', ch[0]);660EXPECT_EQ('\0', ch[1]);661EXPECT_EQ('\0', ch[2]);662EXPECT_EQ('\0', ch[3]);663664// Tests first and last are iterators.665std::string letters = "abc";666a = SetArrayArgument<2>(letters.begin(), letters.end());667std::fill_n(n, 4, 0);668std::fill_n(ch, 4, '\0');669a.Perform(std::make_tuple(true, pn, pch));670EXPECT_EQ(0, n[0]);671EXPECT_EQ(0, n[1]);672EXPECT_EQ(0, n[2]);673EXPECT_EQ(0, n[3]);674EXPECT_EQ('a', ch[0]);675EXPECT_EQ('b', ch[1]);676EXPECT_EQ('c', ch[2]);677EXPECT_EQ('\0', ch[3]);678}679680// Tests SetArrayArgument<N>(first, last) where first == last.681TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {682using MyFunction = void(bool, int*);683int numbers[] = {1, 2, 3};684Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);685686int n[4] = {};687int* pn = n;688a.Perform(std::make_tuple(true, pn));689EXPECT_EQ(0, n[0]);690EXPECT_EQ(0, n[1]);691EXPECT_EQ(0, n[2]);692EXPECT_EQ(0, n[3]);693}694695// Tests SetArrayArgument<N>(first, last) where *first is convertible696// (but not equal) to the argument type.697TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {698using MyFunction = void(bool, int*);699char chars[] = {97, 98, 99};700Action<MyFunction> a = SetArrayArgument<1>(chars, chars + 3);701702int codes[4] = {111, 222, 333, 444};703int* pcodes = codes;704a.Perform(std::make_tuple(true, pcodes));705EXPECT_EQ(97, codes[0]);706EXPECT_EQ(98, codes[1]);707EXPECT_EQ(99, codes[2]);708EXPECT_EQ(444, codes[3]);709}710711// Test SetArrayArgument<N>(first, last) with iterator as argument.712TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {713using MyFunction = void(bool, std::back_insert_iterator<std::string>);714std::string letters = "abc";715Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());716717std::string s;718a.Perform(std::make_tuple(true, std::back_inserter(s)));719EXPECT_EQ(letters, s);720}721722TEST(ReturnPointeeTest, Works) {723int n = 42;724const Action<int()> a = ReturnPointee(&n);725EXPECT_EQ(42, a.Perform(std::make_tuple()));726727n = 43;728EXPECT_EQ(43, a.Perform(std::make_tuple()));729}730731// Tests InvokeArgument<N>(...).732733// Tests using InvokeArgument with a nullary function.734TEST(InvokeArgumentTest, Function0) {735Action<int(int, int (*)())> a = InvokeArgument<1>(); // NOLINT736EXPECT_EQ(1, a.Perform(std::make_tuple(2, &Nullary)));737}738739// Tests using InvokeArgument with a unary functor.740TEST(InvokeArgumentTest, Functor1) {741Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT742EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryFunctor())));743}744745// Tests using InvokeArgument with a unary move-only functor.746TEST(InvokeArgumentTest, Functor1MoveOnly) {747Action<int(UnaryMoveOnlyFunctor)> a = InvokeArgument<0>(true); // NOLINT748EXPECT_EQ(1, a.Perform(std::make_tuple(UnaryMoveOnlyFunctor())));749}750751// Tests using InvokeArgument with a one-shot unary functor.752TEST(InvokeArgumentTest, OneShotFunctor1) {753Action<int(OneShotUnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT754EXPECT_EQ(1, a.Perform(std::make_tuple(OneShotUnaryFunctor())));755}756757// Tests using InvokeArgument with a 5-ary function.758TEST(InvokeArgumentTest, Function5) {759Action<int(int (*)(int, int, int, int, int))> a = // NOLINT760InvokeArgument<0>(10000, 2000, 300, 40, 5);761EXPECT_EQ(12345, a.Perform(std::make_tuple(&SumOf5)));762}763764// Tests using InvokeArgument with a 5-ary functor.765TEST(InvokeArgumentTest, Functor5) {766Action<int(SumOf5Functor)> a = // NOLINT767InvokeArgument<0>(10000, 2000, 300, 40, 5);768EXPECT_EQ(12345, a.Perform(std::make_tuple(SumOf5Functor())));769}770771// Tests using InvokeArgument with a 6-ary function.772TEST(InvokeArgumentTest, Function6) {773Action<int(int (*)(int, int, int, int, int, int))> a = // NOLINT774InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);775EXPECT_EQ(123456, a.Perform(std::make_tuple(&SumOf6)));776}777778// Tests using InvokeArgument with a 6-ary functor.779TEST(InvokeArgumentTest, Functor6) {780Action<int(SumOf6Functor)> a = // NOLINT781InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);782EXPECT_EQ(123456, a.Perform(std::make_tuple(SumOf6Functor())));783}784785// Tests using InvokeArgument with a 7-ary function.786TEST(InvokeArgumentTest, Function7) {787Action<std::string(std::string (*)(const char*, const char*, const char*,788const char*, const char*, const char*,789const char*))>790a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");791EXPECT_EQ("1234567", a.Perform(std::make_tuple(&Concat7)));792}793794// Tests using InvokeArgument with a 8-ary function.795TEST(InvokeArgumentTest, Function8) {796Action<std::string(std::string (*)(const char*, const char*, const char*,797const char*, const char*, const char*,798const char*, const char*))>799a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");800EXPECT_EQ("12345678", a.Perform(std::make_tuple(&Concat8)));801}802803// Tests using InvokeArgument with a 9-ary function.804TEST(InvokeArgumentTest, Function9) {805Action<std::string(std::string (*)(const char*, const char*, const char*,806const char*, const char*, const char*,807const char*, const char*, const char*))>808a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");809EXPECT_EQ("123456789", a.Perform(std::make_tuple(&Concat9)));810}811812// Tests using InvokeArgument with a 10-ary function.813TEST(InvokeArgumentTest, Function10) {814Action<std::string(std::string (*)(815const char*, const char*, const char*, const char*, const char*,816const char*, const char*, const char*, const char*, const char*))>817a = InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");818EXPECT_EQ("1234567890", a.Perform(std::make_tuple(&Concat10)));819}820821// Tests using InvokeArgument with a function that takes a pointer argument.822TEST(InvokeArgumentTest, ByPointerFunction) {823Action<const char*(const char* (*)(const char* input, short n))> // NOLINT824a = InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));825EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));826}827828// Tests using InvokeArgument with a function that takes a const char*829// by passing it a C-string literal.830TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {831Action<const char*(const char* (*)(const char* input, short n))> // NOLINT832a = InvokeArgument<0>("Hi", Short(1));833EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary)));834}835836// Tests using InvokeArgument with a function that takes a const reference.837TEST(InvokeArgumentTest, ByConstReferenceFunction) {838Action<bool(bool (*function)(const std::string& s))> a = // NOLINT839InvokeArgument<0>(std::string("Hi"));840// When action 'a' is constructed, it makes a copy of the temporary841// string object passed to it, so it's OK to use 'a' later, when the842// temporary object has already died.843EXPECT_TRUE(a.Perform(std::make_tuple(&ByConstRef)));844}845846// Tests using InvokeArgument with ByRef() and a function that takes a847// const reference.848TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {849Action<bool(bool (*)(const double& x))> a = // NOLINT850InvokeArgument<0>(ByRef(g_double));851// The above line calls ByRef() on a const value.852EXPECT_TRUE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));853854double x = 0;855a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const.856EXPECT_FALSE(a.Perform(std::make_tuple(&ReferencesGlobalDouble)));857}858859TEST(InvokeArgumentTest, MoveOnlyType) {860struct Marker {};861struct {862// Method takes a unique_ptr (to a type we don't care about), and an863// invocable type.864MOCK_METHOD(bool, MockMethod,865(std::unique_ptr<Marker>, std::function<int()>), ());866} mock;867868ON_CALL(mock, MockMethod(_, _)).WillByDefault(InvokeArgument<1>());869870// This compiles, but is a little opaque as a workaround:871ON_CALL(mock, MockMethod(_, _))872.WillByDefault(WithArg<1>(InvokeArgument<0>()));873}874875// Tests DoAll(a1, a2).876TEST(DoAllTest, TwoActions) {877int n = 0;878Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT879Return(2));880EXPECT_EQ(2, a.Perform(std::make_tuple(&n)));881EXPECT_EQ(1, n);882}883884// Tests DoAll(a1, a2, a3).885TEST(DoAllTest, ThreeActions) {886int m = 0, n = 0;887Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT888SetArgPointee<1>(2), Return(3));889EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n)));890EXPECT_EQ(1, m);891EXPECT_EQ(2, n);892}893894// Tests DoAll(a1, a2, a3, a4).895TEST(DoAllTest, FourActions) {896int m = 0, n = 0;897char ch = '\0';898Action<int(int*, int*, char*)> a = // NOLINT899DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),900Return(3));901EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n, &ch)));902EXPECT_EQ(1, m);903EXPECT_EQ(2, n);904EXPECT_EQ('a', ch);905}906907// Tests DoAll(a1, a2, a3, a4, a5).908TEST(DoAllTest, FiveActions) {909int m = 0, n = 0;910char a = '\0', b = '\0';911Action<int(int*, int*, char*, char*)> action = // NOLINT912DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),913SetArgPointee<3>('b'), Return(3));914EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b)));915EXPECT_EQ(1, m);916EXPECT_EQ(2, n);917EXPECT_EQ('a', a);918EXPECT_EQ('b', b);919}920921// Tests DoAll(a1, a2, ..., a6).922TEST(DoAllTest, SixActions) {923int m = 0, n = 0;924char a = '\0', b = '\0', c = '\0';925Action<int(int*, int*, char*, char*, char*)> action = // NOLINT926DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),927SetArgPointee<3>('b'), SetArgPointee<4>('c'), Return(3));928EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c)));929EXPECT_EQ(1, m);930EXPECT_EQ(2, n);931EXPECT_EQ('a', a);932EXPECT_EQ('b', b);933EXPECT_EQ('c', c);934}935936// Tests DoAll(a1, a2, ..., a7).937TEST(DoAllTest, SevenActions) {938int m = 0, n = 0;939char a = '\0', b = '\0', c = '\0', d = '\0';940Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT941DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),942SetArgPointee<3>('b'), SetArgPointee<4>('c'), SetArgPointee<5>('d'),943Return(3));944EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d)));945EXPECT_EQ(1, m);946EXPECT_EQ(2, n);947EXPECT_EQ('a', a);948EXPECT_EQ('b', b);949EXPECT_EQ('c', c);950EXPECT_EQ('d', d);951}952953// Tests DoAll(a1, a2, ..., a8).954TEST(DoAllTest, EightActions) {955int m = 0, n = 0;956char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';957Action<int(int*, int*, char*, char*, char*, char*, // NOLINT958char*)>959action =960DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),961SetArgPointee<3>('b'), SetArgPointee<4>('c'),962SetArgPointee<5>('d'), SetArgPointee<6>('e'), Return(3));963EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e)));964EXPECT_EQ(1, m);965EXPECT_EQ(2, n);966EXPECT_EQ('a', a);967EXPECT_EQ('b', b);968EXPECT_EQ('c', c);969EXPECT_EQ('d', d);970EXPECT_EQ('e', e);971}972973// Tests DoAll(a1, a2, ..., a9).974TEST(DoAllTest, NineActions) {975int m = 0, n = 0;976char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';977Action<int(int*, int*, char*, char*, char*, char*, // NOLINT978char*, char*)>979action = DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2),980SetArgPointee<2>('a'), SetArgPointee<3>('b'),981SetArgPointee<4>('c'), SetArgPointee<5>('d'),982SetArgPointee<6>('e'), SetArgPointee<7>('f'), Return(3));983EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));984EXPECT_EQ(1, m);985EXPECT_EQ(2, n);986EXPECT_EQ('a', a);987EXPECT_EQ('b', b);988EXPECT_EQ('c', c);989EXPECT_EQ('d', d);990EXPECT_EQ('e', e);991EXPECT_EQ('f', f);992}993994// Tests DoAll(a1, a2, ..., a10).995TEST(DoAllTest, TenActions) {996int m = 0, n = 0;997char a = '\0', b = '\0', c = '\0', d = '\0';998char e = '\0', f = '\0', g = '\0';999Action<int(int*, int*, char*, char*, char*, char*, // NOLINT1000char*, char*, char*)>1001action =1002DoAll(SetArgPointee<0>(1), SetArgPointee<1>(2), SetArgPointee<2>('a'),1003SetArgPointee<3>('b'), SetArgPointee<4>('c'),1004SetArgPointee<5>('d'), SetArgPointee<6>('e'),1005SetArgPointee<7>('f'), SetArgPointee<8>('g'), Return(3));1006EXPECT_EQ(10073, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));1008EXPECT_EQ(1, m);1009EXPECT_EQ(2, n);1010EXPECT_EQ('a', a);1011EXPECT_EQ('b', b);1012EXPECT_EQ('c', c);1013EXPECT_EQ('d', d);1014EXPECT_EQ('e', e);1015EXPECT_EQ('f', f);1016EXPECT_EQ('g', g);1017}10181019TEST(DoAllTest, NoArgs) {1020bool ran_first = false;1021Action<bool()> a =1022DoAll([&] { ran_first = true; }, [&] { return ran_first; });1023EXPECT_TRUE(a.Perform({}));1024}10251026TEST(DoAllTest, MoveOnlyArgs) {1027bool ran_first = false;1028Action<int(std::unique_ptr<int>)> a =1029DoAll(InvokeWithoutArgs([&] { ran_first = true; }),1030[](std::unique_ptr<int> p) { return *p; });1031EXPECT_EQ(7, a.Perform(std::make_tuple(std::unique_ptr<int>(new int(7)))));1032EXPECT_TRUE(ran_first);1033}10341035TEST(DoAllTest, ImplicitlyConvertsActionArguments) {1036bool ran_first = false;1037// Action<void(std::vector<int>)> isn't an1038// Action<void(const std::vector<int>&) but can be converted.1039Action<void(std::vector<int>)> first = [&] { ran_first = true; };1040Action<int(std::vector<int>)> a =1041DoAll(first, [](std::vector<int> arg) { return arg.front(); });1042EXPECT_EQ(7, a.Perform(std::make_tuple(std::vector<int>{7})));1043EXPECT_TRUE(ran_first);1044}10451046// The ACTION*() macros trigger warning C4100 (unreferenced formal1047// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in1048// the macro definition, as the warnings are generated when the macro1049// is expanded and macro expansion cannot contain #pragma. Therefore1050// we suppress them here.1051// Also suppress C4503 decorated name length exceeded, name was truncated1052GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503)1053// Tests the ACTION*() macro family.10541055// Tests that ACTION() can define an action that doesn't reference the1056// mock function arguments.1057ACTION(Return5) { return 5; }10581059TEST(ActionMacroTest, WorksWhenNotReferencingArguments) {1060Action<double()> a1 = Return5();1061EXPECT_DOUBLE_EQ(5, a1.Perform(std::make_tuple()));10621063Action<int(double, bool)> a2 = Return5();1064EXPECT_EQ(5, a2.Perform(std::make_tuple(1, true)));1065}10661067// Tests that ACTION() can define an action that returns void.1068ACTION(IncrementArg1) { (*arg1)++; }10691070TEST(ActionMacroTest, WorksWhenReturningVoid) {1071Action<void(int, int*)> a1 = IncrementArg1();1072int n = 0;1073a1.Perform(std::make_tuple(5, &n));1074EXPECT_EQ(1, n);1075}10761077// Tests that the body of ACTION() can reference the type of the1078// argument.1079ACTION(IncrementArg2) {1080StaticAssertTypeEq<int*, arg2_type>();1081arg2_type temp = arg2;1082(*temp)++;1083}10841085TEST(ActionMacroTest, CanReferenceArgumentType) {1086Action<void(int, bool, int*)> a1 = IncrementArg2();1087int n = 0;1088a1.Perform(std::make_tuple(5, false, &n));1089EXPECT_EQ(1, n);1090}10911092// Tests that the body of ACTION() can reference the argument tuple1093// via args_type and args.1094ACTION(Sum2) {1095StaticAssertTypeEq<std::tuple<int, char, int*>, args_type>();1096args_type args_copy = args;1097return std::get<0>(args_copy) + std::get<1>(args_copy);1098}10991100TEST(ActionMacroTest, CanReferenceArgumentTuple) {1101Action<int(int, char, int*)> a1 = Sum2();1102int dummy = 0;1103EXPECT_EQ(11, a1.Perform(std::make_tuple(5, Char(6), &dummy)));1104}11051106namespace {11071108// Tests that the body of ACTION() can reference the mock function1109// type.1110int Dummy(bool flag) { return flag ? 1 : 0; }11111112} // namespace11131114ACTION(InvokeDummy) {1115StaticAssertTypeEq<int(bool), function_type>();1116function_type* fp = &Dummy;1117return (*fp)(true);1118}11191120TEST(ActionMacroTest, CanReferenceMockFunctionType) {1121Action<int(bool)> a1 = InvokeDummy();1122EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));1123EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));1124}11251126// Tests that the body of ACTION() can reference the mock function's1127// return type.1128ACTION(InvokeDummy2) {1129StaticAssertTypeEq<int, return_type>();1130return_type result = Dummy(true);1131return result;1132}11331134TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {1135Action<int(bool)> a1 = InvokeDummy2();1136EXPECT_EQ(1, a1.Perform(std::make_tuple(true)));1137EXPECT_EQ(1, a1.Perform(std::make_tuple(false)));1138}11391140// Tests that ACTION() works for arguments passed by const reference.1141ACTION(ReturnAddrOfConstBoolReferenceArg) {1142StaticAssertTypeEq<const bool&, arg1_type>();1143return &arg1;1144}11451146TEST(ActionMacroTest, WorksForConstReferenceArg) {1147Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();1148const bool b = false;1149EXPECT_EQ(&b, a.Perform(std::tuple<int, const bool&>(0, b)));1150}11511152// Tests that ACTION() works for arguments passed by non-const reference.1153ACTION(ReturnAddrOfIntReferenceArg) {1154StaticAssertTypeEq<int&, arg0_type>();1155return &arg0;1156}11571158TEST(ActionMacroTest, WorksForNonConstReferenceArg) {1159Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();1160int n = 0;1161EXPECT_EQ(&n, a.Perform(std::tuple<int&, bool, int>(n, true, 1)));1162}11631164// Tests that ACTION() can be used in a namespace.1165namespace action_test {1166ACTION(Sum) { return arg0 + arg1; }1167} // namespace action_test11681169TEST(ActionMacroTest, WorksInNamespace) {1170Action<int(int, int)> a1 = action_test::Sum();1171EXPECT_EQ(3, a1.Perform(std::make_tuple(1, 2)));1172}11731174// Tests that the same ACTION definition works for mock functions with1175// different argument numbers.1176ACTION(PlusTwo) { return arg0 + 2; }11771178TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {1179Action<int(int)> a1 = PlusTwo();1180EXPECT_EQ(4, a1.Perform(std::make_tuple(2)));11811182Action<double(float, void*)> a2 = PlusTwo();1183int dummy;1184EXPECT_DOUBLE_EQ(6, a2.Perform(std::make_tuple(4.0f, &dummy)));1185}11861187// Tests that ACTION_P can define a parameterized action.1188ACTION_P(Plus, n) { return arg0 + n; }11891190TEST(ActionPMacroTest, DefinesParameterizedAction) {1191Action<int(int m, bool t)> a1 = Plus(9);1192EXPECT_EQ(10, a1.Perform(std::make_tuple(1, true)));1193}11941195// Tests that the body of ACTION_P can reference the argument types1196// and the parameter type.1197ACTION_P(TypedPlus, n) {1198arg0_type t1 = arg0;1199n_type t2 = n;1200return t1 + t2;1201}12021203TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {1204Action<int(char m, bool t)> a1 = TypedPlus(9);1205EXPECT_EQ(10, a1.Perform(std::make_tuple(Char(1), true)));1206}12071208// Tests that a parameterized action can be used in any mock function1209// whose type is compatible.1210TEST(ActionPMacroTest, WorksInCompatibleMockFunction) {1211Action<std::string(const std::string& s)> a1 = Plus("tail");1212const std::string re = "re";1213std::tuple<const std::string> dummy = std::make_tuple(re);1214EXPECT_EQ("retail", a1.Perform(dummy));1215}12161217// Tests that we can use ACTION*() to define actions overloaded on the1218// number of parameters.12191220ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }12211222ACTION_P(OverloadedAction, default_value) {1223return arg0 ? arg1 : default_value;1224}12251226ACTION_P2(OverloadedAction, true_value, false_value) {1227return arg0 ? true_value : false_value;1228}12291230TEST(ActionMacroTest, CanDefineOverloadedActions) {1231using MyAction = Action<const char*(bool, const char*)>;12321233const MyAction a1 = OverloadedAction();1234EXPECT_STREQ("hello", a1.Perform(std::make_tuple(false, CharPtr("world"))));1235EXPECT_STREQ("world", a1.Perform(std::make_tuple(true, CharPtr("world"))));12361237const MyAction a2 = OverloadedAction("hi");1238EXPECT_STREQ("hi", a2.Perform(std::make_tuple(false, CharPtr("world"))));1239EXPECT_STREQ("world", a2.Perform(std::make_tuple(true, CharPtr("world"))));12401241const MyAction a3 = OverloadedAction("hi", "you");1242EXPECT_STREQ("hi", a3.Perform(std::make_tuple(true, CharPtr("world"))));1243EXPECT_STREQ("you", a3.Perform(std::make_tuple(false, CharPtr("world"))));1244}12451246// Tests ACTION_Pn where n >= 3.12471248ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }12491250TEST(ActionPnMacroTest, WorksFor3Parameters) {1251Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);1252EXPECT_DOUBLE_EQ(3123.4, a1.Perform(std::make_tuple(3000, true)));12531254Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");1255const std::string re = "re";1256std::tuple<const std::string> dummy = std::make_tuple(re);1257EXPECT_EQ("retail->", a2.Perform(dummy));1258}12591260ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }12611262TEST(ActionPnMacroTest, WorksFor4Parameters) {1263Action<int(int)> a1 = Plus(1, 2, 3, 4);1264EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(std::make_tuple(10)));1265}12661267ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }12681269TEST(ActionPnMacroTest, WorksFor5Parameters) {1270Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);1271EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(std::make_tuple(10)));1272}12731274ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {1275return arg0 + p0 + p1 + p2 + p3 + p4 + p5;1276}12771278TEST(ActionPnMacroTest, WorksFor6Parameters) {1279Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);1280EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(std::make_tuple(10)));1281}12821283ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {1284return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;1285}12861287TEST(ActionPnMacroTest, WorksFor7Parameters) {1288Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);1289EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(std::make_tuple(10)));1290}12911292ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {1293return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;1294}12951296TEST(ActionPnMacroTest, WorksFor8Parameters) {1297Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);1298EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,1299a1.Perform(std::make_tuple(10)));1300}13011302ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {1303return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;1304}13051306TEST(ActionPnMacroTest, WorksFor9Parameters) {1307Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);1308EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9,1309a1.Perform(std::make_tuple(10)));1310}13111312ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {1313arg0_type t0 = arg0;1314last_param_type t9 = last_param;1315return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;1316}13171318TEST(ActionPnMacroTest, WorksFor10Parameters) {1319Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);1320EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,1321a1.Perform(std::make_tuple(10)));1322}13231324// Tests that the action body can promote the parameter types.13251326ACTION_P2(PadArgument, prefix, suffix) {1327// The following lines promote the two parameters to desired types.1328std::string prefix_str(prefix);1329char suffix_char = static_cast<char>(suffix);1330return prefix_str + arg0 + suffix_char;1331}13321333TEST(ActionPnMacroTest, SimpleTypePromotion) {1334Action<std::string(const char*)> no_promo =1335PadArgument(std::string("foo"), 'r');1336Action<std::string(const char*)> promo =1337PadArgument("foo", static_cast<int>('r'));1338EXPECT_EQ("foobar", no_promo.Perform(std::make_tuple(CharPtr("ba"))));1339EXPECT_EQ("foobar", promo.Perform(std::make_tuple(CharPtr("ba"))));1340}13411342// Tests that we can partially restrict parameter types using a1343// straight-forward pattern.13441345// Defines a generic action that doesn't restrict the types of its1346// parameters.1347ACTION_P3(ConcatImpl, a, b, c) {1348std::stringstream ss;1349ss << a << b << c;1350return ss.str();1351}13521353// Next, we try to restrict that either the first parameter is a1354// string, or the second parameter is an int.13551356// Defines a partially specialized wrapper that restricts the first1357// parameter to std::string.1358template <typename T1, typename T2>1359// ConcatImplActionP3 is the class template ACTION_P3 uses to1360// implement ConcatImpl. We shouldn't change the name as this1361// pattern requires the user to use it directly.1362ConcatImplActionP3<std::string, T1, T2> Concat(const std::string& a, T1 b,1363T2 c) {1364GTEST_INTENTIONAL_CONST_COND_PUSH_()1365if (true) {1366GTEST_INTENTIONAL_CONST_COND_POP_()1367// This branch verifies that ConcatImpl() can be invoked without1368// explicit template arguments.1369return ConcatImpl(a, b, c);1370} else {1371// This branch verifies that ConcatImpl() can also be invoked with1372// explicit template arguments. It doesn't really need to be1373// executed as this is a compile-time verification.1374return ConcatImpl<std::string, T1, T2>(a, b, c);1375}1376}13771378// Defines another partially specialized wrapper that restricts the1379// second parameter to int.1380template <typename T1, typename T2>1381ConcatImplActionP3<T1, int, T2> Concat(T1 a, int b, T2 c) {1382return ConcatImpl(a, b, c);1383}13841385TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {1386Action<const std::string()> a1 = Concat("Hello", "1", 2);1387EXPECT_EQ("Hello12", a1.Perform(std::make_tuple()));13881389a1 = Concat(1, 2, 3);1390EXPECT_EQ("123", a1.Perform(std::make_tuple()));1391}13921393// Verifies the type of an ACTION*.13941395ACTION(DoFoo) {}1396ACTION_P(DoFoo, p) {}1397ACTION_P2(DoFoo, p0, p1) {}13981399TEST(ActionPnMacroTest, TypesAreCorrect) {1400// DoFoo() must be assignable to a DoFooAction variable.1401DoFooAction a0 = DoFoo();14021403// DoFoo(1) must be assignable to a DoFooActionP variable.1404DoFooActionP<int> a1 = DoFoo(1);14051406// DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk1407// variable, and so on.1408DoFooActionP2<int, char> a2 = DoFoo(1, '2');1409PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');1410PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');1411PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');1412PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');1413PlusActionP7<int, int, int, int, int, int, char> a7 =1414Plus(1, 2, 3, 4, 5, 6, '7');1415PlusActionP8<int, int, int, int, int, int, int, char> a8 =1416Plus(1, 2, 3, 4, 5, 6, 7, '8');1417PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =1418Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');1419PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =1420Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');14211422// Avoid "unused variable" warnings.1423(void)a0;1424(void)a1;1425(void)a2;1426(void)a3;1427(void)a4;1428(void)a5;1429(void)a6;1430(void)a7;1431(void)a8;1432(void)a9;1433(void)a10;1434}14351436// Tests that an ACTION_P*() action can be explicitly instantiated1437// with reference-typed parameters.14381439ACTION_P(Plus1, x) { return x; }1440ACTION_P2(Plus2, x, y) { return x + y; }1441ACTION_P3(Plus3, x, y, z) { return x + y + z; }1442ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {1443return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;1444}14451446TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {1447int x = 1, y = 2, z = 3;1448const std::tuple<> empty = std::make_tuple();14491450Action<int()> a = Plus1<int&>(x);1451EXPECT_EQ(1, a.Perform(empty));14521453a = Plus2<const int&, int&>(x, y);1454EXPECT_EQ(3, a.Perform(empty));14551456a = Plus3<int&, const int&, int&>(x, y, z);1457EXPECT_EQ(6, a.Perform(empty));14581459int n[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};1460a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,1461int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6],1462n[7], n[8], n[9]);1463EXPECT_EQ(55, a.Perform(empty));1464}14651466class TenArgConstructorClass {1467public:1468TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7,1469int a8, int a9, int a10)1470: value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {}1471int value_;1472};14731474// Tests that ACTION_TEMPLATE works when there is no value parameter.1475ACTION_TEMPLATE(CreateNew, HAS_1_TEMPLATE_PARAMS(typename, T),1476AND_0_VALUE_PARAMS()) {1477return new T;1478}14791480TEST(ActionTemplateTest, WorksWithoutValueParam) {1481const Action<int*()> a = CreateNew<int>();1482int* p = a.Perform(std::make_tuple());1483delete p;1484}14851486// Tests that ACTION_TEMPLATE works when there are value parameters.1487ACTION_TEMPLATE(CreateNew, HAS_1_TEMPLATE_PARAMS(typename, T),1488AND_1_VALUE_PARAMS(a0)) {1489return new T(a0);1490}14911492TEST(ActionTemplateTest, WorksWithValueParams) {1493const Action<int*()> a = CreateNew<int>(42);1494int* p = a.Perform(std::make_tuple());1495EXPECT_EQ(42, *p);1496delete p;1497}14981499// Tests that ACTION_TEMPLATE works for integral template parameters.1500ACTION_TEMPLATE(MyDeleteArg, HAS_1_TEMPLATE_PARAMS(int, k),1501AND_0_VALUE_PARAMS()) {1502delete std::get<k>(args);1503}15041505// Resets a bool variable in the destructor.1506class BoolResetter {1507public:1508explicit BoolResetter(bool* value) : value_(value) {}1509~BoolResetter() { *value_ = false; }15101511private:1512bool* value_;1513};15141515TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {1516const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();1517int n = 0;1518bool b = true;1519auto* resetter = new BoolResetter(&b);1520a.Perform(std::make_tuple(&n, resetter));1521EXPECT_FALSE(b); // Verifies that resetter is deleted.1522}15231524// Tests that ACTION_TEMPLATES works for template template parameters.1525ACTION_TEMPLATE(ReturnSmartPointer,1526HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,1527Pointer),1528AND_1_VALUE_PARAMS(pointee)) {1529return Pointer<pointee_type>(new pointee_type(pointee));1530}15311532TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {1533const Action<std::shared_ptr<int>()> a =1534ReturnSmartPointer<std::shared_ptr>(42);1535std::shared_ptr<int> p = a.Perform(std::make_tuple());1536EXPECT_EQ(42, *p);1537}15381539// Tests that ACTION_TEMPLATE works for 10 template parameters.1540template <typename T1, typename T2, typename T3, int k4, bool k5,1541unsigned int k6, typename T7, typename T8, typename T9>1542struct GiantTemplate {1543public:1544explicit GiantTemplate(int a_value) : value(a_value) {}1545int value;1546};15471548ACTION_TEMPLATE(ReturnGiant,1549HAS_10_TEMPLATE_PARAMS(typename, T1, typename, T2, typename, T3,1550int, k4, bool, k5, unsigned int, k6,1551class, T7, class, T8, class, T9,1552template <typename T> class, T10),1553AND_1_VALUE_PARAMS(value)) {1554return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);1555}15561557TEST(ActionTemplateTest, WorksFor10TemplateParameters) {1558using Giant = GiantTemplate<std::shared_ptr<int>, bool, double, 5, true, 6,1559char, unsigned, int>;1560const Action<Giant()> a = ReturnGiant<int, bool, double, 5, true, 6, char,1561unsigned, int, std::shared_ptr>(42);1562Giant giant = a.Perform(std::make_tuple());1563EXPECT_EQ(42, giant.value);1564}15651566// Tests that ACTION_TEMPLATE works for 10 value parameters.1567ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),1568AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {1569return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;1570}15711572TEST(ActionTemplateTest, WorksFor10ValueParameters) {1573const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);1574EXPECT_EQ(55, a.Perform(std::make_tuple()));1575}15761577// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded1578// on the number of value parameters.15791580ACTION(ReturnSum) { return 0; }15811582ACTION_P(ReturnSum, x) { return x; }15831584ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),1585AND_2_VALUE_PARAMS(v1, v2)) {1586return static_cast<Number>(v1) + v2;1587}15881589ACTION_TEMPLATE(ReturnSum, HAS_1_TEMPLATE_PARAMS(typename, Number),1590AND_3_VALUE_PARAMS(v1, v2, v3)) {1591return static_cast<Number>(v1) + v2 + v3;1592}15931594ACTION_TEMPLATE(ReturnSum, HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),1595AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {1596return static_cast<Number>(v1) + v2 + v3 + v4 + k;1597}15981599TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {1600const Action<int()> a0 = ReturnSum();1601const Action<int()> a1 = ReturnSum(1);1602const Action<int()> a2 = ReturnSum<int>(1, 2);1603const Action<int()> a3 = ReturnSum<int>(1, 2, 3);1604const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);1605EXPECT_EQ(0, a0.Perform(std::make_tuple()));1606EXPECT_EQ(1, a1.Perform(std::make_tuple()));1607EXPECT_EQ(3, a2.Perform(std::make_tuple()));1608EXPECT_EQ(6, a3.Perform(std::make_tuple()));1609EXPECT_EQ(12345, a4.Perform(std::make_tuple()));1610}16111612} // namespace gmock_more_actions_test1613} // namespace testing16141615GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 45031616GTEST_DISABLE_MSC_WARNINGS_POP_() // 4577161716181619