| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TESTING_GMOCK_MUTANT_H_ |
| #define TESTING_GMOCK_MUTANT_H_ |
| |
| // The intention of this file is to make possible using GMock actions in |
| // all of its syntactic beauty. |
| // |
| // |
| // Sample usage with gMock: |
| // |
| // struct Mock : public ObjectDelegate { |
| // MOCK_METHOD2(string, OnRequest(int n, const string& request)); |
| // MOCK_METHOD1(void, OnQuit(int exit_code)); |
| // MOCK_METHOD2(void, LogMessage(int level, const string& message)); |
| // |
| // string HandleFlowers(const string& reply, int n, const string& request) { |
| // string result = SStringPrintf("In request of %d %s ", n, request); |
| // for (int i = 0; i < n; ++i) result.append(reply) |
| // return result; |
| // } |
| // |
| // void DoLogMessage(int level, const string& message) { |
| // } |
| // |
| // void QuitMessageLoop(int seconds) { |
| // base::MessageLoop* loop = base::MessageLoop::current(); |
| // loop->PostDelayedTask(FROM_HERE, |
| // base::MessageLoop::QuitWhenIdleClosure(), |
| // 1000 * seconds); |
| // } |
| // }; |
| // |
| // Mock mock; |
| // // Will invoke mock.HandleFlowers("orchids", n, request) |
| // // "orchids" is a pre-bound argument, and <n> and <request> are call-time |
| // // arguments - they are not known until the OnRequest mock is invoked. |
| // EXPECT_CALL(mock, OnRequest(Ge(5), base::StartsWith("flower")) |
| // .Times(1) |
| // .WillOnce(Invoke(CreateFunctor( |
| // &Mock::HandleFlowers, base::Unretained(&mock), string("orchids")))); |
| // |
| // |
| // // No pre-bound arguments, two call-time arguments passed |
| // // directly to DoLogMessage |
| // EXPECT_CALL(mock, OnLogMessage(_, _)) |
| // .Times(AnyNumber()) |
| // .WillAlways(Invoke(CreateFunctor( |
| // &Mock::DoLogMessage, base::Unretained(&mock)))); |
| // |
| // |
| // // In this case we have a single pre-bound argument - 3. We ignore |
| // // all of the arguments of OnQuit. |
| // EXCEPT_CALL(mock, OnQuit(_)) |
| // .Times(1) |
| // .WillOnce(InvokeWithoutArgs(CreateFunctor( |
| // &Mock::QuitMessageLoop, base::Unretained(&mock), 3))); |
| // |
| // MessageLoop loop; |
| // loop.Run(); |
| // |
| // |
| // // Here is another example of how we can set an action that invokes |
| // // method of an object that is not yet created. |
| // struct Mock : public ObjectDelegate { |
| // MOCK_METHOD1(void, DemiurgeCreated(Demiurge*)); |
| // MOCK_METHOD2(void, OnRequest(int count, const string&)); |
| // |
| // void StoreDemiurge(Demiurge* w) { |
| // demiurge_ = w; |
| // } |
| // |
| // Demiurge* demiurge; |
| // } |
| // |
| // EXPECT_CALL(mock, DemiurgeCreated(_)).Times(1) |
| // .WillOnce(Invoke(CreateFunctor( |
| // &Mock::StoreDemiurge, base::Unretained(&mock)))); |
| // |
| // EXPECT_CALL(mock, OnRequest(_, StrEq("Moby Dick"))) |
| // .Times(AnyNumber()) |
| // .WillAlways(WithArgs<0>(Invoke(CreateFunctor( |
| // &Demiurge::DecreaseMonsters, base::Unretained(&mock->demiurge_))))); |
| // |
| |
| #include "base/bind.h" |
| |
| namespace testing { |
| |
| template <typename Signature> |
| class CallbackToFunctorHelper; |
| |
| template <typename R, typename... Args> |
| class CallbackToFunctorHelper<R(Args...)> { |
| public: |
| explicit CallbackToFunctorHelper(const base::Callback<R(Args...)>& cb) |
| : cb_(cb) {} |
| |
| template <typename... RunArgs> |
| R operator()(RunArgs&&... args) { |
| return cb_.Run(std::forward<RunArgs>(args)...); |
| } |
| |
| private: |
| base::Callback<R(Args...)> cb_; |
| }; |
| |
| template <typename Signature> |
| CallbackToFunctorHelper<Signature> |
| CallbackToFunctor(const base::Callback<Signature>& cb) { |
| return CallbackToFunctorHelper<Signature>(cb); |
| } |
| |
| template <typename Functor, typename... BoundArgs> |
| CallbackToFunctorHelper<base::MakeUnboundRunType<Functor, BoundArgs...>> |
| CreateFunctor(Functor functor, const BoundArgs&... args) { |
| return CallbackToFunctor(base::Bind(functor, args...)); |
| } |
| |
| } // namespace testing |
| |
| #endif // TESTING_GMOCK_MUTANT_H_ |