1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/test/gmock_callback_support.h"
6
7 #include <memory>
8
9 #include "base/functional/bind.h"
10 #include "base/functional/callback.h"
11 #include "base/functional/callback_helpers.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using testing::_;
16 using testing::ByRef;
17 using testing::MockFunction;
18
19 namespace base::test {
20
21 using TestCallback = base::RepeatingCallback<void(const bool& src, bool* dst)>;
22 using TestOnceCallback = base::OnceCallback<void(const bool& src, bool* dst)>;
23 using TestOnceCallbackMove =
24 base::OnceCallback<void(std::unique_ptr<int>, int* dst)>;
25
SetBool(const bool & src,bool * dst)26 void SetBool(const bool& src, bool* dst) {
27 *dst = src;
28 }
29
SetIntFromPtr(std::unique_ptr<int> ptr,int * dst)30 void SetIntFromPtr(std::unique_ptr<int> ptr, int* dst) {
31 *dst = *ptr;
32 }
33
TEST(GmockCallbackSupportTest,IsNullCallback)34 TEST(GmockCallbackSupportTest, IsNullCallback) {
35 MockFunction<void(const TestCallback&)> check;
36 EXPECT_CALL(check, Call(IsNullCallback()));
37 check.Call(TestCallback());
38 }
39
TEST(GmockCallbackSupportTest,IsNotNullCallback)40 TEST(GmockCallbackSupportTest, IsNotNullCallback) {
41 MockFunction<void(const TestCallback&)> check;
42 EXPECT_CALL(check, Call(IsNotNullCallback()));
43 check.Call(base::BindRepeating(&SetBool));
44 }
45
TEST(GmockCallbackSupportTest,IsNullOnceCallback)46 TEST(GmockCallbackSupportTest, IsNullOnceCallback) {
47 MockFunction<void(TestOnceCallback)> mock;
48 EXPECT_CALL(mock, Call(IsNullCallback()));
49 mock.Call(TestOnceCallback());
50 }
51
TEST(GmockCallbackSupportTest,IsNotNullOnceCallback)52 TEST(GmockCallbackSupportTest, IsNotNullOnceCallback) {
53 MockFunction<void(TestOnceCallback)> mock;
54 EXPECT_CALL(mock, Call(IsNotNullCallback()));
55 mock.Call(base::BindOnce(&SetBool));
56 }
57
TEST(GmockCallbackSupportTest,RunClosure0)58 TEST(GmockCallbackSupportTest, RunClosure0) {
59 MockFunction<void(const base::RepeatingClosure&)> check;
60 bool dst = false;
61 EXPECT_CALL(check, Call(IsNotNullCallback())).WillOnce(RunClosure<0>());
62 check.Call(base::BindRepeating(&SetBool, true, &dst));
63 EXPECT_TRUE(dst);
64 }
65
TEST(GmockCallbackSupportTest,RunClosureByRefNotReset)66 TEST(GmockCallbackSupportTest, RunClosureByRefNotReset) {
67 // Check that RepeatingClosure isn't reset by RunClosure<N>().
68 MockFunction<void(base::RepeatingClosure&)> check;
69 bool dst = false;
70 EXPECT_CALL(check, Call(IsNotNullCallback())).WillOnce(RunClosure<0>());
71 auto closure = base::BindRepeating(&SetBool, true, &dst);
72 check.Call(closure);
73 EXPECT_TRUE(dst);
74 EXPECT_FALSE(closure.is_null());
75 }
76
TEST(GmockCallbackSupportTest,RunCallback0)77 TEST(GmockCallbackSupportTest, RunCallback0) {
78 MockFunction<void(const TestCallback&)> check;
79 bool dst = false;
80 EXPECT_CALL(check, Call(IsNotNullCallback()))
81 .WillOnce(RunCallback<0>(true, &dst));
82 check.Call(base::BindRepeating(&SetBool));
83 EXPECT_TRUE(dst);
84 }
85
TEST(GmockCallbackSupportTest,RunCallback1)86 TEST(GmockCallbackSupportTest, RunCallback1) {
87 MockFunction<void(int, const TestCallback&)> check;
88 bool dst = false;
89 EXPECT_CALL(check, Call(0, IsNotNullCallback()))
90 .WillOnce(RunCallback<1>(true, &dst));
91 check.Call(0, base::BindRepeating(&SetBool));
92 EXPECT_TRUE(dst);
93 }
94
TEST(GmockCallbackSupportTest,RunCallbackPassByRef)95 TEST(GmockCallbackSupportTest, RunCallbackPassByRef) {
96 MockFunction<void(const TestCallback&)> check;
97 bool dst = false;
98 bool src = false;
99 EXPECT_CALL(check, Call(IsNotNullCallback()))
100 .WillOnce(RunCallback<0>(ByRef(src), &dst));
101 src = true;
102 check.Call(base::BindRepeating(&SetBool));
103 EXPECT_TRUE(dst);
104 }
105
TEST(GmockCallbackSupportTest,RunCallbackPassByValue)106 TEST(GmockCallbackSupportTest, RunCallbackPassByValue) {
107 MockFunction<void(const TestCallback&)> check;
108 bool dst = false;
109 bool src = true;
110 EXPECT_CALL(check, Call(IsNotNullCallback()))
111 .WillOnce(RunCallback<0>(src, &dst));
112 src = false;
113 check.Call(base::BindRepeating(&SetBool));
114 EXPECT_TRUE(dst);
115 }
116
TEST(GmockCallbackSupportTest,RunOnceClosure0)117 TEST(GmockCallbackSupportTest, RunOnceClosure0) {
118 MockFunction<void(base::OnceClosure)> check;
119 bool dst = false;
120 EXPECT_CALL(check, Call(IsNotNullCallback())).WillOnce(RunOnceClosure<0>());
121 check.Call(base::BindOnce(&SetBool, true, &dst));
122 EXPECT_TRUE(dst);
123 }
124
TEST(GmockCallbackSupportTest,RunOnceCallback0)125 TEST(GmockCallbackSupportTest, RunOnceCallback0) {
126 MockFunction<void(TestOnceCallback)> check;
127 bool dst = false;
128 bool src = true;
129 EXPECT_CALL(check, Call(IsNotNullCallback()))
130 .WillOnce(RunOnceCallback<0>(src, &dst));
131 src = false;
132 check.Call(base::BindOnce(&SetBool));
133 EXPECT_TRUE(dst);
134 }
135
TEST(GmockCallbackSupportTest,RunOnceCallbackTwice)136 TEST(GmockCallbackSupportTest, RunOnceCallbackTwice) {
137 MockFunction<void(TestOnceCallback)> check;
138 bool dst = false;
139 bool src = true;
140
141 EXPECT_CALL(check, Call)
142 .WillRepeatedly(RunOnceCallbackRepeatedly<0>(std::ref(src), &dst));
143
144 check.Call(base::BindOnce(&SetBool));
145 EXPECT_TRUE(dst);
146
147 src = false;
148 check.Call(base::BindOnce(&SetBool));
149 EXPECT_FALSE(dst);
150 }
151
TEST(GmockCallbackSupportTest,RunClosureValue)152 TEST(GmockCallbackSupportTest, RunClosureValue) {
153 MockFunction<void()> check;
154 bool dst = false;
155 EXPECT_CALL(check, Call())
156 .WillOnce(RunClosure(base::BindRepeating(&SetBool, true, &dst)));
157 check.Call();
158 EXPECT_TRUE(dst);
159 }
160
TEST(GmockCallbackSupportTest,RunClosureValueWithArgs)161 TEST(GmockCallbackSupportTest, RunClosureValueWithArgs) {
162 MockFunction<void(bool, int)> check;
163 bool dst = false;
164 EXPECT_CALL(check, Call(true, 42))
165 .WillOnce(RunClosure(base::BindRepeating(&SetBool, true, &dst)));
166 check.Call(true, 42);
167 EXPECT_TRUE(dst);
168 }
169
TEST(GmockCallbackSupportTest,RunOnceClosureValue)170 TEST(GmockCallbackSupportTest, RunOnceClosureValue) {
171 MockFunction<void()> check;
172 bool dst = false;
173 EXPECT_CALL(check, Call())
174 .WillOnce(RunOnceClosure(base::BindOnce(&SetBool, true, &dst)));
175 check.Call();
176 EXPECT_TRUE(dst);
177 }
178
TEST(GmockCallbackSupportTest,RunOnceClosureValueWithArgs)179 TEST(GmockCallbackSupportTest, RunOnceClosureValueWithArgs) {
180 MockFunction<void(bool, int)> check;
181 bool dst = false;
182 EXPECT_CALL(check, Call(true, 42))
183 .WillOnce(RunOnceClosure(base::BindOnce(&SetBool, true, &dst)));
184 check.Call(true, 42);
185 EXPECT_TRUE(dst);
186 }
187
TEST(GmockCallbackSupportTest,RunOnceClosureValueMultipleCall)188 TEST(GmockCallbackSupportTest, RunOnceClosureValueMultipleCall) {
189 MockFunction<void()> check;
190 bool dst = false;
191 EXPECT_CALL(check, Call())
192 .WillRepeatedly(RunOnceClosure(base::BindOnce(&SetBool, true, &dst)));
193 check.Call();
194 EXPECT_TRUE(dst);
195
196 // Invoking the RunOnceClosure action more than once will trigger a
197 // CHECK-failure.
198 dst = false;
199 EXPECT_DEATH_IF_SUPPORTED(check.Call(), "");
200 }
201
TEST(GmockCallbackSupportTest,RunOnceCallbackWithMoveOnlyType)202 TEST(GmockCallbackSupportTest, RunOnceCallbackWithMoveOnlyType) {
203 MockFunction<void(TestOnceCallbackMove)> check;
204 auto val = std::make_unique<int>(42);
205 int dst = 0;
206 EXPECT_CALL(check, Call).WillOnce(RunOnceCallback<0>(std::move(val), &dst));
207
208 check.Call(base::BindOnce(&SetIntFromPtr));
209
210 EXPECT_EQ(dst, 42);
211 EXPECT_FALSE(val);
212 }
213
TEST(GmockCallbackSupportTest,RunOnceCallbackMultipleTimesCrashes)214 TEST(GmockCallbackSupportTest, RunOnceCallbackMultipleTimesCrashes) {
215 MockFunction<void(TestOnceCallback)> check;
216 bool value = true;
217 bool dst = false;
218 EXPECT_CALL(check, Call).WillRepeatedly(RunOnceCallback<0>(value, &dst));
219
220 EXPECT_FALSE(dst);
221 check.Call(BindOnce(&SetBool));
222 EXPECT_TRUE(dst);
223
224 // The first `Call` has invalidated the captured args. Attempting
225 // to run `Call` again should result in a CHECK().
226 EXPECT_DEATH_IF_SUPPORTED(check.Call(BindOnce(&SetBool)), "");
227 }
228
TEST(GmockCallbackSupportTest,RunOnceCallbackReturnsValue)229 TEST(GmockCallbackSupportTest, RunOnceCallbackReturnsValue) {
230 MockFunction<int(base::OnceCallback<int(int)>)> check;
231 EXPECT_CALL(check, Call).WillRepeatedly(RunOnceCallbackRepeatedly<0>(42));
232 EXPECT_EQ(43, check.Call(base::BindOnce([](int i) { return i + 1; })));
233 EXPECT_EQ(44, check.Call(base::BindOnce([](int i) { return i + 2; })));
234 EXPECT_EQ(45, check.Call(base::BindOnce([](int i) { return i + 3; })));
235 }
236
TEST(GmockCallbackSupportTest,RunOnceCallbackReturnsValueMoveOnly)237 TEST(GmockCallbackSupportTest, RunOnceCallbackReturnsValueMoveOnly) {
238 MockFunction<int(base::OnceCallback<int(std::unique_ptr<int>)>)> check;
239 EXPECT_CALL(check, Call)
240 .WillOnce(RunOnceCallback<0>(std::make_unique<int>(42)));
241 EXPECT_EQ(43, check.Call(base::BindOnce(
242 [](std::unique_ptr<int> i) { return *i + 1; })));
243 }
244
TEST(GmockCallbackSupportTest,RunCallbackReturnsValue)245 TEST(GmockCallbackSupportTest, RunCallbackReturnsValue) {
246 MockFunction<int(base::RepeatingCallback<int(int)>)> check;
247 EXPECT_CALL(check, Call).WillRepeatedly(RunCallback<0>(42));
248 EXPECT_EQ(43, check.Call(base::BindRepeating([](int i) { return i + 1; })));
249 EXPECT_EQ(44, check.Call(base::BindRepeating([](int i) { return i + 2; })));
250 EXPECT_EQ(45, check.Call(base::BindRepeating([](int i) { return i + 3; })));
251 }
252
253 // Smoke test to validate that RunOnceCallback<> works with vectors of move-only
254 // args.
TEST(GmockCallbackSupportTest,VectorOfMoveOnlyArgs)255 TEST(GmockCallbackSupportTest, VectorOfMoveOnlyArgs) {
256 using VectorOfMoveOnly = std::vector<std::unique_ptr<std::string>>;
257 MockFunction<void(base::OnceCallback<void(VectorOfMoveOnly)>)> check;
258
259 EXPECT_CALL(check, Call).WillOnce(RunOnceCallback<0>([] {
260 return VectorOfMoveOnly();
261 }()));
262 check.Call(base::DoNothing());
263 }
264
265 } // namespace base::test
266