1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef TESTING_GMOCK_MUTANT_H_
6 #define TESTING_GMOCK_MUTANT_H_
7
8 // The intention of this file is to make possible using GMock actions in
9 // all of its syntactic beauty.
10 //
11 //
12 // Sample usage with gMock:
13 //
14 // struct Mock : public ObjectDelegate {
15 // MOCK_METHOD2(string, OnRequest(int n, const string& request));
16 // MOCK_METHOD1(void, OnQuit(int exit_code));
17 // MOCK_METHOD2(void, LogMessage(int level, const string& message));
18 //
19 // string HandleFlowers(const string& reply, int n, const string& request) {
20 // string result = SStringPrintf("In request of %d %s ", n, request);
21 // for (int i = 0; i < n; ++i) result.append(reply)
22 // return result;
23 // }
24 //
25 // void DoLogMessage(int level, const string& message) {
26 // }
27 //
28 // void QuitMessageLoop(int seconds) {
29 // base::MessageLoop* loop = base::MessageLoop::current();
30 // loop->PostDelayedTask(FROM_HERE,
31 // base::MessageLoop::QuitWhenIdleClosure(),
32 // 1000 * seconds);
33 // }
34 // };
35 //
36 // Mock mock;
37 // // Will invoke mock.HandleFlowers("orchids", n, request)
38 // // "orchids" is a pre-bound argument, and <n> and <request> are call-time
39 // // arguments - they are not known until the OnRequest mock is invoked.
40 // EXPECT_CALL(mock, OnRequest(Ge(5), base::StartsWith("flower"))
41 // .Times(1)
42 // .WillOnce(Invoke(CreateFunctor(
43 // &Mock::HandleFlowers, base::Unretained(&mock), string("orchids"))));
44 //
45 //
46 // // No pre-bound arguments, two call-time arguments passed
47 // // directly to DoLogMessage
48 // EXPECT_CALL(mock, OnLogMessage(_, _))
49 // .Times(AnyNumber())
50 // .WillAlways(Invoke(CreateFunctor(
51 // &Mock::DoLogMessage, base::Unretained(&mock))));
52 //
53 //
54 // // In this case we have a single pre-bound argument - 3. We ignore
55 // // all of the arguments of OnQuit.
56 // EXCEPT_CALL(mock, OnQuit(_))
57 // .Times(1)
58 // .WillOnce(InvokeWithoutArgs(CreateFunctor(
59 // &Mock::QuitMessageLoop, base::Unretained(&mock), 3)));
60 //
61 // MessageLoop loop;
62 // loop.Run();
63 //
64 //
65 // // Here is another example of how we can set an action that invokes
66 // // method of an object that is not yet created.
67 // struct Mock : public ObjectDelegate {
68 // MOCK_METHOD1(void, DemiurgeCreated(Demiurge*));
69 // MOCK_METHOD2(void, OnRequest(int count, const string&));
70 //
71 // void StoreDemiurge(Demiurge* w) {
72 // demiurge_ = w;
73 // }
74 //
75 // Demiurge* demiurge;
76 // }
77 //
78 // EXPECT_CALL(mock, DemiurgeCreated(_)).Times(1)
79 // .WillOnce(Invoke(CreateFunctor(
80 // &Mock::StoreDemiurge, base::Unretained(&mock))));
81 //
82 // EXPECT_CALL(mock, OnRequest(_, StrEq("Moby Dick")))
83 // .Times(AnyNumber())
84 // .WillAlways(WithArgs<0>(Invoke(CreateFunctor(
85 // &Demiurge::DecreaseMonsters, base::Unretained(&mock->demiurge_)))));
86 //
87
88 #include "base/bind.h"
89
90 namespace testing {
91
92 template <typename Signature>
93 class CallbackToFunctorHelper;
94
95 template <typename R, typename... Args>
96 class CallbackToFunctorHelper<R(Args...)> {
97 public:
CallbackToFunctorHelper(const base::Callback<R (Args...)> & cb)98 explicit CallbackToFunctorHelper(const base::Callback<R(Args...)>& cb)
99 : cb_(cb) {}
100
101 template <typename... RunArgs>
operator()102 R operator()(RunArgs&&... args) {
103 return cb_.Run(std::forward<RunArgs>(args)...);
104 }
105
106 private:
107 base::Callback<R(Args...)> cb_;
108 };
109
110 template <typename Signature>
111 CallbackToFunctorHelper<Signature>
CallbackToFunctor(const base::Callback<Signature> & cb)112 CallbackToFunctor(const base::Callback<Signature>& cb) {
113 return CallbackToFunctorHelper<Signature>(cb);
114 }
115
116 template <typename Functor>
CreateFunctor(Functor functor)117 CallbackToFunctorHelper<typename Functor::RunType> CreateFunctor(
118 Functor functor) {
119 return CallbackToFunctor(functor);
120 }
121
122 template <typename Functor, typename... BoundArgs>
123 CallbackToFunctorHelper<base::MakeUnboundRunType<Functor, BoundArgs...>>
CreateFunctor(Functor functor,const BoundArgs &...args)124 CreateFunctor(Functor functor, const BoundArgs&... args) {
125 return CallbackToFunctor(base::Bind(functor, args...));
126 }
127
128 } // namespace testing
129
130 #endif // TESTING_GMOCK_MUTANT_H_
131