|  | $$ -*- mode: c++; -*- | 
|  | $$ This is a Pump source file.  Please use Pump to convert | 
|  | $$ it to gmock-generated-function-mockers.h. | 
|  | $$ | 
|  | $var n = 10  $$ The maximum arity we support. | 
|  | // Copyright 2007, Google Inc. | 
|  | // All rights reserved. | 
|  | // | 
|  | // Redistribution and use in source and binary forms, with or without | 
|  | // modification, are permitted provided that the following conditions are | 
|  | // met: | 
|  | // | 
|  | //     * Redistributions of source code must retain the above copyright | 
|  | // notice, this list of conditions and the following disclaimer. | 
|  | //     * Redistributions in binary form must reproduce the above | 
|  | // copyright notice, this list of conditions and the following disclaimer | 
|  | // in the documentation and/or other materials provided with the | 
|  | // distribution. | 
|  | //     * Neither the name of Google Inc. nor the names of its | 
|  | // contributors may be used to endorse or promote products derived from | 
|  | // this software without specific prior written permission. | 
|  | // | 
|  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | // | 
|  | // Author: wan@google.com (Zhanyong Wan) | 
|  |  | 
|  | // Google Mock - a framework for writing C++ mock classes. | 
|  | // | 
|  | // This file implements function mockers of various arities. | 
|  |  | 
|  | #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ | 
|  | #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ | 
|  |  | 
|  | #include "gmock/gmock-spec-builders.h" | 
|  | #include "gmock/internal/gmock-internal-utils.h" | 
|  |  | 
|  | #if GTEST_HAS_STD_FUNCTION_ | 
|  | # include <functional> | 
|  | #endif | 
|  |  | 
|  | namespace testing { | 
|  | namespace internal { | 
|  |  | 
|  | template <typename F> | 
|  | class FunctionMockerBase; | 
|  |  | 
|  | // Note: class FunctionMocker really belongs to the ::testing | 
|  | // namespace.  However if we define it in ::testing, MSVC will | 
|  | // complain when classes in ::testing::internal declare it as a | 
|  | // friend class template.  To workaround this compiler bug, we define | 
|  | // FunctionMocker in ::testing::internal and import it into ::testing. | 
|  | template <typename F> | 
|  | class FunctionMocker; | 
|  |  | 
|  |  | 
|  | $range i 0..n | 
|  | $for i [[ | 
|  | $range j 1..i | 
|  | $var typename_As = [[$for j [[, typename A$j]]]] | 
|  | $var As = [[$for j, [[A$j]]]] | 
|  | $var as = [[$for j, [[internal::forward<A$j>(a$j)]]]] | 
|  | $var Aas = [[$for j, [[A$j a$j]]]] | 
|  | $var ms = [[$for j, [[m$j]]]] | 
|  | $var matchers = [[$for j, [[const Matcher<A$j>& m$j]]]] | 
|  | template <typename R$typename_As> | 
|  | class FunctionMocker<R($As)> : public | 
|  | internal::FunctionMockerBase<R($As)> { | 
|  | public: | 
|  | typedef R F($As); | 
|  | typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; | 
|  |  | 
|  | MockSpec<F> With($matchers) { | 
|  | return MockSpec<F>(this, ::testing::make_tuple($ms)); | 
|  | } | 
|  |  | 
|  | R Invoke($Aas) { | 
|  | // Even though gcc and MSVC don't enforce it, 'this->' is required | 
|  | // by the C++ standard [14.6.4] here, as the base class type is | 
|  | // dependent on the template argument (and thus shouldn't be | 
|  | // looked into when resolving InvokeWith). | 
|  | return this->InvokeWith(ArgumentTuple($as)); | 
|  | } | 
|  | }; | 
|  |  | 
|  |  | 
|  | ]] | 
|  | // Removes the given pointer; this is a helper for the expectation setter method | 
|  | // for parameterless matchers. | 
|  | // | 
|  | // We want to make sure that the user cannot set a parameterless expectation on | 
|  | // overloaded methods, including methods which are overloaded on const. Example: | 
|  | // | 
|  | //   class MockClass { | 
|  | //     MOCK_METHOD0(GetName, string&()); | 
|  | //     MOCK_CONST_METHOD0(GetName, const string&()); | 
|  | //   }; | 
|  | // | 
|  | //   TEST() { | 
|  | //     // This should be an error, as it's not clear which overload is expected. | 
|  | //     EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value)); | 
|  | //   } | 
|  | // | 
|  | // Here are the generated expectation-setter methods: | 
|  | // | 
|  | //   class MockClass { | 
|  | //     // Overload 1 | 
|  | //     MockSpec<string&()> gmock_GetName() { … } | 
|  | //     // Overload 2. Declared const so that the compiler will generate an | 
|  | //     // error when trying to resolve between this and overload 4 in | 
|  | //     // 'gmock_GetName(WithoutMatchers(), nullptr)'. | 
|  | //     MockSpec<string&()> gmock_GetName( | 
|  | //         const WithoutMatchers&, const Function<string&()>*) const { | 
|  | //       // Removes const from this, calls overload 1 | 
|  | //       return AdjustConstness_(this)->gmock_GetName(); | 
|  | //     } | 
|  | // | 
|  | //     // Overload 3 | 
|  | //     const string& gmock_GetName() const { … } | 
|  | //     // Overload 4 | 
|  | //     MockSpec<const string&()> gmock_GetName( | 
|  | //         const WithoutMatchers&, const Function<const string&()>*) const { | 
|  | //       // Does not remove const, calls overload 3 | 
|  | //       return AdjustConstness_const(this)->gmock_GetName(); | 
|  | //     } | 
|  | //   } | 
|  | // | 
|  | template <typename MockType> | 
|  | const MockType* AdjustConstness_const(const MockType* mock) { | 
|  | return mock; | 
|  | } | 
|  |  | 
|  | // Removes const from and returns the given pointer; this is a helper for the | 
|  | // expectation setter method for parameterless matchers. | 
|  | template <typename MockType> | 
|  | MockType* AdjustConstness_(const MockType* mock) { | 
|  | return const_cast<MockType*>(mock); | 
|  | } | 
|  |  | 
|  | }  // namespace internal | 
|  |  | 
|  | // The style guide prohibits "using" statements in a namespace scope | 
|  | // inside a header file.  However, the FunctionMocker class template | 
|  | // is meant to be defined in the ::testing namespace.  The following | 
|  | // line is just a trick for working around a bug in MSVC 8.0, which | 
|  | // cannot handle it if we define FunctionMocker in ::testing. | 
|  | using internal::FunctionMocker; | 
|  |  | 
|  | // GMOCK_RESULT_(tn, F) expands to the result type of function type F. | 
|  | // We define this as a variadic macro in case F contains unprotected | 
|  | // commas (the same reason that we use variadic macros in other places | 
|  | // in this file). | 
|  | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | 
|  | #define GMOCK_RESULT_(tn, ...) \ | 
|  | tn ::testing::internal::Function<__VA_ARGS__>::Result | 
|  |  | 
|  | // The type of argument N of the given function type. | 
|  | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | 
|  | #define GMOCK_ARG_(tn, N, ...) \ | 
|  | tn ::testing::internal::Function<__VA_ARGS__>::Argument##N | 
|  |  | 
|  | // The matcher type for argument N of the given function type. | 
|  | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | 
|  | #define GMOCK_MATCHER_(tn, N, ...) \ | 
|  | const ::testing::Matcher<GMOCK_ARG_(tn, N, __VA_ARGS__)>& | 
|  |  | 
|  | // The variable for mocking the given method. | 
|  | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | 
|  | #define GMOCK_MOCKER_(arity, constness, Method) \ | 
|  | GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | $range j 1..i | 
|  | $var arg_as = [[$for j, [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] | 
|  | $var as = [[$for j, \ | 
|  | [[::testing::internal::forward<GMOCK_ARG_(tn, $j, __VA_ARGS__)>(gmock_a$j)]]]] | 
|  | $var matcher_arg_as = [[$for j, \ | 
|  | [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] | 
|  | $var matcher_as = [[$for j, [[gmock_a$j]]]] | 
|  | $var anything_matchers = [[$for j, \ | 
|  | [[::testing::A<GMOCK_ARG_(tn, $j, __VA_ARGS__)>()]]]] | 
|  | // INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! | 
|  | #define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ | 
|  | GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ | 
|  | $arg_as) constness { \ | 
|  | GTEST_COMPILE_ASSERT_((::testing::tuple_size<                          \ | 
|  | tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \ | 
|  | this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \ | 
|  | GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ | 
|  | return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ | 
|  | } \ | 
|  | ::testing::MockSpec<__VA_ARGS__> \ | 
|  | gmock_##Method($matcher_arg_as) constness { \ | 
|  | GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ | 
|  | return GMOCK_MOCKER_($i, constness, Method).With($matcher_as); \ | 
|  | } \ | 
|  | ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \ | 
|  | const ::testing::internal::WithoutMatchers&, \ | 
|  | constness ::testing::internal::Function<__VA_ARGS__>* ) const { \ | 
|  | return ::testing::internal::AdjustConstness_##constness(this)-> \ | 
|  | gmock_##Method($anything_matchers); \ | 
|  | } \ | 
|  | mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) | 
|  |  | 
|  |  | 
|  | ]] | 
|  | $for i [[ | 
|  | #define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | #define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | #define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | #define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ | 
|  | GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | #define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ | 
|  | GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | #define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ | 
|  | GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | #define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ | 
|  | GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | #define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ | 
|  | GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) | 
|  |  | 
|  | ]] | 
|  |  | 
|  | // A MockFunction<F> class has one mock method whose type is F.  It is | 
|  | // useful when you just want your test code to emit some messages and | 
|  | // have Google Mock verify the right messages are sent (and perhaps at | 
|  | // the right times).  For example, if you are exercising code: | 
|  | // | 
|  | //   Foo(1); | 
|  | //   Foo(2); | 
|  | //   Foo(3); | 
|  | // | 
|  | // and want to verify that Foo(1) and Foo(3) both invoke | 
|  | // mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: | 
|  | // | 
|  | // TEST(FooTest, InvokesBarCorrectly) { | 
|  | //   MyMock mock; | 
|  | //   MockFunction<void(string check_point_name)> check; | 
|  | //   { | 
|  | //     InSequence s; | 
|  | // | 
|  | //     EXPECT_CALL(mock, Bar("a")); | 
|  | //     EXPECT_CALL(check, Call("1")); | 
|  | //     EXPECT_CALL(check, Call("2")); | 
|  | //     EXPECT_CALL(mock, Bar("a")); | 
|  | //   } | 
|  | //   Foo(1); | 
|  | //   check.Call("1"); | 
|  | //   Foo(2); | 
|  | //   check.Call("2"); | 
|  | //   Foo(3); | 
|  | // } | 
|  | // | 
|  | // The expectation spec says that the first Bar("a") must happen | 
|  | // before check point "1", the second Bar("a") must happen after check | 
|  | // 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<F> can also be used to exercise code that accepts | 
|  | // std::function<F> callbacks. To do so, use AsStdFunction() method | 
|  | // to create std::function proxy forwarding to original object's Call. | 
|  | // Example: | 
|  | // | 
|  | // TEST(FooTest, RunsCallbackWithBarArgument) { | 
|  | //   MockFunction<int(string)> callback; | 
|  | //   EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); | 
|  | //   Foo(callback.AsStdFunction()); | 
|  | // } | 
|  | template <typename F> | 
|  | class MockFunction; | 
|  |  | 
|  |  | 
|  | $for i [[ | 
|  | $range j 0..i-1 | 
|  | $var ArgTypes = [[$for j, [[A$j]]]] | 
|  | $var ArgValues = [[$for j, [[::std::move(a$j)]]]] | 
|  | $var ArgDecls = [[$for j, [[A$j a$j]]]] | 
|  | template <typename R$for j [[, typename A$j]]> | 
|  | class MockFunction<R($ArgTypes)> { | 
|  | public: | 
|  | MockFunction() {} | 
|  |  | 
|  | MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); | 
|  |  | 
|  | #if GTEST_HAS_STD_FUNCTION_ | 
|  | ::std::function<R($ArgTypes)> AsStdFunction() { | 
|  | return [this]($ArgDecls) -> R { | 
|  | return this->Call($ArgValues); | 
|  | }; | 
|  | } | 
|  | #endif  // GTEST_HAS_STD_FUNCTION_ | 
|  |  | 
|  | private: | 
|  | GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); | 
|  | }; | 
|  |  | 
|  |  | 
|  | ]] | 
|  | }  // namespace testing | 
|  |  | 
|  | #endif  // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ |