blob: 2a41cf54da750fd265b35b49b362734a0901e19c [file] [log] [blame]
// 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>
CallbackToFunctorHelper<typename Functor::RunType> CreateFunctor(
Functor functor) {
return CallbackToFunctor(functor);
}
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_