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