From a9e02a9178d29446b77564dd59e995ec4acfeb11 Mon Sep 17 00:00:00 2001 From: kosak Date: Tue, 17 Jun 2014 23:19:54 +0000 Subject: [PATCH] Add MockFunction::AsStdFunction(). Also pull in gtest 688. --- .../gmock/gmock-generated-function-mockers.h | 101 ++++++++++++++++++ .../gmock-generated-function-mockers.h.pump | 26 ++++- test/gmock-generated-function-mockers_test.cc | 13 +++ 3 files changed, 138 insertions(+), 2 deletions(-) diff --git a/include/gmock/gmock-generated-function-mockers.h b/include/gmock/gmock-generated-function-mockers.h index 1b01dc86..d14e1ad4 100644 --- a/include/gmock/gmock-generated-function-mockers.h +++ b/include/gmock/gmock-generated-function-mockers.h @@ -854,6 +854,17 @@ using internal::FunctionMocker; // point "2", and nothing should happen between the two check // points. The explicit check points make it easy to tell which // Bar("a") is called by which call to Foo(). +// +// MockFunction can also be used to exercise code that accepts +// std::function callbacks. To do so, use AsStdFunction() method +// to create std::function proxy forwarding to original object's Call. +// Example: +// +// TEST(FooTest, RunsCallbackWithBarArgument) { +// MockFunction callback; +// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); +// Foo(callback.AsStdFunction()); +// } template class MockFunction; @@ -864,6 +875,14 @@ class MockFunction { MOCK_METHOD0_T(Call, R()); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this]() { + return this->Call(); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -875,6 +894,14 @@ class MockFunction { MOCK_METHOD1_T(Call, R(A0)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0) { + return this->Call(a0); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -886,6 +913,14 @@ class MockFunction { MOCK_METHOD2_T(Call, R(A0, A1)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1) { + return this->Call(a0, a1); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -897,6 +932,14 @@ class MockFunction { MOCK_METHOD3_T(Call, R(A0, A1, A2)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2) { + return this->Call(a0, a1, a2); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -908,6 +951,14 @@ class MockFunction { MOCK_METHOD4_T(Call, R(A0, A1, A2, A3)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3) { + return this->Call(a0, a1, a2, a3); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -920,6 +971,14 @@ class MockFunction { MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return this->Call(a0, a1, a2, a3, a4); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -932,6 +991,14 @@ class MockFunction { MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + return this->Call(a0, a1, a2, a3, a4, a5); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -944,6 +1011,14 @@ class MockFunction { MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + return this->Call(a0, a1, a2, a3, a4, a5, a6); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -956,6 +1031,14 @@ class MockFunction { MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -968,6 +1051,15 @@ class MockFunction { MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, + A8 a8) { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; @@ -981,6 +1073,15 @@ class MockFunction { MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)); +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, + A8 a8, A9 a9) { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + }; + } +#endif // GTEST_LANG_CXX11 + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); }; diff --git a/include/gmock/gmock-generated-function-mockers.h.pump b/include/gmock/gmock-generated-function-mockers.h.pump index be819961..5e839625 100644 --- a/include/gmock/gmock-generated-function-mockers.h.pump +++ b/include/gmock/gmock-generated-function-mockers.h.pump @@ -241,18 +241,40 @@ $for i [[ // point "2", and nothing should happen between the two check // points. The explicit check points make it easy to tell which // Bar("a") is called by which call to Foo(). +// +// MockFunction can also be used to exercise code that accepts +// std::function callbacks. To do so, use AsStdFunction() method +// to create std::function proxy forwarding to original object's Call. +// Example: +// +// TEST(FooTest, RunsCallbackWithBarArgument) { +// MockFunction callback; +// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); +// Foo(callback.AsStdFunction()); +// } template class MockFunction; $for i [[ $range j 0..i-1 +$var ArgTypes = [[$for j, [[A$j]]]] +$var ArgNames = [[$for j, [[a$j]]]] +$var ArgDecls = [[$for j, [[A$j a$j]]]] template -class MockFunction { +class MockFunction { public: MockFunction() {} - MOCK_METHOD$i[[]]_T(Call, R($for j, [[A$j]])); + MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); + +#if GTEST_LANG_CXX11 + std::function AsStdFunction() { + return [this]($ArgDecls) { + return this->Call($ArgNames); + }; + } +#endif // GTEST_LANG_CXX11 private: GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); diff --git a/test/gmock-generated-function-mockers_test.cc b/test/gmock-generated-function-mockers_test.cc index 169ed5a2..14dded87 100644 --- a/test/gmock-generated-function-mockers_test.cc +++ b/test/gmock-generated-function-mockers_test.cc @@ -595,5 +595,18 @@ TEST(MockFunctionTest, WorksFor10Arguments) { EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false)); } +#if GTEST_LANG_CXX11 +TEST(MockFunctionTest, AsStdFunction) { + MockFunction foo; + auto call = [](const std::function &f, int i) { + return f(i); + }; + EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1)); + EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2)); + EXPECT_EQ(-1, call(foo.AsStdFunction(), 1)); + EXPECT_EQ(-2, call(foo.AsStdFunction(), 2)); +} +#endif // GTEST_LANG_CXX11 + } // namespace gmock_generated_function_mockers_test } // namespace testing