Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Side by Side Diff: base/bind_unittest.cc

Issue 2250373002: Readd base::UnwrapTraits to support rvalue-reference wrappers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20_oneshot
Patch Set: remove unused "using" Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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::Mock; 21 using ::testing::Mock;
22 using ::testing::ByMove;
22 using ::testing::Return; 23 using ::testing::Return;
23 using ::testing::StrictMock; 24 using ::testing::StrictMock;
24 25
26 using base::internal::BindOneShot;
27 using base::internal::BindRepeating;
28 using base::internal::OneShotCallback;
29 using base::internal::RepeatingCallback;
30 using base::internal::OneShotClosure;
31 using base::internal::RepeatingClosure;
32
25 namespace base { 33 namespace base {
26 namespace { 34 namespace {
27 35
28 class IncompleteType; 36 class IncompleteType;
29 37
30 class NoRef { 38 class NoRef {
31 public: 39 public:
32 NoRef() {} 40 NoRef() {}
33 41
34 MOCK_METHOD0(VoidMethod0, void()); 42 MOCK_METHOD0(VoidMethod0, void());
35 MOCK_CONST_METHOD0(VoidConstMethod0, void()); 43 MOCK_CONST_METHOD0(VoidConstMethod0, void());
36 44
37 MOCK_METHOD0(IntMethod0, int()); 45 MOCK_METHOD0(IntMethod0, int());
38 MOCK_CONST_METHOD0(IntConstMethod0, int()); 46 MOCK_CONST_METHOD0(IntConstMethod0, int());
39 47
48 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
49
40 private: 50 private:
41 // Particularly important in this test to ensure no copies are made. 51 // Particularly important in this test to ensure no copies are made.
42 DISALLOW_COPY_AND_ASSIGN(NoRef); 52 DISALLOW_COPY_AND_ASSIGN(NoRef);
43 }; 53 };
44 54
45 class HasRef : public NoRef { 55 class HasRef : public NoRef {
46 public: 56 public:
47 HasRef() {} 57 HasRef() {}
48 58
49 MOCK_CONST_METHOD0(AddRef, void()); 59 MOCK_CONST_METHOD0(AddRef, void());
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 StrictMock<NoRef> static_func_mock_; 343 StrictMock<NoRef> static_func_mock_;
334 344
335 // Used by the static functions to perform expectations. 345 // Used by the static functions to perform expectations.
336 static StrictMock<NoRef>* static_func_mock_ptr; 346 static StrictMock<NoRef>* static_func_mock_ptr;
337 347
338 private: 348 private:
339 DISALLOW_COPY_AND_ASSIGN(BindTest); 349 DISALLOW_COPY_AND_ASSIGN(BindTest);
340 }; 350 };
341 351
342 StrictMock<NoRef>* BindTest::static_func_mock_ptr; 352 StrictMock<NoRef>* BindTest::static_func_mock_ptr;
353 StrictMock<NoRef>* g_func_mock_ptr;
354
355 void VoidFunc0() {
356 g_func_mock_ptr->VoidMethod0();
357 }
358
359 int IntFunc0() {
360 return g_func_mock_ptr->IntMethod0();
361 }
343 362
344 // Sanity check that we can instantiate a callback for each arity. 363 // Sanity check that we can instantiate a callback for each arity.
345 TEST_F(BindTest, ArityTest) { 364 TEST_F(BindTest, ArityTest) {
346 Callback<int()> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1); 365 Callback<int()> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1);
347 EXPECT_EQ(63, c0.Run()); 366 EXPECT_EQ(63, c0.Run());
348 367
349 Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2); 368 Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2);
350 EXPECT_EQ(75, c1.Run(13)); 369 EXPECT_EQ(75, c1.Run(13));
351 370
352 Callback<int(int,int)> c2 = Bind(&Sum, 32, 16, 8, 4); 371 Callback<int(int,int)> c2 = Bind(&Sum, 32, 16, 8, 4);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 406
388 Callback<int()> c0 = Bind(c1, 1); 407 Callback<int()> c0 = Bind(c1, 1);
389 EXPECT_EQ(63, c0.Run()); 408 EXPECT_EQ(63, c0.Run());
390 } 409 }
391 410
392 // Test that currying the rvalue result of another Bind() works correctly. 411 // Test that currying the rvalue result of another Bind() works correctly.
393 // - rvalue should be usable as argument to Bind(). 412 // - rvalue should be usable as argument to Bind().
394 // - multiple runs of resulting Callback remain valid. 413 // - multiple runs of resulting Callback remain valid.
395 TEST_F(BindTest, CurryingRvalueResultOfBind) { 414 TEST_F(BindTest, CurryingRvalueResultOfBind) {
396 int n = 0; 415 int n = 0;
397 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n)); 416 RepeatingClosure cb = BindRepeating(&TakesACallback,
dcheng 2016/08/23 05:25:38 I guess this change now depends on the OneShotCall
tzik 2016/08/23 07:01:09 There was only one caller of Unwrap before the One
417 BindRepeating(&PtrArgSet, &n));
398 418
399 // If we implement Bind() such that the return value has auto_ptr-like 419 // If we implement Bind() such that the return value has auto_ptr-like
400 // semantics, the second call here will fail because ownership of 420 // semantics, the second call here will fail because ownership of
401 // the internal BindState<> would have been transfered to a *temporary* 421 // the internal BindState<> would have been transfered to a *temporary*
402 // constructon of a Callback object on the first call. 422 // constructon of a Callback object on the first call.
403 cb.Run(); 423 cb.Run();
404 EXPECT_EQ(2, n); 424 EXPECT_EQ(2, n);
405 425
406 n = 0; 426 n = 0;
407 cb.Run(); 427 cb.Run();
408 EXPECT_EQ(2, n); 428 EXPECT_EQ(2, n);
409 } 429 }
410 430
411 // Function type support. 431 TEST_F(BindTest, RepeatingCallbackBasicTest) {
412 // - Normal function. 432 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
413 // - Normal function bound with non-refcounted first argument.
414 // - Method bound to non-const object.
415 // - Method bound to scoped_refptr.
416 // - Const method bound to non-const object.
417 // - Const method bound to const object.
418 // - Derived classes can be used with pointers to non-virtual base functions.
419 // - Derived classes can be used with pointers to virtual base functions (and
420 // preserve virtual dispatch).
421 TEST_F(BindTest, FunctionTypeSupport) {
422 EXPECT_CALL(static_func_mock_, VoidMethod0());
423 EXPECT_CALL(has_ref_, AddRef()).Times(4);
424 EXPECT_CALL(has_ref_, Release()).Times(4);
425 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2);
426 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2);
427 433
428 Closure normal_cb = Bind(&VoidFunc0); 434 // RepeatingCallback can run via a lvalue-reference.
429 Callback<NoRef*()> normal_non_refcounted_cb = 435 EXPECT_EQ(63, c0.Run(32));
430 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_);
431 normal_cb.Run();
432 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run());
433 436
434 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); 437 // It is valid to call a RepeatingCallback more than once.
435 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0, 438 EXPECT_EQ(54, c0.Run(23));
436 make_scoped_refptr(&has_ref_));
437 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0,
438 &has_ref_);
439 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0,
440 const_has_ref_ptr_);
441 method_cb.Run();
442 method_refptr_cb.Run();
443 const_method_nonconst_obj_cb.Run();
444 const_method_const_obj_cb.Run();
445 439
446 Child child; 440 // BindRepeating can handle a RepeatingCallback as the target functor.
447 child.value = 0; 441 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
448 Closure virtual_set_cb = Bind(&Parent::VirtualSet, &child);
449 virtual_set_cb.Run();
450 EXPECT_EQ(kChildValue, child.value);
451 442
452 child.value = 0; 443 // RepeatingCallback can run via a rvalue-referenc.
453 Closure non_virtual_set_cb = Bind(&Parent::NonVirtualSet, &child); 444 EXPECT_EQ(42, std::move(c1).Run());
454 non_virtual_set_cb.Run(); 445
455 EXPECT_EQ(kParentValue, child.value); 446 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
447 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
456 } 448 }
457 449
458 // Return value support. 450 TEST_F(BindTest, OneShotCallbackBasicTest) {
459 // - Function with return value. 451 OneShotCallback<int(int)> c0 = BindOneShot(&Sum, 1, 2, 4, 8, 16);
460 // - Method with return value.
461 // - Const method with return value.
462 TEST_F(BindTest, ReturnValues) {
463 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
464 EXPECT_CALL(has_ref_, AddRef()).Times(3);
465 EXPECT_CALL(has_ref_, Release()).Times(3);
466 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337));
467 EXPECT_CALL(has_ref_, IntConstMethod0())
468 .WillOnce(Return(41337))
469 .WillOnce(Return(51337));
470 452
471 Callback<int()> normal_cb = Bind(&IntFunc0); 453 // OneShotCallback can run via a rvalue-reference.
472 Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_); 454 EXPECT_EQ(63, std::move(c0).Run(32));
473 Callback<int()> const_method_nonconst_obj_cb = 455
474 Bind(&HasRef::IntConstMethod0, &has_ref_); 456 // After running via the rvalue-reference, the value of the OneShotCallback
475 Callback<int()> const_method_const_obj_cb = 457 // is undefined. The implementation simply clears the instance after the
476 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_); 458 // invocation.
477 EXPECT_EQ(1337, normal_cb.Run()); 459 EXPECT_TRUE(c0.is_null());
478 EXPECT_EQ(31337, method_cb.Run()); 460
479 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run()); 461 c0 = BindOneShot(&Sum, 2, 3, 5, 7, 11);
480 EXPECT_EQ(51337, const_method_const_obj_cb.Run()); 462
463 // BindOneShot can handle a rvalue-reference of OneShotCallback as the target
464 // functor.
465 OneShotCallback<int()> c1 = BindOneShot(std::move(c0), 13);
466 EXPECT_EQ(41, std::move(c1).Run());
467
468 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
469 EXPECT_EQ(41, BindOneShot(c2, 13).Run());
481 } 470 }
482 471
483 // IgnoreResult adapter test. 472 // IgnoreResult adapter test.
484 // - Function with return value. 473 // - Function with return value.
485 // - Method with return value. 474 // - Method with return value.
486 // - Const Method with return. 475 // - Const Method with return.
487 // - Method with return value bound to WeakPtr<>. 476 // - Method with return value bound to WeakPtr<>.
488 // - Const Method with return bound to WeakPtr<>. 477 // - Const Method with return bound to WeakPtr<>.
489 TEST_F(BindTest, IgnoreResult) { 478 TEST_F(BindTest, IgnoreResultForRepeating) {
490 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); 479 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
491 EXPECT_CALL(has_ref_, AddRef()).Times(2); 480 EXPECT_CALL(has_ref_, AddRef()).Times(2);
492 EXPECT_CALL(has_ref_, Release()).Times(2); 481 EXPECT_CALL(has_ref_, Release()).Times(2);
493 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10)); 482 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
494 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11)); 483 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
495 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12)); 484 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
496 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13)); 485 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
497 486
498 Closure normal_func_cb = Bind(IgnoreResult(&IntFunc0)); 487 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
499 normal_func_cb.Run(); 488 normal_func_cb.Run();
500 489
501 Closure non_void_method_cb = 490 RepeatingClosure non_void_method_cb =
502 Bind(IgnoreResult(&HasRef::IntMethod0), &has_ref_); 491 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
503 non_void_method_cb.Run(); 492 non_void_method_cb.Run();
504 493
505 Closure non_void_const_method_cb = 494 RepeatingClosure non_void_const_method_cb =
506 Bind(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_); 495 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
507 non_void_const_method_cb.Run(); 496 non_void_const_method_cb.Run();
508 497
509 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 498 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
510 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 499 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
511 500
512 Closure non_void_weak_method_cb = 501 RepeatingClosure non_void_weak_method_cb =
513 Bind(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr()); 502 BindRepeating(IgnoreResult(&NoRef::IntMethod0),
503 weak_factory.GetWeakPtr());
514 non_void_weak_method_cb.Run(); 504 non_void_weak_method_cb.Run();
515 505
516 Closure non_void_weak_const_method_cb = 506 RepeatingClosure non_void_weak_const_method_cb =
517 Bind(IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr()); 507 BindRepeating(IgnoreResult(&NoRef::IntConstMethod0),
508 weak_factory.GetWeakPtr());
518 non_void_weak_const_method_cb.Run(); 509 non_void_weak_const_method_cb.Run();
519 510
520 weak_factory.InvalidateWeakPtrs(); 511 weak_factory.InvalidateWeakPtrs();
521 non_void_weak_const_method_cb.Run(); 512 non_void_weak_const_method_cb.Run();
522 non_void_weak_method_cb.Run(); 513 non_void_weak_method_cb.Run();
523 } 514 }
524 515
525 // Argument binding tests. 516 TEST_F(BindTest, IgnoreResultForOneShot) {
526 // - Argument binding to primitive. 517 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
527 // - Argument binding to primitive pointer. 518 EXPECT_CALL(has_ref_, AddRef()).Times(2);
528 // - Argument binding to a literal integer. 519 EXPECT_CALL(has_ref_, Release()).Times(2);
529 // - Argument binding to a literal string. 520 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
530 // - Argument binding with template function. 521 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
531 // - Argument binding to an object.
532 // - Argument binding to pointer to incomplete type.
533 // - Argument gets type converted.
534 // - Pointer argument gets converted.
535 // - Const Reference forces conversion.
536 TEST_F(BindTest, ArgumentBinding) {
537 int n = 2;
538 522
539 Callback<int()> bind_primitive_cb = Bind(&Identity, n); 523 OneShotClosure normal_func_cb = BindOneShot(IgnoreResult(&IntFunc0));
540 EXPECT_EQ(n, bind_primitive_cb.Run()); 524 std::move(normal_func_cb).Run();
541 525
542 Callback<int*()> bind_primitive_pointer_cb = 526 OneShotClosure non_void_method_cb =
543 Bind(&PolymorphicIdentity<int*>, &n); 527 BindOneShot(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
544 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run()); 528 std::move(non_void_method_cb).Run();
545 529
546 Callback<int()> bind_int_literal_cb = Bind(&Identity, 3); 530 OneShotClosure non_void_const_method_cb =
547 EXPECT_EQ(3, bind_int_literal_cb.Run()); 531 BindOneShot(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
532 std::move(non_void_const_method_cb).Run();
548 533
549 Callback<const char*()> bind_string_literal_cb = 534 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
550 Bind(&CStringIdentity, "hi"); 535 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
551 EXPECT_STREQ("hi", bind_string_literal_cb.Run());
552 536
553 Callback<int()> bind_template_function_cb = 537 OneShotClosure non_void_weak_method_cb =
554 Bind(&PolymorphicIdentity<int>, 4); 538 BindOneShot(IgnoreResult(&NoRef::IntMethod0),
555 EXPECT_EQ(4, bind_template_function_cb.Run()); 539 weak_factory.GetWeakPtr());
540 OneShotClosure non_void_weak_const_method_cb =
541 BindOneShot(IgnoreResult(&NoRef::IntConstMethod0),
542 weak_factory.GetWeakPtr());
556 543
557 NoRefParent p; 544 weak_factory.InvalidateWeakPtrs();
558 p.value = 5; 545 std::move(non_void_weak_const_method_cb).Run();
559 Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p); 546 std::move(non_void_weak_method_cb).Run();
560 EXPECT_EQ(5, bind_object_cb.Run());
561
562 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
563 Callback<IncompleteType*()> bind_incomplete_ptr_cb =
564 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr);
565 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run());
566
567 NoRefChild c;
568 c.value = 6;
569 Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c);
570 EXPECT_EQ(6, bind_promotes_cb.Run());
571
572 c.value = 7;
573 Callback<int()> bind_pointer_promotes_cb =
574 Bind(&UnwrapNoRefParentPtr, &c);
575 EXPECT_EQ(7, bind_pointer_promotes_cb.Run());
576
577 c.value = 8;
578 Callback<int()> bind_const_reference_promotes_cb =
579 Bind(&UnwrapNoRefParentConstRef, c);
580 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run());
581 }
582
583 // Unbound argument type support tests.
584 // - Unbound value.
585 // - Unbound pointer.
586 // - Unbound reference.
587 // - Unbound const reference.
588 // - Unbound unsized array.
589 // - Unbound sized array.
590 // - Unbound array-of-arrays.
591 TEST_F(BindTest, UnboundArgumentTypeSupport) {
592 Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic<int>::Run);
593 Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic<int*>::Run);
594 Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic<int&>::Run);
595 Callback<void(const int&)> unbound_const_ref_cb =
596 Bind(&VoidPolymorphic<const int&>::Run);
597 Callback<void(int[])> unbound_unsized_array_cb =
598 Bind(&VoidPolymorphic<int[]>::Run);
599 Callback<void(int[2])> unbound_sized_array_cb =
600 Bind(&VoidPolymorphic<int[2]>::Run);
601 Callback<void(int[][2])> unbound_array_of_arrays_cb =
602 Bind(&VoidPolymorphic<int[][2]>::Run);
603
604 Callback<void(int&)> unbound_ref_with_bound_arg =
605 Bind(&VoidPolymorphic<int, int&>::Run, 1);
606 }
607
608 // Function with unbound reference parameter.
609 // - Original parameter is modified by callback.
610 TEST_F(BindTest, UnboundReferenceSupport) {
611 int n = 0;
612 Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet);
613 unbound_ref_cb.Run(n);
614 EXPECT_EQ(2, n);
615 } 547 }
616 548
617 // Functions that take reference parameters. 549 // Functions that take reference parameters.
618 // - Forced reference parameter type still stores a copy. 550 // - Forced reference parameter type still stores a copy.
619 // - Forced const reference parameter type still stores a copy. 551 // - Forced const reference parameter type still stores a copy.
620 TEST_F(BindTest, ReferenceArgumentBinding) { 552 TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
621 int n = 1; 553 int n = 1;
622 int& ref_n = n; 554 int& ref_n = n;
623 const int& const_ref_n = n; 555 const int& const_ref_n = n;
624 556
625 Callback<int()> ref_copies_cb = Bind(&Identity, ref_n); 557 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
626 EXPECT_EQ(n, ref_copies_cb.Run()); 558 EXPECT_EQ(n, ref_copies_cb.Run());
627 n++; 559 n++;
628 EXPECT_EQ(n - 1, ref_copies_cb.Run()); 560 EXPECT_EQ(n - 1, ref_copies_cb.Run());
629 561
630 Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n); 562 RepeatingCallback<int()> const_ref_copies_cb =
563 BindRepeating(&Identity, const_ref_n);
631 EXPECT_EQ(n, const_ref_copies_cb.Run()); 564 EXPECT_EQ(n, const_ref_copies_cb.Run());
632 n++; 565 n++;
633 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); 566 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
634 } 567 }
635 568
569 TEST_F(BindTest, ReferenceArgumentBindingForOneShot) {
570 int n = 1;
571 int& ref_n = n;
572 const int& const_ref_n = n;
573
574 OneShotCallback<int()> ref_copies_cb = BindOneShot(&Identity, ref_n);
575 n++;
576 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
577
578 OneShotCallback<int()> const_ref_copies_cb =
579 BindOneShot(&Identity, const_ref_n);
580 n++;
581 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
582 }
583
636 // Check that we can pass in arrays and have them be stored as a pointer. 584 // Check that we can pass in arrays and have them be stored as a pointer.
637 // - Array of values stores a pointer. 585 // - Array of values stores a pointer.
638 // - Array of const values stores a pointer. 586 // - Array of const values stores a pointer.
639 TEST_F(BindTest, ArrayArgumentBinding) { 587 TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
640 int array[4] = {1, 1, 1, 1}; 588 int array[4] = {1, 1, 1, 1};
641 const int (*const_array_ptr)[4] = &array; 589 const int (*const_array_ptr)[4] = &array;
642 590
643 Callback<int()> array_cb = Bind(&ArrayGet, array, 1); 591 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
644 EXPECT_EQ(1, array_cb.Run()); 592 EXPECT_EQ(1, array_cb.Run());
645 593
646 Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1); 594 RepeatingCallback<int()> const_array_cb =
595 BindRepeating(&ArrayGet, *const_array_ptr, 1);
647 EXPECT_EQ(1, const_array_cb.Run()); 596 EXPECT_EQ(1, const_array_cb.Run());
648 597
649 array[1] = 3; 598 array[1] = 3;
650 EXPECT_EQ(3, array_cb.Run()); 599 EXPECT_EQ(3, array_cb.Run());
651 EXPECT_EQ(3, const_array_cb.Run()); 600 EXPECT_EQ(3, const_array_cb.Run());
652 } 601 }
653 602
654 // Unretained() wrapper support. 603 TEST_F(BindTest, ArrayArgumentBindingForOneShot) {
655 // - Method bound to Unretained() non-const object. 604 int array[4] = {1, 1, 1, 1};
656 // - Const method bound to Unretained() non-const object. 605 const int (*const_array_ptr)[4] = &array;
657 // - Const method bound to Unretained() const object.
658 TEST_F(BindTest, Unretained) {
659 EXPECT_CALL(no_ref_, VoidMethod0());
660 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
661 606
662 Callback<void()> method_cb = 607 OneShotCallback<int()> array_cb = BindOneShot(&ArrayGet, array, 1);
663 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_)); 608 OneShotCallback<int()> const_array_cb =
664 method_cb.Run(); 609 BindOneShot(&ArrayGet, *const_array_ptr, 1);
665 610
666 Callback<void()> const_method_cb = 611 array[1] = 3;
667 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_)); 612 EXPECT_EQ(3, std::move(array_cb).Run());
668 const_method_cb.Run(); 613 EXPECT_EQ(3, std::move(const_array_cb).Run());
669
670 Callback<void()> const_method_const_ptr_cb =
671 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_));
672 const_method_const_ptr_cb.Run();
673 } 614 }
674 615
675 // WeakPtr() support. 616 // WeakPtr() support.
676 // - Method bound to WeakPtr<> to non-const object. 617 // - Method bound to WeakPtr<> to non-const object.
677 // - Const method bound to WeakPtr<> to non-const object. 618 // - Const method bound to WeakPtr<> to non-const object.
678 // - Const method bound to WeakPtr<> to const object. 619 // - Const method bound to WeakPtr<> to const object.
679 // - Normal Function with WeakPtr<> as P1 can have return type and is 620 // - Normal Function with WeakPtr<> as P1 can have return type and is
680 // not canceled. 621 // not canceled.
681 TEST_F(BindTest, WeakPtr) { 622 TEST_F(BindTest, WeakPtrForRepeating) {
682 EXPECT_CALL(no_ref_, VoidMethod0()); 623 EXPECT_CALL(no_ref_, VoidMethod0());
683 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); 624 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
684 625
685 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 626 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
686 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 627 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
687 628
688 Closure method_cb = 629 RepeatingClosure method_cb =
689 Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr()); 630 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
690 method_cb.Run(); 631 method_cb.Run();
691 632
692 Closure const_method_cb = 633 RepeatingClosure const_method_cb =
693 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 634 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
694 const_method_cb.Run(); 635 const_method_cb.Run();
695 636
696 Closure const_method_const_ptr_cb = 637 RepeatingClosure const_method_const_ptr_cb =
697 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 638 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
698 const_method_const_ptr_cb.Run(); 639 const_method_const_ptr_cb.Run();
699 640
700 Callback<int(int)> normal_func_cb = 641 RepeatingCallback<int(int)> normal_func_cb =
701 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr()); 642 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
702 EXPECT_EQ(1, normal_func_cb.Run(1)); 643 EXPECT_EQ(1, normal_func_cb.Run(1));
703 644
704 weak_factory.InvalidateWeakPtrs(); 645 weak_factory.InvalidateWeakPtrs();
705 const_weak_factory.InvalidateWeakPtrs(); 646 const_weak_factory.InvalidateWeakPtrs();
706 647
707 method_cb.Run(); 648 method_cb.Run();
708 const_method_cb.Run(); 649 const_method_cb.Run();
709 const_method_const_ptr_cb.Run(); 650 const_method_const_ptr_cb.Run();
710 651
711 // Still runs even after the pointers are invalidated. 652 // Still runs even after the pointers are invalidated.
712 EXPECT_EQ(2, normal_func_cb.Run(2)); 653 EXPECT_EQ(2, normal_func_cb.Run(2));
713 } 654 }
714 655
656 TEST_F(BindTest, WeakPtrForOneShot) {
657 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
658 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
659
660 OneShotClosure method_cb =
661 BindOneShot(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
662 OneShotClosure const_method_cb =
663 BindOneShot(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
664 OneShotClosure const_method_const_ptr_cb =
665 BindOneShot(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
666 Callback<int(int)> normal_func_cb =
667 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
668
669 weak_factory.InvalidateWeakPtrs();
670 const_weak_factory.InvalidateWeakPtrs();
671
672 std::move(method_cb).Run();
673 std::move(const_method_cb).Run();
674 std::move(const_method_const_ptr_cb).Run();
675
676 // Still runs even after the pointers are invalidated.
677 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
678 }
679
715 // ConstRef() wrapper support. 680 // ConstRef() wrapper support.
716 // - Binding w/o ConstRef takes a copy. 681 // - Binding w/o ConstRef takes a copy.
717 // - Binding a ConstRef takes a reference. 682 // - Binding a ConstRef takes a reference.
718 // - Binding ConstRef to a function ConstRef does not copy on invoke. 683 // - Binding ConstRef to a function ConstRef does not copy on invoke.
719 TEST_F(BindTest, ConstRef) { 684 TEST_F(BindTest, ConstRefForRepeating) {
720 int n = 1; 685 int n = 1;
721 686
722 Callback<int()> copy_cb = Bind(&Identity, n); 687 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
723 Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n)); 688 RepeatingCallback<int()> const_ref_cb = BindRepeating(&Identity, ConstRef(n));
724 EXPECT_EQ(n, copy_cb.Run()); 689 EXPECT_EQ(n, copy_cb.Run());
725 EXPECT_EQ(n, const_ref_cb.Run()); 690 EXPECT_EQ(n, const_ref_cb.Run());
726 n++; 691 n++;
727 EXPECT_EQ(n - 1, copy_cb.Run()); 692 EXPECT_EQ(n - 1, copy_cb.Run());
728 EXPECT_EQ(n, const_ref_cb.Run()); 693 EXPECT_EQ(n, const_ref_cb.Run());
729 694
730 int copies = 0; 695 int copies = 0;
731 int assigns = 0; 696 int assigns = 0;
732 int move_constructs = 0; 697 int move_constructs = 0;
733 int move_assigns = 0; 698 int move_assigns = 0;
734 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns); 699 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
735 Callback<int()> all_const_ref_cb = 700 RepeatingCallback<int()> all_const_ref_cb =
736 Bind(&GetCopies, ConstRef(counter)); 701 BindRepeating(&GetCopies, ConstRef(counter));
737 EXPECT_EQ(0, all_const_ref_cb.Run()); 702 EXPECT_EQ(0, all_const_ref_cb.Run());
738 EXPECT_EQ(0, copies); 703 EXPECT_EQ(0, copies);
739 EXPECT_EQ(0, assigns); 704 EXPECT_EQ(0, assigns);
740 EXPECT_EQ(0, move_constructs); 705 EXPECT_EQ(0, move_constructs);
741 EXPECT_EQ(0, move_assigns); 706 EXPECT_EQ(0, move_assigns);
742 } 707 }
743 708
744 TEST_F(BindTest, ScopedRefptr) { 709 TEST_F(BindTest, ConstRefForOneShot) {
745 EXPECT_CALL(has_ref_, AddRef()).Times(1); 710 int n = 1;
746 EXPECT_CALL(has_ref_, Release()).Times(1);
747 711
748 const scoped_refptr<HasRef> refptr(&has_ref_); 712 OneShotCallback<int()> copy_cb = BindOneShot(&Identity, n);
749 Callback<int()> scoped_refptr_const_ref_cb = 713 OneShotCallback<int()> const_ref_cb = BindOneShot(&Identity, ConstRef(n));
750 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1); 714 n++;
751 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run()); 715 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
716 EXPECT_EQ(n, std::move(const_ref_cb).Run());
717
718 int copies = 0;
719 int assigns = 0;
720 int move_constructs = 0;
721 int move_assigns = 0;
722 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
723 OneShotCallback<int()> all_const_ref_cb =
724 BindOneShot(&GetCopies, ConstRef(counter));
725 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
726 EXPECT_EQ(0, copies);
727 EXPECT_EQ(0, assigns);
728 EXPECT_EQ(0, move_constructs);
729 EXPECT_EQ(0, move_assigns);
752 } 730 }
753 731
754 // Test Owned() support. 732 // Test Owned() support.
755 TEST_F(BindTest, Owned) { 733 TEST_F(BindTest, OwnedForRepeating) {
756 int deletes = 0; 734 int deletes = 0;
757 DeleteCounter* counter = new DeleteCounter(&deletes); 735 DeleteCounter* counter = new DeleteCounter(&deletes);
758 736
759 // If we don't capture, delete happens on Callback destruction/reset. 737 // If we don't capture, delete happens on Callback destruction/reset.
760 // return the same value. 738 // return the same value.
761 Callback<DeleteCounter*()> no_capture_cb = 739 RepeatingCallback<DeleteCounter*()> no_capture_cb =
762 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); 740 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
763 ASSERT_EQ(counter, no_capture_cb.Run()); 741 ASSERT_EQ(counter, no_capture_cb.Run());
764 ASSERT_EQ(counter, no_capture_cb.Run()); 742 ASSERT_EQ(counter, no_capture_cb.Run());
765 EXPECT_EQ(0, deletes); 743 EXPECT_EQ(0, deletes);
766 no_capture_cb.Reset(); // This should trigger a delete. 744 no_capture_cb.Reset(); // This should trigger a delete.
767 EXPECT_EQ(1, deletes); 745 EXPECT_EQ(1, deletes);
768 746
769 deletes = 0; 747 deletes = 0;
770 counter = new DeleteCounter(&deletes); 748 counter = new DeleteCounter(&deletes);
771 base::Closure own_object_cb = 749 RepeatingClosure own_object_cb =
772 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); 750 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
773 own_object_cb.Run(); 751 own_object_cb.Run();
774 EXPECT_EQ(0, deletes); 752 EXPECT_EQ(0, deletes);
775 own_object_cb.Reset(); 753 own_object_cb.Reset();
776 EXPECT_EQ(1, deletes); 754 EXPECT_EQ(1, deletes);
777 } 755 }
778 756
779 TEST_F(BindTest, UniquePtrReceiver) { 757 TEST_F(BindTest, OwnedForOneShot) {
758 int deletes = 0;
759 DeleteCounter* counter = new DeleteCounter(&deletes);
760
761 // If we don't capture, delete happens on Callback destruction/reset.
762 // return the same value.
763 OneShotCallback<DeleteCounter*()> no_capture_cb =
764 BindOneShot(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
765 EXPECT_EQ(0, deletes);
766 no_capture_cb.Reset(); // This should trigger a delete.
767 EXPECT_EQ(1, deletes);
768
769 deletes = 0;
770 counter = new DeleteCounter(&deletes);
771 OneShotClosure own_object_cb =
772 BindOneShot(&DeleteCounter::VoidMethod0, Owned(counter));
773 EXPECT_EQ(0, deletes);
774 own_object_cb.Reset();
775 EXPECT_EQ(1, deletes);
776 }
777
778 template <typename T>
779 class BindVariantsTest : public ::testing::Test {
780 };
781
782 struct RepeatingTestConfig {
783 template <typename Signature>
784 using CallbackType = RepeatingCallback<Signature>;
785 using ClosureType = RepeatingClosure;
786
787 template <typename F, typename... Args>
788 static CallbackType<MakeUnboundRunType<F, Args...>>
789 Bind(F&& f, Args&&... args) {
790 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
791 }
792 };
793
794 struct OneShotTestConfig {
795 template <typename Signature>
796 using CallbackType = OneShotCallback<Signature>;
797 using ClosureType = OneShotClosure;
798
799 template <typename F, typename... Args>
800 static CallbackType<MakeUnboundRunType<F, Args...>>
801 Bind(F&& f, Args&&... args) {
802 return BindOneShot(std::forward<F>(f), std::forward<Args>(args)...);
803 }
804 };
805
806 using BindVariantsTestConfig = ::testing::Types<
807 RepeatingTestConfig, OneShotTestConfig>;
808 TYPED_TEST_CASE(BindVariantsTest, BindVariantsTestConfig);
809
810 template <typename TypeParam, typename Signature>
811 using CallbackType = typename TypeParam::template CallbackType<Signature>;
812
813 // Function type support.
814 // - Normal function.
815 // - Normal function bound with non-refcounted first argument.
816 // - Method bound to non-const object.
817 // - Method bound to scoped_refptr.
818 // - Const method bound to non-const object.
819 // - Const method bound to const object.
820 // - Derived classes can be used with pointers to non-virtual base functions.
821 // - Derived classes can be used with pointers to virtual base functions (and
822 // preserve virtual dispatch).
823 TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
824 using ClosureType = typename TypeParam::ClosureType;
825
826 StrictMock<HasRef> has_ref;
827 StrictMock<NoRef> no_ref;
828 StrictMock<NoRef> static_func_mock;
829 const HasRef* const_has_ref_ptr = &has_ref;
830 g_func_mock_ptr = &static_func_mock;
831
832 EXPECT_CALL(static_func_mock, VoidMethod0());
833 EXPECT_CALL(has_ref, AddRef()).Times(4);
834 EXPECT_CALL(has_ref, Release()).Times(4);
835 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
836 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
837
838 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
839 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
840 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
841 std::move(normal_cb).Run();
842 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
843
844 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
845 ClosureType method_refptr_cb = TypeParam::Bind(&HasRef::VoidMethod0,
846 make_scoped_refptr(&has_ref));
847 ClosureType const_method_nonconst_obj_cb =
848 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
849 ClosureType const_method_const_obj_cb =
850 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
851 std::move(method_cb).Run();
852 std::move(method_refptr_cb).Run();
853 std::move(const_method_nonconst_obj_cb).Run();
854 std::move(const_method_const_obj_cb).Run();
855
856 Child child;
857 child.value = 0;
858 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
859 std::move(virtual_set_cb).Run();
860 EXPECT_EQ(kChildValue, child.value);
861
862 child.value = 0;
863 ClosureType non_virtual_set_cb =
864 TypeParam::Bind(&Parent::NonVirtualSet, &child);
865 std::move(non_virtual_set_cb).Run();
866 EXPECT_EQ(kParentValue, child.value);
867 }
868
869 // Return value support.
870 // - Function with return value.
871 // - Method with return value.
872 // - Const method with return value.
873 // - Move-only return value.
874 TYPED_TEST(BindVariantsTest, ReturnValues) {
875 StrictMock<NoRef> static_func_mock;
876 StrictMock<HasRef> has_ref;
877 g_func_mock_ptr = &static_func_mock;
878 const HasRef* const_has_ref_ptr = &has_ref;
879
880 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
881 EXPECT_CALL(has_ref, AddRef()).Times(4);
882 EXPECT_CALL(has_ref, Release()).Times(4);
883 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
884 EXPECT_CALL(has_ref, IntConstMethod0())
885 .WillOnce(Return(41337))
886 .WillOnce(Return(51337));
887 EXPECT_CALL(has_ref, UniquePtrMethod0())
888 .WillOnce(Return(ByMove(MakeUnique<int>(42))));
889
890 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
891 CallbackType<TypeParam, int()> method_cb =
892 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
893 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
894 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
895 CallbackType<TypeParam, int()> const_method_const_obj_cb =
896 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
897 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
898 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
899 EXPECT_EQ(1337, std::move(normal_cb).Run());
900 EXPECT_EQ(31337, std::move(method_cb).Run());
901 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
902 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
903 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
904 }
905
906 // Argument binding tests.
907 // - Argument binding to primitive.
908 // - Argument binding to primitive pointer.
909 // - Argument binding to a literal integer.
910 // - Argument binding to a literal string.
911 // - Argument binding with template function.
912 // - Argument binding to an object.
913 // - Argument binding to pointer to incomplete type.
914 // - Argument gets type converted.
915 // - Pointer argument gets converted.
916 // - Const Reference forces conversion.
917 TYPED_TEST(BindVariantsTest, ArgumentBinding) {
918 int n = 2;
919
920 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
921 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
922 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
923 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
924 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
925
926 NoRefParent p;
927 p.value = 5;
928 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
929
930 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
931 EXPECT_EQ(incomplete_ptr,
932 TypeParam::Bind(&PolymorphicIdentity<IncompleteType*>,
933 incomplete_ptr).Run());
934
935 NoRefChild c;
936 c.value = 6;
937 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
938
939 c.value = 7;
940 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
941
942 c.value = 8;
943 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
944 }
945
946 // Unbound argument type support tests.
947 // - Unbound value.
948 // - Unbound pointer.
949 // - Unbound reference.
950 // - Unbound const reference.
951 // - Unbound unsized array.
952 // - Unbound sized array.
953 // - Unbound array-of-arrays.
954 TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
955 CallbackType<TypeParam, void(int)> unbound_value_cb =
956 TypeParam::Bind(&VoidPolymorphic<int>::Run);
957 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
958 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
959 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
960 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
961 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
962 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
963 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
964 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
965 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
966 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
967 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
968 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
969 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
970 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
971 }
972
973 // Function with unbound reference parameter.
974 // - Original parameter is modified by callback.
975 TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
976 int n = 0;
977 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
978 TypeParam::Bind(&RefArgSet);
979 std::move(unbound_ref_cb).Run(n);
980 EXPECT_EQ(2, n);
981 }
982
983 // Unretained() wrapper support.
984 // - Method bound to Unretained() non-const object.
985 // - Const method bound to Unretained() non-const object.
986 // - Const method bound to Unretained() const object.
987 TYPED_TEST(BindVariantsTest, Unretained) {
988 StrictMock<NoRef> no_ref;
989 const NoRef* const_no_ref_ptr = &no_ref;
990
991 EXPECT_CALL(no_ref, VoidMethod0());
992 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
993
994 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
995 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
996 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
997 }
998
999 TYPED_TEST(BindVariantsTest, ScopedRefptr) {
1000 StrictMock<HasRef> has_ref;
1001 EXPECT_CALL(has_ref, AddRef()).Times(1);
1002 EXPECT_CALL(has_ref, Release()).Times(1);
1003
1004 const scoped_refptr<HasRef> refptr(&has_ref);
1005 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb =
1006 TypeParam::Bind(&FunctionWithScopedRefptrFirstParam,
1007 base::ConstRef(refptr), 1);
1008 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
1009 }
1010
1011 TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
780 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>); 1012 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
781 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1); 1013 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
782 Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run(); 1014 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
783 } 1015 }
784 1016
785 // Tests for Passed() wrapper support: 1017 // Tests for Passed() wrapper support:
786 // - Passed() can be constructed from a pointer to scoper. 1018 // - Passed() can be constructed from a pointer to scoper.
787 // - Passed() can be constructed from a scoper rvalue. 1019 // - Passed() can be constructed from a scoper rvalue.
788 // - Using Passed() gives Callback Ownership. 1020 // - Using Passed() gives Callback Ownership.
789 // - Ownership is transferred from Callback to callee on the first Run(). 1021 // - Ownership is transferred from Callback to callee on the first Run().
790 // - Callback supports unbound arguments. 1022 // - Callback supports unbound arguments.
791 template <typename T> 1023 template <typename T>
792 class BindMoveOnlyTypeTest : public ::testing::Test { 1024 class BindMoveOnlyTypeTest : public ::testing::Test {
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 1404
1173 // Test null callbacks cause a DCHECK. 1405 // Test null callbacks cause a DCHECK.
1174 TEST(BindDeathTest, NullCallback) { 1406 TEST(BindDeathTest, NullCallback) {
1175 base::Callback<void(int)> null_cb; 1407 base::Callback<void(int)> null_cb;
1176 ASSERT_TRUE(null_cb.is_null()); 1408 ASSERT_TRUE(null_cb.is_null());
1177 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42)); 1409 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42));
1178 } 1410 }
1179 1411
1180 } // namespace 1412 } // namespace
1181 } // namespace base 1413 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698