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/functional/callback.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/functional/bind.h"
11 #include "base/functional/callback_internal.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/notreached.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/test/bind.h"
17 #include "base/test/gtest_util.h"
18 #include "base/test/test_timeouts.h"
19 #include "base/threading/thread.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace base {
23
NopInvokeFunc()24 void NopInvokeFunc() {}
25
26 // White-box testpoints to inject into a callback object for checking
27 // comparators and emptiness APIs. Use a BindState that is specialized based on
28 // a type we declared in the anonymous namespace above to remove any chance of
29 // colliding with another instantiation and breaking the one-definition-rule.
30 struct FakeBindState : internal::BindStateBase {
FakeBindStatebase::FakeBindState31 FakeBindState() : BindStateBase(&NopInvokeFunc, &Destroy) {}
32
33 private:
34 ~FakeBindState() = default;
Destroybase::FakeBindState35 static void Destroy(const internal::BindStateBase* self) {
36 delete static_cast<const FakeBindState*>(self);
37 }
38 };
39
40 namespace {
41
42 class CallbackTest : public ::testing::Test {
43 public:
CallbackTest()44 CallbackTest()
45 : callback_a_(new FakeBindState()), callback_b_(new FakeBindState()) {}
46
47 ~CallbackTest() override = default;
48
49 protected:
50 RepeatingCallback<void()> callback_a_;
51 const RepeatingCallback<void()> callback_b_; // Ensure APIs work with const.
52 RepeatingCallback<void()> null_callback_;
53 };
54
TEST_F(CallbackTest,Types)55 TEST_F(CallbackTest, Types) {
56 static_assert(std::is_same_v<void, OnceClosure::ResultType>, "");
57 static_assert(std::is_same_v<void(), OnceClosure::RunType>, "");
58
59 using OnceCallbackT = OnceCallback<double(int, char)>;
60 static_assert(std::is_same_v<double, OnceCallbackT::ResultType>, "");
61 static_assert(std::is_same_v<double(int, char), OnceCallbackT::RunType>, "");
62
63 static_assert(std::is_same_v<void, RepeatingClosure::ResultType>, "");
64 static_assert(std::is_same_v<void(), RepeatingClosure::RunType>, "");
65
66 using RepeatingCallbackT = RepeatingCallback<bool(float, short)>;
67 static_assert(std::is_same_v<bool, RepeatingCallbackT::ResultType>, "");
68 static_assert(std::is_same_v<bool(float, short), RepeatingCallbackT::RunType>,
69 "");
70 }
71
72 // Ensure we can create unbound callbacks. We need this to be able to store
73 // them in class members that can be initialized later.
TEST_F(CallbackTest,DefaultConstruction)74 TEST_F(CallbackTest, DefaultConstruction) {
75 RepeatingCallback<void()> c0;
76 RepeatingCallback<void(int)> c1;
77 RepeatingCallback<void(int, int)> c2;
78 RepeatingCallback<void(int, int, int)> c3;
79 RepeatingCallback<void(int, int, int, int)> c4;
80 RepeatingCallback<void(int, int, int, int, int)> c5;
81 RepeatingCallback<void(int, int, int, int, int, int)> c6;
82
83 EXPECT_TRUE(c0.is_null());
84 EXPECT_TRUE(c1.is_null());
85 EXPECT_TRUE(c2.is_null());
86 EXPECT_TRUE(c3.is_null());
87 EXPECT_TRUE(c4.is_null());
88 EXPECT_TRUE(c5.is_null());
89 EXPECT_TRUE(c6.is_null());
90 }
91
TEST_F(CallbackTest,IsNull)92 TEST_F(CallbackTest, IsNull) {
93 EXPECT_TRUE(null_callback_.is_null());
94 EXPECT_FALSE(callback_a_.is_null());
95 EXPECT_FALSE(callback_b_.is_null());
96 }
97
TEST_F(CallbackTest,Equals)98 TEST_F(CallbackTest, Equals) {
99 EXPECT_EQ(callback_a_, callback_a_);
100 EXPECT_NE(callback_a_, callback_b_);
101 EXPECT_NE(callback_b_, callback_a_);
102
103 // We should compare based on instance, not type.
104 RepeatingCallback<void()> callback_c(new FakeBindState());
105 RepeatingCallback<void()> callback_a2 = callback_a_;
106 EXPECT_EQ(callback_a_, callback_a2);
107 EXPECT_NE(callback_a_, callback_c);
108
109 // Empty, however, is always equal to empty.
110 RepeatingCallback<void()> empty2;
111 EXPECT_EQ(null_callback_, empty2);
112 }
113
TEST_F(CallbackTest,Reset)114 TEST_F(CallbackTest, Reset) {
115 // Resetting should bring us back to empty.
116 ASSERT_FALSE(callback_a_.is_null());
117 EXPECT_NE(callback_a_, null_callback_);
118
119 callback_a_.Reset();
120
121 EXPECT_TRUE(callback_a_.is_null());
122 EXPECT_EQ(callback_a_, null_callback_);
123 }
124
TEST_F(CallbackTest,Move)125 TEST_F(CallbackTest, Move) {
126 // Moving should reset the callback.
127 ASSERT_FALSE(callback_a_.is_null());
128 EXPECT_NE(callback_a_, null_callback_);
129
130 auto tmp = std::move(callback_a_);
131
132 EXPECT_TRUE(callback_a_.is_null());
133 EXPECT_EQ(callback_a_, null_callback_);
134 }
135
TEST_F(CallbackTest,NullAfterMoveRun)136 TEST_F(CallbackTest, NullAfterMoveRun) {
137 RepeatingCallback<void(void*)> cb = BindRepeating([](void* param) {
138 EXPECT_TRUE(static_cast<RepeatingCallback<void(void*)>*>(param)->is_null());
139 });
140 ASSERT_TRUE(cb);
141 std::move(cb).Run(&cb);
142 EXPECT_FALSE(cb);
143
144 const RepeatingClosure cb2 = BindRepeating([] {});
145 ASSERT_TRUE(cb2);
146 std::move(cb2).Run();
147 EXPECT_TRUE(cb2);
148
149 OnceCallback<void(void*)> cb3 = BindOnce([](void* param) {
150 EXPECT_TRUE(static_cast<OnceCallback<void(void*)>*>(param)->is_null());
151 });
152 ASSERT_TRUE(cb3);
153 std::move(cb3).Run(&cb3);
154 EXPECT_FALSE(cb3);
155 }
156
TEST_F(CallbackTest,MaybeValidReturnsTrue)157 TEST_F(CallbackTest, MaybeValidReturnsTrue) {
158 RepeatingCallback<void()> cb = BindRepeating([]() {});
159 // By default, MaybeValid() just returns true all the time.
160 EXPECT_TRUE(cb.MaybeValid());
161 cb.Run();
162 EXPECT_TRUE(cb.MaybeValid());
163 }
164
TEST_F(CallbackTest,ThenResetsOriginalCallback)165 TEST_F(CallbackTest, ThenResetsOriginalCallback) {
166 {
167 // OnceCallback::Then() always destroys the original callback.
168 OnceClosure orig = base::BindOnce([]() {});
169 EXPECT_TRUE(!!orig);
170 OnceClosure joined = std::move(orig).Then(base::BindOnce([]() {}));
171 EXPECT_TRUE(!!joined);
172 EXPECT_FALSE(!!orig);
173 }
174 {
175 // RepeatingCallback::Then() destroys the original callback if it's an
176 // rvalue.
177 RepeatingClosure orig = base::BindRepeating([]() {});
178 EXPECT_TRUE(!!orig);
179 RepeatingClosure joined =
180 std::move(orig).Then(base::BindRepeating([]() {}));
181 EXPECT_TRUE(!!joined);
182 EXPECT_FALSE(!!orig);
183 }
184 {
185 // RepeatingCallback::Then() doesn't destroy the original callback if it's
186 // not an rvalue.
187 RepeatingClosure orig = base::BindRepeating([]() {});
188 RepeatingClosure copy = orig;
189 EXPECT_TRUE(!!orig);
190 RepeatingClosure joined = orig.Then(base::BindRepeating([]() {}));
191 EXPECT_TRUE(!!joined);
192 EXPECT_TRUE(!!orig);
193 // The original callback is not changed.
194 EXPECT_EQ(orig, copy);
195 EXPECT_NE(joined, copy);
196 }
197 }
198
199 // A RepeatingCallback will implicitly convert to a OnceCallback, so a
200 // once_callback.Then(repeating_callback) should turn into a OnceCallback
201 // that holds 2 OnceCallbacks which it will run.
TEST_F(CallbackTest,ThenCanConvertRepeatingToOnce)202 TEST_F(CallbackTest, ThenCanConvertRepeatingToOnce) {
203 {
204 RepeatingClosure repeating_closure = base::BindRepeating([]() {});
205 OnceClosure once_closure = base::BindOnce([]() {});
206 std::move(once_closure).Then(repeating_closure).Run();
207
208 RepeatingCallback<int(int)> repeating_callback =
209 base::BindRepeating([](int i) { return i + 1; });
210 OnceCallback<int(int)> once_callback =
211 base::BindOnce([](int i) { return i * 2; });
212 EXPECT_EQ(3, std::move(once_callback).Then(repeating_callback).Run(1));
213 }
214 {
215 RepeatingClosure repeating_closure = base::BindRepeating([]() {});
216 OnceClosure once_closure = base::BindOnce([]() {});
217 std::move(once_closure).Then(std::move(repeating_closure)).Run();
218
219 RepeatingCallback<int(int)> repeating_callback =
220 base::BindRepeating([](int i) { return i + 1; });
221 OnceCallback<int(int)> once_callback =
222 base::BindOnce([](int i) { return i * 2; });
223 EXPECT_EQ(
224 3, std::move(once_callback).Then(std::move(repeating_callback)).Run(1));
225 }
226 }
227
228 // `Then()` should should allow a return value of type `R` to be passed to a
229 // callback with one parameter of type `const R&` or type `R&&`.
TEST_F(CallbackTest,ThenWithCompatibleButNotSameType)230 TEST_F(CallbackTest, ThenWithCompatibleButNotSameType) {
231 {
232 OnceCallback<std::string()> once_callback =
233 BindOnce([] { return std::string("hello"); });
234 EXPECT_EQ("hello",
235 std::move(once_callback)
236 .Then(BindOnce([](const std::string& s) { return s; }))
237 .Run());
238 }
239
240 class NotCopied {
241 public:
242 NotCopied() = default;
243 NotCopied(NotCopied&&) = default;
244 NotCopied& operator=(NotCopied&&) = default;
245
246 NotCopied(const NotCopied&) {
247 ADD_FAILURE() << "should not have been copied";
248 }
249
250 NotCopied& operator=(const NotCopied&) {
251 ADD_FAILURE() << "should not have been copied";
252 return *this;
253 }
254 };
255
256 {
257 OnceCallback<NotCopied()> once_callback =
258 BindOnce([] { return NotCopied(); });
259 std::move(once_callback).Then(BindOnce([](const NotCopied&) {})).Run();
260 }
261
262 {
263 OnceCallback<NotCopied()> once_callback =
264 BindOnce([] { return NotCopied(); });
265 std::move(once_callback).Then(BindOnce([](NotCopied&&) {})).Run();
266 }
267 }
268
269 // A factory class for building an outer and inner callback for calling
270 // Then() on either a OnceCallback or RepeatingCallback with combinations of
271 // void return types, non-void, and move-only return types.
272 template <bool use_once, typename R, typename ThenR, typename... Args>
273 class CallbackThenTest;
274 template <bool use_once, typename R, typename ThenR, typename... Args>
275 class CallbackThenTest<use_once, R(Args...), ThenR> {
276 public:
277 using CallbackType =
278 typename std::conditional<use_once,
279 OnceCallback<R(Args...)>,
280 RepeatingCallback<R(Args...)>>::type;
281 using ThenType =
282 typename std::conditional<use_once, OnceClosure, RepeatingClosure>::type;
283
284 // Gets the Callback that will have Then() called on it. Has a return type
285 // of `R`, which would chain to the inner callback for Then(). Has inputs of
286 // type `Args...`.
GetOuter(std::string & s)287 static auto GetOuter(std::string& s) {
288 s = "";
289 return Bind(
290 [](std::string* s, Args... args) {
291 return Outer(s, std::forward<Args>(args)...);
292 },
293 &s);
294 }
295 // Gets the Callback that will be passed to Then(). Has a return type of
296 // `ThenR`, specified for the class instance. Receives as input the return
297 // type `R` from the function bound and returned in GetOuter().
GetInner(std::string & s)298 static auto GetInner(std::string& s) { return Bind(&Inner<R, ThenR>, &s); }
299
300 private:
301 template <bool bind_once = use_once,
302 typename F,
303 typename... FArgs,
304 std::enable_if_t<bind_once, int> = 0>
Bind(F function,FArgs...args)305 static auto Bind(F function, FArgs... args) {
306 return BindOnce(function, std::forward<FArgs>(args)...);
307 }
308 template <bool bind_once = use_once,
309 typename F,
310 typename... FArgs,
311 std::enable_if_t<!bind_once, int> = 0>
Bind(F function,FArgs...args)312 static auto Bind(F function, FArgs... args) {
313 return BindRepeating(function, std::forward<FArgs>(args)...);
314 }
315
316 template <typename R2 = R, std::enable_if_t<!std::is_void_v<R2>, int> = 0>
Outer(std::string * s,std::unique_ptr<int> a,std::unique_ptr<int> b)317 static int Outer(std::string* s,
318 std::unique_ptr<int> a,
319 std::unique_ptr<int> b) {
320 *s += "Outer";
321 *s += base::NumberToString(*a) + base::NumberToString(*b);
322 return *a + *b;
323 }
324 template <typename R2 = R, std::enable_if_t<!std::is_void_v<R2>, int> = 0>
Outer(std::string * s,int a,int b)325 static int Outer(std::string* s, int a, int b) {
326 *s += "Outer";
327 *s += base::NumberToString(a) + base::NumberToString(b);
328 return a + b;
329 }
330 template <typename R2 = R, std::enable_if_t<!std::is_void_v<R2>, int> = 0>
Outer(std::string * s)331 static int Outer(std::string* s) {
332 *s += "Outer";
333 *s += "None";
334 return 99;
335 }
336
337 template <typename R2 = R, std::enable_if_t<std::is_void_v<R2>, int> = 0>
Outer(std::string * s,std::unique_ptr<int> a,std::unique_ptr<int> b)338 static void Outer(std::string* s,
339 std::unique_ptr<int> a,
340 std::unique_ptr<int> b) {
341 *s += "Outer";
342 *s += base::NumberToString(*a) + base::NumberToString(*b);
343 }
344 template <typename R2 = R, std::enable_if_t<std::is_void_v<R2>, int> = 0>
Outer(std::string * s,int a,int b)345 static void Outer(std::string* s, int a, int b) {
346 *s += "Outer";
347 *s += base::NumberToString(a) + base::NumberToString(b);
348 }
349 template <typename R2 = R, std::enable_if_t<std::is_void_v<R2>, int> = 0>
Outer(std::string * s)350 static void Outer(std::string* s) {
351 *s += "Outer";
352 *s += "None";
353 }
354
355 template <typename OuterR,
356 typename InnerR,
357 std::enable_if_t<!std::is_void_v<OuterR>, int> = 0,
358 std::enable_if_t<!std::is_void_v<InnerR>, int> = 0>
Inner(std::string * s,OuterR a)359 static int Inner(std::string* s, OuterR a) {
360 static_assert(std::is_same_v<InnerR, int>, "Use int return type");
361 *s += "Inner";
362 *s += base::NumberToString(a);
363 return a;
364 }
365 template <typename OuterR,
366 typename InnerR,
367 std::enable_if_t<std::is_void_v<OuterR>, int> = 0,
368 std::enable_if_t<!std::is_void_v<InnerR>, int> = 0>
Inner(std::string * s)369 static int Inner(std::string* s) {
370 static_assert(std::is_same_v<InnerR, int>, "Use int return type");
371 *s += "Inner";
372 *s += "None";
373 return 99;
374 }
375
376 template <typename OuterR,
377 typename InnerR,
378 std::enable_if_t<!std::is_void_v<OuterR>, int> = 0,
379 std::enable_if_t<std::is_void_v<InnerR>, int> = 0>
Inner(std::string * s,OuterR a)380 static void Inner(std::string* s, OuterR a) {
381 *s += "Inner";
382 *s += base::NumberToString(a);
383 }
384 template <typename OuterR,
385 typename InnerR,
386 std::enable_if_t<std::is_void_v<OuterR>, int> = 0,
387 std::enable_if_t<std::is_void_v<InnerR>, int> = 0>
Inner(std::string * s)388 static void Inner(std::string* s) {
389 *s += "Inner";
390 *s += "None";
391 }
392 };
393
394 template <typename R, typename ThenR = void, typename... Args>
395 using CallbackThenOnceTest = CallbackThenTest<true, R, ThenR, Args...>;
396 template <typename R, typename ThenR = void, typename... Args>
397 using CallbackThenRepeatingTest = CallbackThenTest<false, R, ThenR, Args...>;
398
TEST_F(CallbackTest,ThenOnce)399 TEST_F(CallbackTest, ThenOnce) {
400 std::string s;
401
402 // Void return from outer + void return from Then().
403 {
404 using VoidReturnWithoutArgs = void();
405 using ThenReturn = void;
406 using Test = CallbackThenOnceTest<VoidReturnWithoutArgs, ThenReturn>;
407 Test::GetOuter(s).Then(Test::GetInner(s)).Run();
408 EXPECT_EQ(s, "OuterNoneInnerNone");
409 }
410 {
411 using VoidReturnWithArgs = void(int, int);
412 using ThenReturn = void;
413 using Test = CallbackThenOnceTest<VoidReturnWithArgs, ThenReturn>;
414 Test::GetOuter(s).Then(Test::GetInner(s)).Run(1, 2);
415 EXPECT_EQ(s, "Outer12InnerNone");
416 }
417 {
418 using VoidReturnWithMoveOnlyArgs =
419 void(std::unique_ptr<int>, std::unique_ptr<int>);
420 using ThenReturn = void;
421 using Test = CallbackThenOnceTest<VoidReturnWithMoveOnlyArgs, ThenReturn>;
422 Test::GetOuter(s)
423 .Then(Test::GetInner(s))
424 .Run(std::make_unique<int>(1), std::make_unique<int>(2));
425 EXPECT_EQ(s, "Outer12InnerNone");
426 }
427
428 // Void return from outer + non-void return from Then().
429 {
430 using VoidReturnWithoutArgs = void();
431 using ThenReturn = int;
432 using Test = CallbackThenOnceTest<VoidReturnWithoutArgs, ThenReturn>;
433 EXPECT_EQ(99, Test::GetOuter(s).Then(Test::GetInner(s)).Run());
434 EXPECT_EQ(s, "OuterNoneInnerNone");
435 }
436 {
437 using VoidReturnWithArgs = void(int, int);
438 using ThenReturn = int;
439 using Test = CallbackThenOnceTest<VoidReturnWithArgs, ThenReturn>;
440 EXPECT_EQ(99, Test::GetOuter(s).Then(Test::GetInner(s)).Run(1, 2));
441 EXPECT_EQ(s, "Outer12InnerNone");
442 }
443 {
444 using VoidReturnWithMoveOnlyArgs =
445 void(std::unique_ptr<int>, std::unique_ptr<int>);
446 using ThenReturn = int;
447 using Test = CallbackThenOnceTest<VoidReturnWithMoveOnlyArgs, ThenReturn>;
448 EXPECT_EQ(99, Test::GetOuter(s)
449 .Then(Test::GetInner(s))
450 .Run(std::make_unique<int>(1), std::make_unique<int>(2)));
451 EXPECT_EQ(s, "Outer12InnerNone");
452 }
453
454 // Non-void return from outer + void return from Then().
455 {
456 using NonVoidReturnWithoutArgs = int();
457 using ThenReturn = void;
458 using Test = CallbackThenOnceTest<NonVoidReturnWithoutArgs, ThenReturn>;
459 Test::GetOuter(s).Then(Test::GetInner(s)).Run();
460 EXPECT_EQ(s, "OuterNoneInner99");
461 }
462 {
463 using NonVoidReturnWithArgs = int(int, int);
464 using ThenReturn = void;
465 using Test = CallbackThenOnceTest<NonVoidReturnWithArgs, ThenReturn>;
466 Test::GetOuter(s).Then(Test::GetInner(s)).Run(1, 2);
467 EXPECT_EQ(s, "Outer12Inner3");
468 }
469 {
470 using NonVoidReturnWithMoveOnlyArgs =
471 int(std::unique_ptr<int>, std::unique_ptr<int>);
472 using ThenReturn = void;
473 using Test =
474 CallbackThenOnceTest<NonVoidReturnWithMoveOnlyArgs, ThenReturn>;
475 Test::GetOuter(s)
476 .Then(Test::GetInner(s))
477 .Run(std::make_unique<int>(1), std::make_unique<int>(2));
478 EXPECT_EQ(s, "Outer12Inner3");
479 }
480
481 // Non-void return from outer + non-void return from Then().
482 {
483 using NonVoidReturnWithoutArgs = int();
484 using ThenReturn = int;
485 using Test = CallbackThenOnceTest<NonVoidReturnWithoutArgs, ThenReturn>;
486 EXPECT_EQ(99, Test::GetOuter(s).Then(Test::GetInner(s)).Run());
487 EXPECT_EQ(s, "OuterNoneInner99");
488 }
489 {
490 using NonVoidReturnWithArgs = int(int, int);
491 using ThenReturn = int;
492 using Test = CallbackThenOnceTest<NonVoidReturnWithArgs, ThenReturn>;
493 EXPECT_EQ(3, Test::GetOuter(s).Then(Test::GetInner(s)).Run(1, 2));
494 EXPECT_EQ(s, "Outer12Inner3");
495 }
496 {
497 using NonVoidReturnWithMoveOnlyArgs =
498 int(std::unique_ptr<int>, std::unique_ptr<int>);
499 using ThenReturn = int;
500 using Test =
501 CallbackThenOnceTest<NonVoidReturnWithMoveOnlyArgs, ThenReturn>;
502 EXPECT_EQ(3, Test::GetOuter(s)
503 .Then(Test::GetInner(s))
504 .Run(std::make_unique<int>(1), std::make_unique<int>(2)));
505 EXPECT_EQ(s, "Outer12Inner3");
506 }
507 }
508
TEST_F(CallbackTest,ThenRepeating)509 TEST_F(CallbackTest, ThenRepeating) {
510 std::string s;
511
512 // Void return from outer + void return from Then().
513 {
514 using VoidReturnWithoutArgs = void();
515 using ThenReturn = void;
516 using Test = CallbackThenRepeatingTest<VoidReturnWithoutArgs, ThenReturn>;
517 auto outer = Test::GetOuter(s);
518 outer.Then(Test::GetInner(s)).Run();
519 EXPECT_EQ(s, "OuterNoneInnerNone");
520 std::move(outer).Then(Test::GetInner(s)).Run();
521 EXPECT_EQ(s, "OuterNoneInnerNoneOuterNoneInnerNone");
522 }
523 {
524 using VoidReturnWithArgs = void(int, int);
525 using ThenReturn = void;
526 using Test = CallbackThenRepeatingTest<VoidReturnWithArgs, ThenReturn>;
527 auto outer = Test::GetOuter(s);
528 outer.Then(Test::GetInner(s)).Run(1, 2);
529 EXPECT_EQ(s, "Outer12InnerNone");
530 std::move(outer).Then(Test::GetInner(s)).Run(1, 2);
531 EXPECT_EQ(s, "Outer12InnerNoneOuter12InnerNone");
532 }
533 {
534 using VoidReturnWithMoveOnlyArgs =
535 void(std::unique_ptr<int>, std::unique_ptr<int>);
536 using ThenReturn = void;
537 using Test =
538 CallbackThenRepeatingTest<VoidReturnWithMoveOnlyArgs, ThenReturn>;
539 auto outer = Test::GetOuter(s);
540 outer.Then(Test::GetInner(s))
541 .Run(std::make_unique<int>(1), std::make_unique<int>(2));
542 EXPECT_EQ(s, "Outer12InnerNone");
543 std::move(outer)
544 .Then(Test::GetInner(s))
545 .Run(std::make_unique<int>(1), std::make_unique<int>(2));
546 EXPECT_EQ(s, "Outer12InnerNoneOuter12InnerNone");
547 }
548
549 // Void return from outer + non-void return from Then().
550 {
551 using VoidReturnWithoutArgs = void();
552 using ThenReturn = int;
553 using Test = CallbackThenRepeatingTest<VoidReturnWithoutArgs, ThenReturn>;
554 auto outer = Test::GetOuter(s);
555 EXPECT_EQ(99, outer.Then(Test::GetInner(s)).Run());
556 EXPECT_EQ(s, "OuterNoneInnerNone");
557 EXPECT_EQ(99, std::move(outer).Then(Test::GetInner(s)).Run());
558 EXPECT_EQ(s, "OuterNoneInnerNoneOuterNoneInnerNone");
559 }
560 {
561 using VoidReturnWithArgs = void(int, int);
562 using ThenReturn = int;
563 using Test = CallbackThenRepeatingTest<VoidReturnWithArgs, ThenReturn>;
564 auto outer = Test::GetOuter(s);
565 EXPECT_EQ(99, outer.Then(Test::GetInner(s)).Run(1, 2));
566 EXPECT_EQ(s, "Outer12InnerNone");
567 EXPECT_EQ(99, std::move(outer).Then(Test::GetInner(s)).Run(1, 2));
568 EXPECT_EQ(s, "Outer12InnerNoneOuter12InnerNone");
569 }
570 {
571 using VoidReturnWithMoveOnlyArgs =
572 void(std::unique_ptr<int>, std::unique_ptr<int>);
573 using ThenReturn = int;
574 using Test =
575 CallbackThenRepeatingTest<VoidReturnWithMoveOnlyArgs, ThenReturn>;
576 auto outer = Test::GetOuter(s);
577 EXPECT_EQ(99, outer.Then(Test::GetInner(s))
578 .Run(std::make_unique<int>(1), std::make_unique<int>(2)));
579 EXPECT_EQ(s, "Outer12InnerNone");
580 EXPECT_EQ(99, std::move(outer)
581 .Then(Test::GetInner(s))
582 .Run(std::make_unique<int>(1), std::make_unique<int>(2)));
583 EXPECT_EQ(s, "Outer12InnerNoneOuter12InnerNone");
584 }
585
586 // Non-void return from outer + void return from Then().
587 {
588 using NonVoidReturnWithoutArgs = int();
589 using ThenReturn = void;
590 using Test =
591 CallbackThenRepeatingTest<NonVoidReturnWithoutArgs, ThenReturn>;
592 auto outer = Test::GetOuter(s);
593 outer.Then(Test::GetInner(s)).Run();
594 EXPECT_EQ(s, "OuterNoneInner99");
595 std::move(outer).Then(Test::GetInner(s)).Run();
596 EXPECT_EQ(s, "OuterNoneInner99OuterNoneInner99");
597 }
598 {
599 using NonVoidReturnWithArgs = int(int, int);
600 using ThenReturn = void;
601 using Test = CallbackThenRepeatingTest<NonVoidReturnWithArgs, ThenReturn>;
602 auto outer = Test::GetOuter(s);
603 outer.Then(Test::GetInner(s)).Run(1, 2);
604 EXPECT_EQ(s, "Outer12Inner3");
605 std::move(outer).Then(Test::GetInner(s)).Run(1, 2);
606 EXPECT_EQ(s, "Outer12Inner3Outer12Inner3");
607 }
608 {
609 using NonVoidReturnWithMoveOnlyArgs =
610 int(std::unique_ptr<int>, std::unique_ptr<int>);
611 using ThenReturn = void;
612 using Test =
613 CallbackThenRepeatingTest<NonVoidReturnWithMoveOnlyArgs, ThenReturn>;
614 auto outer = Test::GetOuter(s);
615 outer.Then(Test::GetInner(s))
616 .Run(std::make_unique<int>(1), std::make_unique<int>(2));
617 EXPECT_EQ(s, "Outer12Inner3");
618 std::move(outer)
619 .Then(Test::GetInner(s))
620 .Run(std::make_unique<int>(1), std::make_unique<int>(2));
621 EXPECT_EQ(s, "Outer12Inner3Outer12Inner3");
622 }
623
624 // Non-void return from outer + non-void return from Then().
625 {
626 using NonVoidReturnWithoutArgs = int();
627 using ThenReturn = int;
628 using Test =
629 CallbackThenRepeatingTest<NonVoidReturnWithoutArgs, ThenReturn>;
630 auto outer = Test::GetOuter(s);
631 EXPECT_EQ(99, outer.Then(Test::GetInner(s)).Run());
632 EXPECT_EQ(s, "OuterNoneInner99");
633 EXPECT_EQ(99, std::move(outer).Then(Test::GetInner(s)).Run());
634 EXPECT_EQ(s, "OuterNoneInner99OuterNoneInner99");
635 }
636 {
637 using NonVoidReturnWithArgs = int(int, int);
638 using ThenReturn = int;
639 using Test = CallbackThenRepeatingTest<NonVoidReturnWithArgs, ThenReturn>;
640 auto outer = Test::GetOuter(s);
641 EXPECT_EQ(3, outer.Then(Test::GetInner(s)).Run(1, 2));
642 EXPECT_EQ(s, "Outer12Inner3");
643 EXPECT_EQ(3, std::move(outer).Then(Test::GetInner(s)).Run(1, 2));
644 EXPECT_EQ(s, "Outer12Inner3Outer12Inner3");
645 }
646 {
647 using NonVoidReturnWithMoveOnlyArgs =
648 int(std::unique_ptr<int>, std::unique_ptr<int>);
649 using ThenReturn = int;
650 using Test =
651 CallbackThenRepeatingTest<NonVoidReturnWithMoveOnlyArgs, ThenReturn>;
652 auto outer = Test::GetOuter(s);
653 EXPECT_EQ(3, outer.Then(Test::GetInner(s))
654 .Run(std::make_unique<int>(1), std::make_unique<int>(2)));
655 EXPECT_EQ(s, "Outer12Inner3");
656 EXPECT_EQ(3, std::move(outer)
657 .Then(Test::GetInner(s))
658 .Run(std::make_unique<int>(1), std::make_unique<int>(2)));
659 EXPECT_EQ(s, "Outer12Inner3Outer12Inner3");
660 }
661 }
662
663 // WeakPtr detection in BindRepeating() requires a method, not just any
664 // function.
665 class ClassWithAMethod {
666 public:
TheMethod()667 void TheMethod() { method_called = true; }
668
669 bool method_called = false;
670 };
671
TEST_F(CallbackTest,MaybeValidInvalidateWeakPtrsOnSameSequence)672 TEST_F(CallbackTest, MaybeValidInvalidateWeakPtrsOnSameSequence) {
673 ClassWithAMethod obj;
674 WeakPtrFactory<ClassWithAMethod> factory(&obj);
675 WeakPtr<ClassWithAMethod> ptr = factory.GetWeakPtr();
676
677 RepeatingCallback<void()> cb =
678 BindRepeating(&ClassWithAMethod::TheMethod, ptr);
679 EXPECT_TRUE(cb.MaybeValid());
680 EXPECT_FALSE(cb.IsCancelled());
681
682 factory.InvalidateWeakPtrs();
683 // MaybeValid() should be false and IsCancelled() should become true because
684 // InvalidateWeakPtrs() was called on the same thread.
685 EXPECT_FALSE(cb.MaybeValid());
686 EXPECT_TRUE(cb.IsCancelled());
687 // is_null() is not affected by the invalidated WeakPtr.
688 EXPECT_FALSE(cb.is_null());
689 }
690
TEST_F(CallbackTest,MaybeValidInvalidateWeakPtrsOnOtherSequence)691 TEST_F(CallbackTest, MaybeValidInvalidateWeakPtrsOnOtherSequence) {
692 ClassWithAMethod obj;
693 WeakPtrFactory<ClassWithAMethod> factory(&obj);
694 WeakPtr<ClassWithAMethod> ptr = factory.GetWeakPtr();
695
696 RepeatingCallback<void()> cb =
697 BindRepeating(&ClassWithAMethod::TheMethod, ptr);
698 EXPECT_TRUE(cb.MaybeValid());
699
700 Thread other_thread("other_thread");
701 other_thread.StartAndWaitForTesting();
702 other_thread.task_runner()->PostTask(
703 FROM_HERE,
704 BindOnce(
705 [](RepeatingCallback<void()> cb) {
706 // Check that MaybeValid() _eventually_ returns false.
707 const TimeDelta timeout = TestTimeouts::tiny_timeout();
708 const TimeTicks begin = TimeTicks::Now();
709 while (cb.MaybeValid() && (TimeTicks::Now() - begin) < timeout)
710 PlatformThread::YieldCurrentThread();
711 EXPECT_FALSE(cb.MaybeValid());
712 },
713 cb));
714 factory.InvalidateWeakPtrs();
715 // |other_thread|'s destructor will join, ensuring we wait for the task to be
716 // run.
717 }
718
TEST_F(CallbackTest,ThenAfterWeakPtr)719 TEST_F(CallbackTest, ThenAfterWeakPtr) {
720 ClassWithAMethod obj;
721 WeakPtrFactory<ClassWithAMethod> factory(&obj);
722 WeakPtr<ClassWithAMethod> ptr = factory.GetWeakPtr();
723
724 // If the first callback of a chain is skipped due to InvalidateWeakPtrs(),
725 // the remaining callbacks should still run.
726 bool chained_closure_called = false;
727 OnceClosure closure =
728 BindOnce(&ClassWithAMethod::TheMethod, ptr)
729 .Then(BindLambdaForTesting(
730 [&chained_closure_called] { chained_closure_called = true; }));
731 factory.InvalidateWeakPtrs();
732 std::move(closure).Run();
733 EXPECT_FALSE(obj.method_called);
734 EXPECT_TRUE(chained_closure_called);
735 }
736
737 class CallbackOwner : public base::RefCounted<CallbackOwner> {
738 public:
CallbackOwner(bool * deleted)739 explicit CallbackOwner(bool* deleted) {
740 // WrapRefCounted() here is needed to avoid the check failure in the
741 // BindRepeating implementation, that refuses to create the first reference
742 // to ref-counted objects.
743 callback_ = BindRepeating(&CallbackOwner::Unused, WrapRefCounted(this));
744 deleted_ = deleted;
745 }
Reset()746 void Reset() {
747 callback_.Reset();
748 // We are deleted here if no-one else had a ref to us.
749 }
750
751 private:
752 friend class base::RefCounted<CallbackOwner>;
~CallbackOwner()753 virtual ~CallbackOwner() { *deleted_ = true; }
Unused()754 void Unused() { FAIL() << "Should never be called"; }
755
756 RepeatingClosure callback_;
757 raw_ptr<bool> deleted_;
758 };
759
TEST_F(CallbackTest,CallbackHasLastRefOnContainingObject)760 TEST_F(CallbackTest, CallbackHasLastRefOnContainingObject) {
761 bool deleted = false;
762 CallbackOwner* owner = new CallbackOwner(&deleted);
763 owner->Reset();
764 ASSERT_TRUE(deleted);
765 }
766
767 // According to legends, it is good practice to put death tests into their own
768 // test suite, so they are grouped separately from regular tests, since death
769 // tests are somewhat slow and have quirks that can slow down test running if
770 // intermixed.
TEST(CallbackDeathTest,RunNullCallbackChecks)771 TEST(CallbackDeathTest, RunNullCallbackChecks) {
772 {
773 base::OnceClosure closure;
774 EXPECT_CHECK_DEATH(std::move(closure).Run());
775 }
776
777 {
778 base::RepeatingClosure closure;
779 EXPECT_CHECK_DEATH(std::move(closure).Run());
780 }
781
782 {
783 base::RepeatingClosure closure;
784 EXPECT_CHECK_DEATH(closure.Run());
785 }
786 }
787
788 } // namespace
789 } // namespace base
790