OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
16 #include "base/test/gtest_util.h" | 16 #include "base/test/gtest_util.h" |
17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
18 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
20 | 20 |
21 using ::testing::_; | 21 using ::testing::_; |
22 using ::testing::Mock; | 22 using ::testing::Mock; |
| 23 using ::testing::ByMove; |
23 using ::testing::Return; | 24 using ::testing::Return; |
24 using ::testing::StrictMock; | 25 using ::testing::StrictMock; |
25 | 26 |
26 namespace base { | 27 namespace base { |
27 | 28 |
28 using internal::OnceCallback; | 29 using internal::OnceCallback; |
29 using internal::RepeatingCallback; | 30 using internal::RepeatingCallback; |
30 using internal::OnceClosure; | 31 using internal::OnceClosure; |
31 using internal::RepeatingClosure; | 32 using internal::RepeatingClosure; |
32 using internal::BindOnce; | 33 using internal::BindOnce; |
33 using internal::BindRepeating; | 34 using internal::BindRepeating; |
34 | 35 |
35 namespace { | 36 namespace { |
36 | 37 |
37 class IncompleteType; | 38 class IncompleteType; |
38 | 39 |
39 class NoRef { | 40 class NoRef { |
40 public: | 41 public: |
41 NoRef() {} | 42 NoRef() {} |
42 | 43 |
43 MOCK_METHOD0(VoidMethod0, void()); | 44 MOCK_METHOD0(VoidMethod0, void()); |
44 MOCK_CONST_METHOD0(VoidConstMethod0, void()); | 45 MOCK_CONST_METHOD0(VoidConstMethod0, void()); |
45 | 46 |
46 MOCK_METHOD0(IntMethod0, int()); | 47 MOCK_METHOD0(IntMethod0, int()); |
47 MOCK_CONST_METHOD0(IntConstMethod0, int()); | 48 MOCK_CONST_METHOD0(IntConstMethod0, int()); |
48 | 49 |
49 MOCK_METHOD1(VoidMethodWithIntArg, void(int)); | 50 MOCK_METHOD1(VoidMethodWithIntArg, void(int)); |
| 51 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>()); |
50 | 52 |
51 private: | 53 private: |
52 // Particularly important in this test to ensure no copies are made. | 54 // Particularly important in this test to ensure no copies are made. |
53 DISALLOW_COPY_AND_ASSIGN(NoRef); | 55 DISALLOW_COPY_AND_ASSIGN(NoRef); |
54 }; | 56 }; |
55 | 57 |
56 class HasRef : public NoRef { | 58 class HasRef : public NoRef { |
57 public: | 59 public: |
58 HasRef() {} | 60 HasRef() {} |
59 | 61 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 StrictMock<NoRef> static_func_mock_; | 346 StrictMock<NoRef> static_func_mock_; |
345 | 347 |
346 // Used by the static functions to perform expectations. | 348 // Used by the static functions to perform expectations. |
347 static StrictMock<NoRef>* static_func_mock_ptr; | 349 static StrictMock<NoRef>* static_func_mock_ptr; |
348 | 350 |
349 private: | 351 private: |
350 DISALLOW_COPY_AND_ASSIGN(BindTest); | 352 DISALLOW_COPY_AND_ASSIGN(BindTest); |
351 }; | 353 }; |
352 | 354 |
353 StrictMock<NoRef>* BindTest::static_func_mock_ptr; | 355 StrictMock<NoRef>* BindTest::static_func_mock_ptr; |
| 356 StrictMock<NoRef>* g_func_mock_ptr; |
| 357 |
| 358 void VoidFunc0() { |
| 359 g_func_mock_ptr->VoidMethod0(); |
| 360 } |
| 361 |
| 362 int IntFunc0() { |
| 363 return g_func_mock_ptr->IntMethod0(); |
| 364 } |
354 | 365 |
355 TEST_F(BindTest, BasicTest) { | 366 TEST_F(BindTest, BasicTest) { |
356 Callback<int(int, int, int)> cb = Bind(&Sum, 32, 16, 8); | 367 Callback<int(int, int, int)> cb = Bind(&Sum, 32, 16, 8); |
357 EXPECT_EQ(92, cb.Run(13, 12, 11)); | 368 EXPECT_EQ(92, cb.Run(13, 12, 11)); |
358 | 369 |
359 Callback<int(int, int, int, int, int, int)> c1 = Bind(&Sum); | 370 Callback<int(int, int, int, int, int, int)> c1 = Bind(&Sum); |
360 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9)); | 371 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9)); |
361 | 372 |
362 Callback<int(int, int, int)> c2 = Bind(c1, 32, 16, 8); | 373 Callback<int(int, int, int)> c2 = Bind(c1, 32, 16, 8); |
363 EXPECT_EQ(86, c2.Run(11, 10, 9)); | 374 EXPECT_EQ(86, c2.Run(11, 10, 9)); |
364 | 375 |
365 Callback<int()> c3 = Bind(c2, 4, 2, 1); | 376 Callback<int()> c3 = Bind(c2, 4, 2, 1); |
366 EXPECT_EQ(63, c3.Run()); | 377 EXPECT_EQ(63, c3.Run()); |
367 } | 378 } |
368 | 379 |
369 // Test that currying the rvalue result of another Bind() works correctly. | 380 // Test that currying the rvalue result of another Bind() works correctly. |
370 // - rvalue should be usable as argument to Bind(). | 381 // - rvalue should be usable as argument to Bind(). |
371 // - multiple runs of resulting Callback remain valid. | 382 // - multiple runs of resulting Callback remain valid. |
372 TEST_F(BindTest, CurryingRvalueResultOfBind) { | 383 TEST_F(BindTest, CurryingRvalueResultOfBind) { |
373 int n = 0; | 384 int n = 0; |
374 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n)); | 385 RepeatingClosure cb = BindRepeating(&TakesACallback, |
| 386 BindRepeating(&PtrArgSet, &n)); |
375 | 387 |
376 // If we implement Bind() such that the return value has auto_ptr-like | 388 // If we implement Bind() such that the return value has auto_ptr-like |
377 // semantics, the second call here will fail because ownership of | 389 // semantics, the second call here will fail because ownership of |
378 // the internal BindState<> would have been transfered to a *temporary* | 390 // the internal BindState<> would have been transfered to a *temporary* |
379 // constructon of a Callback object on the first call. | 391 // constructon of a Callback object on the first call. |
380 cb.Run(); | 392 cb.Run(); |
381 EXPECT_EQ(2, n); | 393 EXPECT_EQ(2, n); |
382 | 394 |
383 n = 0; | 395 n = 0; |
384 cb.Run(); | 396 cb.Run(); |
385 EXPECT_EQ(2, n); | 397 EXPECT_EQ(2, n); |
386 } | 398 } |
387 | 399 |
388 // Function type support. | 400 TEST_F(BindTest, RepeatingCallbackBasicTest) { |
389 // - Normal function. | 401 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16); |
390 // - Normal function bound with non-refcounted first argument. | |
391 // - Method bound to non-const object. | |
392 // - Method bound to scoped_refptr. | |
393 // - Const method bound to non-const object. | |
394 // - Const method bound to const object. | |
395 // - Derived classes can be used with pointers to non-virtual base functions. | |
396 // - Derived classes can be used with pointers to virtual base functions (and | |
397 // preserve virtual dispatch). | |
398 TEST_F(BindTest, FunctionTypeSupport) { | |
399 EXPECT_CALL(static_func_mock_, VoidMethod0()); | |
400 EXPECT_CALL(has_ref_, AddRef()).Times(4); | |
401 EXPECT_CALL(has_ref_, Release()).Times(4); | |
402 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2); | |
403 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2); | |
404 | 402 |
405 Closure normal_cb = Bind(&VoidFunc0); | 403 // RepeatingCallback can run via a lvalue-reference. |
406 Callback<NoRef*()> normal_non_refcounted_cb = | 404 EXPECT_EQ(63, c0.Run(32)); |
407 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_); | |
408 normal_cb.Run(); | |
409 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run()); | |
410 | 405 |
411 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); | 406 // It is valid to call a RepeatingCallback more than once. |
412 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0, | 407 EXPECT_EQ(54, c0.Run(23)); |
413 make_scoped_refptr(&has_ref_)); | |
414 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0, | |
415 &has_ref_); | |
416 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0, | |
417 const_has_ref_ptr_); | |
418 method_cb.Run(); | |
419 method_refptr_cb.Run(); | |
420 const_method_nonconst_obj_cb.Run(); | |
421 const_method_const_obj_cb.Run(); | |
422 | 408 |
423 Child child; | 409 // BindRepeating can handle a RepeatingCallback as the target functor. |
424 child.value = 0; | 410 RepeatingCallback<int()> c1 = BindRepeating(c0, 11); |
425 Closure virtual_set_cb = Bind(&Parent::VirtualSet, &child); | |
426 virtual_set_cb.Run(); | |
427 EXPECT_EQ(kChildValue, child.value); | |
428 | 411 |
429 child.value = 0; | 412 // RepeatingCallback can run via a rvalue-reference. |
430 Closure non_virtual_set_cb = Bind(&Parent::NonVirtualSet, &child); | 413 EXPECT_EQ(42, std::move(c1).Run()); |
431 non_virtual_set_cb.Run(); | 414 |
432 EXPECT_EQ(kParentValue, child.value); | 415 // BindRepeating can handle a rvalue-reference of RepeatingCallback. |
| 416 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run()); |
433 } | 417 } |
434 | 418 |
435 // Return value support. | 419 TEST_F(BindTest, OnceCallbackBasicTest) { |
436 // - Function with return value. | 420 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16); |
437 // - Method with return value. | |
438 // - Const method with return value. | |
439 TEST_F(BindTest, ReturnValues) { | |
440 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); | |
441 EXPECT_CALL(has_ref_, AddRef()).Times(3); | |
442 EXPECT_CALL(has_ref_, Release()).Times(3); | |
443 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337)); | |
444 EXPECT_CALL(has_ref_, IntConstMethod0()) | |
445 .WillOnce(Return(41337)) | |
446 .WillOnce(Return(51337)); | |
447 | 421 |
448 Callback<int()> normal_cb = Bind(&IntFunc0); | 422 // OnceCallback can run via a rvalue-reference. |
449 Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_); | 423 EXPECT_EQ(63, std::move(c0).Run(32)); |
450 Callback<int()> const_method_nonconst_obj_cb = | 424 |
451 Bind(&HasRef::IntConstMethod0, &has_ref_); | 425 // After running via the rvalue-reference, the value of the OnceCallback |
452 Callback<int()> const_method_const_obj_cb = | 426 // is undefined. The implementation simply clears the instance after the |
453 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_); | 427 // invocation. |
454 EXPECT_EQ(1337, normal_cb.Run()); | 428 EXPECT_TRUE(c0.is_null()); |
455 EXPECT_EQ(31337, method_cb.Run()); | 429 |
456 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run()); | 430 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11); |
457 EXPECT_EQ(51337, const_method_const_obj_cb.Run()); | 431 |
| 432 // BindOnce can handle a rvalue-reference of OnceCallback as the target |
| 433 // functor. |
| 434 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13); |
| 435 EXPECT_EQ(41, std::move(c1).Run()); |
| 436 |
| 437 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11); |
| 438 EXPECT_EQ(41, BindOnce(c2, 13).Run()); |
458 } | 439 } |
459 | 440 |
460 // IgnoreResult adapter test. | 441 // IgnoreResult adapter test. |
461 // - Function with return value. | 442 // - Function with return value. |
462 // - Method with return value. | 443 // - Method with return value. |
463 // - Const Method with return. | 444 // - Const Method with return. |
464 // - Method with return value bound to WeakPtr<>. | 445 // - Method with return value bound to WeakPtr<>. |
465 // - Const Method with return bound to WeakPtr<>. | 446 // - Const Method with return bound to WeakPtr<>. |
466 TEST_F(BindTest, IgnoreResult) { | 447 TEST_F(BindTest, IgnoreResultForRepeating) { |
467 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); | 448 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); |
468 EXPECT_CALL(has_ref_, AddRef()).Times(2); | 449 EXPECT_CALL(has_ref_, AddRef()).Times(2); |
469 EXPECT_CALL(has_ref_, Release()).Times(2); | 450 EXPECT_CALL(has_ref_, Release()).Times(2); |
470 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10)); | 451 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10)); |
471 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11)); | 452 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11)); |
472 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12)); | 453 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12)); |
473 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13)); | 454 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13)); |
474 | 455 |
475 Closure normal_func_cb = Bind(IgnoreResult(&IntFunc0)); | 456 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0)); |
476 normal_func_cb.Run(); | 457 normal_func_cb.Run(); |
477 | 458 |
478 Closure non_void_method_cb = | 459 RepeatingClosure non_void_method_cb = |
479 Bind(IgnoreResult(&HasRef::IntMethod0), &has_ref_); | 460 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_); |
480 non_void_method_cb.Run(); | 461 non_void_method_cb.Run(); |
481 | 462 |
482 Closure non_void_const_method_cb = | 463 RepeatingClosure non_void_const_method_cb = |
483 Bind(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_); | 464 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_); |
484 non_void_const_method_cb.Run(); | 465 non_void_const_method_cb.Run(); |
485 | 466 |
486 WeakPtrFactory<NoRef> weak_factory(&no_ref_); | 467 WeakPtrFactory<NoRef> weak_factory(&no_ref_); |
487 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); | 468 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); |
488 | 469 |
489 Closure non_void_weak_method_cb = | 470 RepeatingClosure non_void_weak_method_cb = |
490 Bind(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr()); | 471 BindRepeating(IgnoreResult(&NoRef::IntMethod0), |
| 472 weak_factory.GetWeakPtr()); |
491 non_void_weak_method_cb.Run(); | 473 non_void_weak_method_cb.Run(); |
492 | 474 |
493 Closure non_void_weak_const_method_cb = | 475 RepeatingClosure non_void_weak_const_method_cb = |
494 Bind(IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr()); | 476 BindRepeating(IgnoreResult(&NoRef::IntConstMethod0), |
| 477 weak_factory.GetWeakPtr()); |
495 non_void_weak_const_method_cb.Run(); | 478 non_void_weak_const_method_cb.Run(); |
496 | 479 |
497 weak_factory.InvalidateWeakPtrs(); | 480 weak_factory.InvalidateWeakPtrs(); |
498 non_void_weak_const_method_cb.Run(); | 481 non_void_weak_const_method_cb.Run(); |
499 non_void_weak_method_cb.Run(); | 482 non_void_weak_method_cb.Run(); |
500 } | 483 } |
501 | 484 |
502 // Argument binding tests. | 485 TEST_F(BindTest, IgnoreResultForOnce) { |
503 // - Argument binding to primitive. | 486 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); |
504 // - Argument binding to primitive pointer. | 487 EXPECT_CALL(has_ref_, AddRef()).Times(2); |
505 // - Argument binding to a literal integer. | 488 EXPECT_CALL(has_ref_, Release()).Times(2); |
506 // - Argument binding to a literal string. | 489 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10)); |
507 // - Argument binding with template function. | 490 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11)); |
508 // - Argument binding to an object. | |
509 // - Argument binding to pointer to incomplete type. | |
510 // - Argument gets type converted. | |
511 // - Pointer argument gets converted. | |
512 // - Const Reference forces conversion. | |
513 TEST_F(BindTest, ArgumentBinding) { | |
514 int n = 2; | |
515 | 491 |
516 Callback<int()> bind_primitive_cb = Bind(&Identity, n); | 492 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0)); |
517 EXPECT_EQ(n, bind_primitive_cb.Run()); | 493 std::move(normal_func_cb).Run(); |
518 | 494 |
519 Callback<int*()> bind_primitive_pointer_cb = | 495 OnceClosure non_void_method_cb = |
520 Bind(&PolymorphicIdentity<int*>, &n); | 496 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_); |
521 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run()); | 497 std::move(non_void_method_cb).Run(); |
522 | 498 |
523 Callback<int()> bind_int_literal_cb = Bind(&Identity, 3); | 499 OnceClosure non_void_const_method_cb = |
524 EXPECT_EQ(3, bind_int_literal_cb.Run()); | 500 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_); |
| 501 std::move(non_void_const_method_cb).Run(); |
525 | 502 |
526 Callback<const char*()> bind_string_literal_cb = | 503 WeakPtrFactory<NoRef> weak_factory(&no_ref_); |
527 Bind(&CStringIdentity, "hi"); | 504 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); |
528 EXPECT_STREQ("hi", bind_string_literal_cb.Run()); | |
529 | 505 |
530 Callback<int()> bind_template_function_cb = | 506 OnceClosure non_void_weak_method_cb = |
531 Bind(&PolymorphicIdentity<int>, 4); | 507 BindOnce(IgnoreResult(&NoRef::IntMethod0), |
532 EXPECT_EQ(4, bind_template_function_cb.Run()); | 508 weak_factory.GetWeakPtr()); |
| 509 OnceClosure non_void_weak_const_method_cb = |
| 510 BindOnce(IgnoreResult(&NoRef::IntConstMethod0), |
| 511 weak_factory.GetWeakPtr()); |
533 | 512 |
534 NoRefParent p; | 513 weak_factory.InvalidateWeakPtrs(); |
535 p.value = 5; | 514 std::move(non_void_weak_const_method_cb).Run(); |
536 Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p); | 515 std::move(non_void_weak_method_cb).Run(); |
537 EXPECT_EQ(5, bind_object_cb.Run()); | |
538 | |
539 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123); | |
540 Callback<IncompleteType*()> bind_incomplete_ptr_cb = | |
541 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr); | |
542 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run()); | |
543 | |
544 NoRefChild c; | |
545 c.value = 6; | |
546 Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c); | |
547 EXPECT_EQ(6, bind_promotes_cb.Run()); | |
548 | |
549 c.value = 7; | |
550 Callback<int()> bind_pointer_promotes_cb = | |
551 Bind(&UnwrapNoRefParentPtr, &c); | |
552 EXPECT_EQ(7, bind_pointer_promotes_cb.Run()); | |
553 | |
554 c.value = 8; | |
555 Callback<int()> bind_const_reference_promotes_cb = | |
556 Bind(&UnwrapNoRefParentConstRef, c); | |
557 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run()); | |
558 } | |
559 | |
560 // Unbound argument type support tests. | |
561 // - Unbound value. | |
562 // - Unbound pointer. | |
563 // - Unbound reference. | |
564 // - Unbound const reference. | |
565 // - Unbound unsized array. | |
566 // - Unbound sized array. | |
567 // - Unbound array-of-arrays. | |
568 TEST_F(BindTest, UnboundArgumentTypeSupport) { | |
569 Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic<int>::Run); | |
570 Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic<int*>::Run); | |
571 Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic<int&>::Run); | |
572 Callback<void(const int&)> unbound_const_ref_cb = | |
573 Bind(&VoidPolymorphic<const int&>::Run); | |
574 Callback<void(int[])> unbound_unsized_array_cb = | |
575 Bind(&VoidPolymorphic<int[]>::Run); | |
576 Callback<void(int[2])> unbound_sized_array_cb = | |
577 Bind(&VoidPolymorphic<int[2]>::Run); | |
578 Callback<void(int[][2])> unbound_array_of_arrays_cb = | |
579 Bind(&VoidPolymorphic<int[][2]>::Run); | |
580 | |
581 Callback<void(int&)> unbound_ref_with_bound_arg = | |
582 Bind(&VoidPolymorphic<int, int&>::Run, 1); | |
583 } | |
584 | |
585 // Function with unbound reference parameter. | |
586 // - Original parameter is modified by callback. | |
587 TEST_F(BindTest, UnboundReferenceSupport) { | |
588 int n = 0; | |
589 Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet); | |
590 unbound_ref_cb.Run(n); | |
591 EXPECT_EQ(2, n); | |
592 } | 516 } |
593 | 517 |
594 // Functions that take reference parameters. | 518 // Functions that take reference parameters. |
595 // - Forced reference parameter type still stores a copy. | 519 // - Forced reference parameter type still stores a copy. |
596 // - Forced const reference parameter type still stores a copy. | 520 // - Forced const reference parameter type still stores a copy. |
597 TEST_F(BindTest, ReferenceArgumentBinding) { | 521 TEST_F(BindTest, ReferenceArgumentBindingForRepeating) { |
598 int n = 1; | 522 int n = 1; |
599 int& ref_n = n; | 523 int& ref_n = n; |
600 const int& const_ref_n = n; | 524 const int& const_ref_n = n; |
601 | 525 |
602 Callback<int()> ref_copies_cb = Bind(&Identity, ref_n); | 526 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n); |
603 EXPECT_EQ(n, ref_copies_cb.Run()); | 527 EXPECT_EQ(n, ref_copies_cb.Run()); |
604 n++; | 528 n++; |
605 EXPECT_EQ(n - 1, ref_copies_cb.Run()); | 529 EXPECT_EQ(n - 1, ref_copies_cb.Run()); |
606 | 530 |
607 Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n); | 531 RepeatingCallback<int()> const_ref_copies_cb = |
| 532 BindRepeating(&Identity, const_ref_n); |
608 EXPECT_EQ(n, const_ref_copies_cb.Run()); | 533 EXPECT_EQ(n, const_ref_copies_cb.Run()); |
609 n++; | 534 n++; |
610 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); | 535 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); |
611 } | 536 } |
612 | 537 |
| 538 TEST_F(BindTest, ReferenceArgumentBindingForOnce) { |
| 539 int n = 1; |
| 540 int& ref_n = n; |
| 541 const int& const_ref_n = n; |
| 542 |
| 543 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n); |
| 544 n++; |
| 545 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run()); |
| 546 |
| 547 OnceCallback<int()> const_ref_copies_cb = |
| 548 BindOnce(&Identity, const_ref_n); |
| 549 n++; |
| 550 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run()); |
| 551 } |
| 552 |
613 // Check that we can pass in arrays and have them be stored as a pointer. | 553 // Check that we can pass in arrays and have them be stored as a pointer. |
614 // - Array of values stores a pointer. | 554 // - Array of values stores a pointer. |
615 // - Array of const values stores a pointer. | 555 // - Array of const values stores a pointer. |
616 TEST_F(BindTest, ArrayArgumentBinding) { | 556 TEST_F(BindTest, ArrayArgumentBindingForRepeating) { |
617 int array[4] = {1, 1, 1, 1}; | 557 int array[4] = {1, 1, 1, 1}; |
618 const int (*const_array_ptr)[4] = &array; | 558 const int (*const_array_ptr)[4] = &array; |
619 | 559 |
620 Callback<int()> array_cb = Bind(&ArrayGet, array, 1); | 560 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1); |
621 EXPECT_EQ(1, array_cb.Run()); | 561 EXPECT_EQ(1, array_cb.Run()); |
622 | 562 |
623 Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1); | 563 RepeatingCallback<int()> const_array_cb = |
| 564 BindRepeating(&ArrayGet, *const_array_ptr, 1); |
624 EXPECT_EQ(1, const_array_cb.Run()); | 565 EXPECT_EQ(1, const_array_cb.Run()); |
625 | 566 |
626 array[1] = 3; | 567 array[1] = 3; |
627 EXPECT_EQ(3, array_cb.Run()); | 568 EXPECT_EQ(3, array_cb.Run()); |
628 EXPECT_EQ(3, const_array_cb.Run()); | 569 EXPECT_EQ(3, const_array_cb.Run()); |
629 } | 570 } |
630 | 571 |
631 // Unretained() wrapper support. | 572 TEST_F(BindTest, ArrayArgumentBindingForOnce) { |
632 // - Method bound to Unretained() non-const object. | 573 int array[4] = {1, 1, 1, 1}; |
633 // - Const method bound to Unretained() non-const object. | 574 const int (*const_array_ptr)[4] = &array; |
634 // - Const method bound to Unretained() const object. | |
635 TEST_F(BindTest, Unretained) { | |
636 EXPECT_CALL(no_ref_, VoidMethod0()); | |
637 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); | |
638 | 575 |
639 Callback<void()> method_cb = | 576 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1); |
640 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_)); | 577 OnceCallback<int()> const_array_cb = |
641 method_cb.Run(); | 578 BindOnce(&ArrayGet, *const_array_ptr, 1); |
642 | 579 |
643 Callback<void()> const_method_cb = | 580 array[1] = 3; |
644 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_)); | 581 EXPECT_EQ(3, std::move(array_cb).Run()); |
645 const_method_cb.Run(); | 582 EXPECT_EQ(3, std::move(const_array_cb).Run()); |
646 | |
647 Callback<void()> const_method_const_ptr_cb = | |
648 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_)); | |
649 const_method_const_ptr_cb.Run(); | |
650 } | 583 } |
651 | 584 |
652 // WeakPtr() support. | 585 // WeakPtr() support. |
653 // - Method bound to WeakPtr<> to non-const object. | 586 // - Method bound to WeakPtr<> to non-const object. |
654 // - Const method bound to WeakPtr<> to non-const object. | 587 // - Const method bound to WeakPtr<> to non-const object. |
655 // - Const method bound to WeakPtr<> to const object. | 588 // - Const method bound to WeakPtr<> to const object. |
656 // - Normal Function with WeakPtr<> as P1 can have return type and is | 589 // - Normal Function with WeakPtr<> as P1 can have return type and is |
657 // not canceled. | 590 // not canceled. |
658 TEST_F(BindTest, WeakPtr) { | 591 TEST_F(BindTest, WeakPtrForRepeating) { |
659 EXPECT_CALL(no_ref_, VoidMethod0()); | 592 EXPECT_CALL(no_ref_, VoidMethod0()); |
660 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); | 593 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); |
661 | 594 |
662 WeakPtrFactory<NoRef> weak_factory(&no_ref_); | 595 WeakPtrFactory<NoRef> weak_factory(&no_ref_); |
663 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); | 596 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); |
664 | 597 |
665 Closure method_cb = | 598 RepeatingClosure method_cb = |
666 Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr()); | 599 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr()); |
667 method_cb.Run(); | 600 method_cb.Run(); |
668 | 601 |
669 Closure const_method_cb = | 602 RepeatingClosure const_method_cb = |
670 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); | 603 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); |
671 const_method_cb.Run(); | 604 const_method_cb.Run(); |
672 | 605 |
673 Closure const_method_const_ptr_cb = | 606 RepeatingClosure const_method_const_ptr_cb = |
674 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); | 607 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); |
675 const_method_const_ptr_cb.Run(); | 608 const_method_const_ptr_cb.Run(); |
676 | 609 |
677 Callback<int(int)> normal_func_cb = | 610 RepeatingCallback<int(int)> normal_func_cb = |
678 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr()); | 611 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr()); |
679 EXPECT_EQ(1, normal_func_cb.Run(1)); | 612 EXPECT_EQ(1, normal_func_cb.Run(1)); |
680 | 613 |
681 weak_factory.InvalidateWeakPtrs(); | 614 weak_factory.InvalidateWeakPtrs(); |
682 const_weak_factory.InvalidateWeakPtrs(); | 615 const_weak_factory.InvalidateWeakPtrs(); |
683 | 616 |
684 method_cb.Run(); | 617 method_cb.Run(); |
685 const_method_cb.Run(); | 618 const_method_cb.Run(); |
686 const_method_const_ptr_cb.Run(); | 619 const_method_const_ptr_cb.Run(); |
687 | 620 |
688 // Still runs even after the pointers are invalidated. | 621 // Still runs even after the pointers are invalidated. |
689 EXPECT_EQ(2, normal_func_cb.Run(2)); | 622 EXPECT_EQ(2, normal_func_cb.Run(2)); |
690 } | 623 } |
691 | 624 |
| 625 TEST_F(BindTest, WeakPtrForOnce) { |
| 626 WeakPtrFactory<NoRef> weak_factory(&no_ref_); |
| 627 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); |
| 628 |
| 629 OnceClosure method_cb = |
| 630 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr()); |
| 631 OnceClosure const_method_cb = |
| 632 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); |
| 633 OnceClosure const_method_const_ptr_cb = |
| 634 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); |
| 635 Callback<int(int)> normal_func_cb = |
| 636 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr()); |
| 637 |
| 638 weak_factory.InvalidateWeakPtrs(); |
| 639 const_weak_factory.InvalidateWeakPtrs(); |
| 640 |
| 641 std::move(method_cb).Run(); |
| 642 std::move(const_method_cb).Run(); |
| 643 std::move(const_method_const_ptr_cb).Run(); |
| 644 |
| 645 // Still runs even after the pointers are invalidated. |
| 646 EXPECT_EQ(2, std::move(normal_func_cb).Run(2)); |
| 647 } |
| 648 |
692 // ConstRef() wrapper support. | 649 // ConstRef() wrapper support. |
693 // - Binding w/o ConstRef takes a copy. | 650 // - Binding w/o ConstRef takes a copy. |
694 // - Binding a ConstRef takes a reference. | 651 // - Binding a ConstRef takes a reference. |
695 // - Binding ConstRef to a function ConstRef does not copy on invoke. | 652 // - Binding ConstRef to a function ConstRef does not copy on invoke. |
696 TEST_F(BindTest, ConstRef) { | 653 TEST_F(BindTest, ConstRefForRepeating) { |
697 int n = 1; | 654 int n = 1; |
698 | 655 |
699 Callback<int()> copy_cb = Bind(&Identity, n); | 656 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n); |
700 Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n)); | 657 RepeatingCallback<int()> const_ref_cb = BindRepeating(&Identity, ConstRef(n)); |
701 EXPECT_EQ(n, copy_cb.Run()); | 658 EXPECT_EQ(n, copy_cb.Run()); |
702 EXPECT_EQ(n, const_ref_cb.Run()); | 659 EXPECT_EQ(n, const_ref_cb.Run()); |
703 n++; | 660 n++; |
704 EXPECT_EQ(n - 1, copy_cb.Run()); | 661 EXPECT_EQ(n - 1, copy_cb.Run()); |
705 EXPECT_EQ(n, const_ref_cb.Run()); | 662 EXPECT_EQ(n, const_ref_cb.Run()); |
706 | 663 |
707 int copies = 0; | 664 int copies = 0; |
708 int assigns = 0; | 665 int assigns = 0; |
709 int move_constructs = 0; | 666 int move_constructs = 0; |
710 int move_assigns = 0; | 667 int move_assigns = 0; |
711 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns); | 668 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns); |
712 Callback<int()> all_const_ref_cb = | 669 RepeatingCallback<int()> all_const_ref_cb = |
713 Bind(&GetCopies, ConstRef(counter)); | 670 BindRepeating(&GetCopies, ConstRef(counter)); |
714 EXPECT_EQ(0, all_const_ref_cb.Run()); | 671 EXPECT_EQ(0, all_const_ref_cb.Run()); |
715 EXPECT_EQ(0, copies); | 672 EXPECT_EQ(0, copies); |
716 EXPECT_EQ(0, assigns); | 673 EXPECT_EQ(0, assigns); |
717 EXPECT_EQ(0, move_constructs); | 674 EXPECT_EQ(0, move_constructs); |
718 EXPECT_EQ(0, move_assigns); | 675 EXPECT_EQ(0, move_assigns); |
719 } | 676 } |
720 | 677 |
721 TEST_F(BindTest, ScopedRefptr) { | 678 TEST_F(BindTest, ConstRefForOnce) { |
722 EXPECT_CALL(has_ref_, AddRef()).Times(1); | 679 int n = 1; |
723 EXPECT_CALL(has_ref_, Release()).Times(1); | |
724 | 680 |
725 const scoped_refptr<HasRef> refptr(&has_ref_); | 681 OnceCallback<int()> copy_cb = BindOnce(&Identity, n); |
726 Callback<int()> scoped_refptr_const_ref_cb = | 682 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, ConstRef(n)); |
727 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1); | 683 n++; |
728 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run()); | 684 EXPECT_EQ(n - 1, std::move(copy_cb).Run()); |
| 685 EXPECT_EQ(n, std::move(const_ref_cb).Run()); |
| 686 |
| 687 int copies = 0; |
| 688 int assigns = 0; |
| 689 int move_constructs = 0; |
| 690 int move_assigns = 0; |
| 691 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns); |
| 692 OnceCallback<int()> all_const_ref_cb = |
| 693 BindOnce(&GetCopies, ConstRef(counter)); |
| 694 EXPECT_EQ(0, std::move(all_const_ref_cb).Run()); |
| 695 EXPECT_EQ(0, copies); |
| 696 EXPECT_EQ(0, assigns); |
| 697 EXPECT_EQ(0, move_constructs); |
| 698 EXPECT_EQ(0, move_assigns); |
729 } | 699 } |
730 | 700 |
731 // Test Owned() support. | 701 // Test Owned() support. |
732 TEST_F(BindTest, Owned) { | 702 TEST_F(BindTest, OwnedForRepeating) { |
733 int deletes = 0; | 703 int deletes = 0; |
734 DeleteCounter* counter = new DeleteCounter(&deletes); | 704 DeleteCounter* counter = new DeleteCounter(&deletes); |
735 | 705 |
736 // If we don't capture, delete happens on Callback destruction/reset. | 706 // If we don't capture, delete happens on Callback destruction/reset. |
737 // return the same value. | 707 // return the same value. |
738 Callback<DeleteCounter*()> no_capture_cb = | 708 RepeatingCallback<DeleteCounter*()> no_capture_cb = |
739 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); | 709 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); |
740 ASSERT_EQ(counter, no_capture_cb.Run()); | 710 ASSERT_EQ(counter, no_capture_cb.Run()); |
741 ASSERT_EQ(counter, no_capture_cb.Run()); | 711 ASSERT_EQ(counter, no_capture_cb.Run()); |
742 EXPECT_EQ(0, deletes); | 712 EXPECT_EQ(0, deletes); |
743 no_capture_cb.Reset(); // This should trigger a delete. | 713 no_capture_cb.Reset(); // This should trigger a delete. |
744 EXPECT_EQ(1, deletes); | 714 EXPECT_EQ(1, deletes); |
745 | 715 |
746 deletes = 0; | 716 deletes = 0; |
747 counter = new DeleteCounter(&deletes); | 717 counter = new DeleteCounter(&deletes); |
748 base::Closure own_object_cb = | 718 RepeatingClosure own_object_cb = |
749 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); | 719 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter)); |
750 own_object_cb.Run(); | 720 own_object_cb.Run(); |
751 EXPECT_EQ(0, deletes); | 721 EXPECT_EQ(0, deletes); |
752 own_object_cb.Reset(); | 722 own_object_cb.Reset(); |
753 EXPECT_EQ(1, deletes); | 723 EXPECT_EQ(1, deletes); |
754 } | 724 } |
755 | 725 |
756 TEST_F(BindTest, UniquePtrReceiver) { | 726 TEST_F(BindTest, OwnedForOnce) { |
| 727 int deletes = 0; |
| 728 DeleteCounter* counter = new DeleteCounter(&deletes); |
| 729 |
| 730 // If we don't capture, delete happens on Callback destruction/reset. |
| 731 // return the same value. |
| 732 OnceCallback<DeleteCounter*()> no_capture_cb = |
| 733 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); |
| 734 EXPECT_EQ(0, deletes); |
| 735 no_capture_cb.Reset(); // This should trigger a delete. |
| 736 EXPECT_EQ(1, deletes); |
| 737 |
| 738 deletes = 0; |
| 739 counter = new DeleteCounter(&deletes); |
| 740 OnceClosure own_object_cb = |
| 741 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter)); |
| 742 EXPECT_EQ(0, deletes); |
| 743 own_object_cb.Reset(); |
| 744 EXPECT_EQ(1, deletes); |
| 745 } |
| 746 |
| 747 template <typename T> |
| 748 class BindVariantsTest : public ::testing::Test { |
| 749 }; |
| 750 |
| 751 struct RepeatingTestConfig { |
| 752 template <typename Signature> |
| 753 using CallbackType = RepeatingCallback<Signature>; |
| 754 using ClosureType = RepeatingClosure; |
| 755 |
| 756 template <typename F, typename... Args> |
| 757 static CallbackType<MakeUnboundRunType<F, Args...>> |
| 758 Bind(F&& f, Args&&... args) { |
| 759 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...); |
| 760 } |
| 761 }; |
| 762 |
| 763 struct OnceTestConfig { |
| 764 template <typename Signature> |
| 765 using CallbackType = OnceCallback<Signature>; |
| 766 using ClosureType = OnceClosure; |
| 767 |
| 768 template <typename F, typename... Args> |
| 769 static CallbackType<MakeUnboundRunType<F, Args...>> |
| 770 Bind(F&& f, Args&&... args) { |
| 771 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...); |
| 772 } |
| 773 }; |
| 774 |
| 775 using BindVariantsTestConfig = ::testing::Types< |
| 776 RepeatingTestConfig, OnceTestConfig>; |
| 777 TYPED_TEST_CASE(BindVariantsTest, BindVariantsTestConfig); |
| 778 |
| 779 template <typename TypeParam, typename Signature> |
| 780 using CallbackType = typename TypeParam::template CallbackType<Signature>; |
| 781 |
| 782 // Function type support. |
| 783 // - Normal function. |
| 784 // - Normal function bound with non-refcounted first argument. |
| 785 // - Method bound to non-const object. |
| 786 // - Method bound to scoped_refptr. |
| 787 // - Const method bound to non-const object. |
| 788 // - Const method bound to const object. |
| 789 // - Derived classes can be used with pointers to non-virtual base functions. |
| 790 // - Derived classes can be used with pointers to virtual base functions (and |
| 791 // preserve virtual dispatch). |
| 792 TYPED_TEST(BindVariantsTest, FunctionTypeSupport) { |
| 793 using ClosureType = typename TypeParam::ClosureType; |
| 794 |
| 795 StrictMock<HasRef> has_ref; |
| 796 StrictMock<NoRef> no_ref; |
| 797 StrictMock<NoRef> static_func_mock; |
| 798 const HasRef* const_has_ref_ptr = &has_ref; |
| 799 g_func_mock_ptr = &static_func_mock; |
| 800 |
| 801 EXPECT_CALL(static_func_mock, VoidMethod0()); |
| 802 EXPECT_CALL(has_ref, AddRef()).Times(4); |
| 803 EXPECT_CALL(has_ref, Release()).Times(4); |
| 804 EXPECT_CALL(has_ref, VoidMethod0()).Times(2); |
| 805 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2); |
| 806 |
| 807 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0); |
| 808 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb = |
| 809 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref); |
| 810 std::move(normal_cb).Run(); |
| 811 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run()); |
| 812 |
| 813 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref); |
| 814 ClosureType method_refptr_cb = TypeParam::Bind(&HasRef::VoidMethod0, |
| 815 make_scoped_refptr(&has_ref)); |
| 816 ClosureType const_method_nonconst_obj_cb = |
| 817 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref); |
| 818 ClosureType const_method_const_obj_cb = |
| 819 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr); |
| 820 std::move(method_cb).Run(); |
| 821 std::move(method_refptr_cb).Run(); |
| 822 std::move(const_method_nonconst_obj_cb).Run(); |
| 823 std::move(const_method_const_obj_cb).Run(); |
| 824 |
| 825 Child child; |
| 826 child.value = 0; |
| 827 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child); |
| 828 std::move(virtual_set_cb).Run(); |
| 829 EXPECT_EQ(kChildValue, child.value); |
| 830 |
| 831 child.value = 0; |
| 832 ClosureType non_virtual_set_cb = |
| 833 TypeParam::Bind(&Parent::NonVirtualSet, &child); |
| 834 std::move(non_virtual_set_cb).Run(); |
| 835 EXPECT_EQ(kParentValue, child.value); |
| 836 } |
| 837 |
| 838 // Return value support. |
| 839 // - Function with return value. |
| 840 // - Method with return value. |
| 841 // - Const method with return value. |
| 842 // - Move-only return value. |
| 843 TYPED_TEST(BindVariantsTest, ReturnValues) { |
| 844 StrictMock<NoRef> static_func_mock; |
| 845 StrictMock<HasRef> has_ref; |
| 846 g_func_mock_ptr = &static_func_mock; |
| 847 const HasRef* const_has_ref_ptr = &has_ref; |
| 848 |
| 849 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337)); |
| 850 EXPECT_CALL(has_ref, AddRef()).Times(4); |
| 851 EXPECT_CALL(has_ref, Release()).Times(4); |
| 852 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337)); |
| 853 EXPECT_CALL(has_ref, IntConstMethod0()) |
| 854 .WillOnce(Return(41337)) |
| 855 .WillOnce(Return(51337)); |
| 856 EXPECT_CALL(has_ref, UniquePtrMethod0()) |
| 857 .WillOnce(Return(ByMove(MakeUnique<int>(42)))); |
| 858 |
| 859 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0); |
| 860 CallbackType<TypeParam, int()> method_cb = |
| 861 TypeParam::Bind(&HasRef::IntMethod0, &has_ref); |
| 862 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb = |
| 863 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref); |
| 864 CallbackType<TypeParam, int()> const_method_const_obj_cb = |
| 865 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr); |
| 866 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb = |
| 867 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref); |
| 868 EXPECT_EQ(1337, std::move(normal_cb).Run()); |
| 869 EXPECT_EQ(31337, std::move(method_cb).Run()); |
| 870 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run()); |
| 871 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run()); |
| 872 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run()); |
| 873 } |
| 874 |
| 875 // Argument binding tests. |
| 876 // - Argument binding to primitive. |
| 877 // - Argument binding to primitive pointer. |
| 878 // - Argument binding to a literal integer. |
| 879 // - Argument binding to a literal string. |
| 880 // - Argument binding with template function. |
| 881 // - Argument binding to an object. |
| 882 // - Argument binding to pointer to incomplete type. |
| 883 // - Argument gets type converted. |
| 884 // - Pointer argument gets converted. |
| 885 // - Const Reference forces conversion. |
| 886 TYPED_TEST(BindVariantsTest, ArgumentBinding) { |
| 887 int n = 2; |
| 888 |
| 889 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run()); |
| 890 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run()); |
| 891 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run()); |
| 892 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run()); |
| 893 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run()); |
| 894 |
| 895 NoRefParent p; |
| 896 p.value = 5; |
| 897 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run()); |
| 898 |
| 899 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123); |
| 900 EXPECT_EQ(incomplete_ptr, |
| 901 TypeParam::Bind(&PolymorphicIdentity<IncompleteType*>, |
| 902 incomplete_ptr).Run()); |
| 903 |
| 904 NoRefChild c; |
| 905 c.value = 6; |
| 906 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run()); |
| 907 |
| 908 c.value = 7; |
| 909 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run()); |
| 910 |
| 911 c.value = 8; |
| 912 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run()); |
| 913 } |
| 914 |
| 915 // Unbound argument type support tests. |
| 916 // - Unbound value. |
| 917 // - Unbound pointer. |
| 918 // - Unbound reference. |
| 919 // - Unbound const reference. |
| 920 // - Unbound unsized array. |
| 921 // - Unbound sized array. |
| 922 // - Unbound array-of-arrays. |
| 923 TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) { |
| 924 CallbackType<TypeParam, void(int)> unbound_value_cb = |
| 925 TypeParam::Bind(&VoidPolymorphic<int>::Run); |
| 926 CallbackType<TypeParam, void(int*)> unbound_pointer_cb = |
| 927 TypeParam::Bind(&VoidPolymorphic<int*>::Run); |
| 928 CallbackType<TypeParam, void(int&)> unbound_ref_cb = |
| 929 TypeParam::Bind(&VoidPolymorphic<int&>::Run); |
| 930 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb = |
| 931 TypeParam::Bind(&VoidPolymorphic<const int&>::Run); |
| 932 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb = |
| 933 TypeParam::Bind(&VoidPolymorphic<int[]>::Run); |
| 934 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb = |
| 935 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run); |
| 936 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb = |
| 937 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run); |
| 938 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg = |
| 939 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1); |
| 940 } |
| 941 |
| 942 // Function with unbound reference parameter. |
| 943 // - Original parameter is modified by callback. |
| 944 TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) { |
| 945 int n = 0; |
| 946 CallbackType<TypeParam, void(int&)> unbound_ref_cb = |
| 947 TypeParam::Bind(&RefArgSet); |
| 948 std::move(unbound_ref_cb).Run(n); |
| 949 EXPECT_EQ(2, n); |
| 950 } |
| 951 |
| 952 // Unretained() wrapper support. |
| 953 // - Method bound to Unretained() non-const object. |
| 954 // - Const method bound to Unretained() non-const object. |
| 955 // - Const method bound to Unretained() const object. |
| 956 TYPED_TEST(BindVariantsTest, Unretained) { |
| 957 StrictMock<NoRef> no_ref; |
| 958 const NoRef* const_no_ref_ptr = &no_ref; |
| 959 |
| 960 EXPECT_CALL(no_ref, VoidMethod0()); |
| 961 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2); |
| 962 |
| 963 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run(); |
| 964 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run(); |
| 965 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run(); |
| 966 } |
| 967 |
| 968 TYPED_TEST(BindVariantsTest, ScopedRefptr) { |
| 969 StrictMock<HasRef> has_ref; |
| 970 EXPECT_CALL(has_ref, AddRef()).Times(1); |
| 971 EXPECT_CALL(has_ref, Release()).Times(1); |
| 972 |
| 973 const scoped_refptr<HasRef> refptr(&has_ref); |
| 974 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb = |
| 975 TypeParam::Bind(&FunctionWithScopedRefptrFirstParam, |
| 976 base::ConstRef(refptr), 1); |
| 977 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run()); |
| 978 } |
| 979 |
| 980 TYPED_TEST(BindVariantsTest, UniquePtrReceiver) { |
757 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>); | 981 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>); |
758 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1); | 982 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1); |
759 Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run(); | 983 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run(); |
760 } | 984 } |
761 | 985 |
762 // Tests for Passed() wrapper support: | 986 // Tests for Passed() wrapper support: |
763 // - Passed() can be constructed from a pointer to scoper. | 987 // - Passed() can be constructed from a pointer to scoper. |
764 // - Passed() can be constructed from a scoper rvalue. | 988 // - Passed() can be constructed from a scoper rvalue. |
765 // - Using Passed() gives Callback Ownership. | 989 // - Using Passed() gives Callback Ownership. |
766 // - Ownership is transferred from Callback to callee on the first Run(). | 990 // - Ownership is transferred from Callback to callee on the first Run(). |
767 // - Callback supports unbound arguments. | 991 // - Callback supports unbound arguments. |
768 template <typename T> | 992 template <typename T> |
769 class BindMoveOnlyTypeTest : public ::testing::Test { | 993 class BindMoveOnlyTypeTest : public ::testing::Test { |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 EXPECT_TRUE(cb3.IsCancelled()); | 1299 EXPECT_TRUE(cb3.IsCancelled()); |
1076 EXPECT_TRUE(cb5.IsCancelled()); | 1300 EXPECT_TRUE(cb5.IsCancelled()); |
1077 | 1301 |
1078 cb.Run(6); | 1302 cb.Run(6); |
1079 cb2.Run(); | 1303 cb2.Run(); |
1080 std::move(cb3).Run(); | 1304 std::move(cb3).Run(); |
1081 std::move(cb5).Run(); | 1305 std::move(cb5).Run(); |
1082 } | 1306 } |
1083 | 1307 |
1084 TEST_F(BindTest, OnceCallback) { | 1308 TEST_F(BindTest, OnceCallback) { |
1085 using internal::OnceClosure; | |
1086 using internal::RepeatingClosure; | |
1087 using internal::BindOnce; | |
1088 using internal::BindRepeating; | |
1089 using internal::OnceCallback; | |
1090 | |
1091 // Check if Callback variants have declarations of conversions as expected. | 1309 // Check if Callback variants have declarations of conversions as expected. |
1092 // Copy constructor and assignment of RepeatingCallback. | 1310 // Copy constructor and assignment of RepeatingCallback. |
1093 static_assert(std::is_constructible< | 1311 static_assert(std::is_constructible< |
1094 RepeatingClosure, const RepeatingClosure&>::value, | 1312 RepeatingClosure, const RepeatingClosure&>::value, |
1095 "RepeatingClosure should be copyable."); | 1313 "RepeatingClosure should be copyable."); |
1096 static_assert(is_assignable< | 1314 static_assert(is_assignable< |
1097 RepeatingClosure, const RepeatingClosure&>::value, | 1315 RepeatingClosure, const RepeatingClosure&>::value, |
1098 "RepeatingClosure should be copy-assignable."); | 1316 "RepeatingClosure should be copy-assignable."); |
1099 | 1317 |
1100 // Move constructor and assignment of RepeatingCallback. | 1318 // Move constructor and assignment of RepeatingCallback. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 | 1418 |
1201 // Test null callbacks cause a DCHECK. | 1419 // Test null callbacks cause a DCHECK. |
1202 TEST(BindDeathTest, NullCallback) { | 1420 TEST(BindDeathTest, NullCallback) { |
1203 base::Callback<void(int)> null_cb; | 1421 base::Callback<void(int)> null_cb; |
1204 ASSERT_TRUE(null_cb.is_null()); | 1422 ASSERT_TRUE(null_cb.is_null()); |
1205 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42)); | 1423 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42)); |
1206 } | 1424 } |
1207 | 1425 |
1208 } // namespace | 1426 } // namespace |
1209 } // namespace base | 1427 } // namespace base |
OLD | NEW |