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 3 // found in the LICENSE file. 4 5 #include "base/bind.h" 6 7 #include <memory> 8 #include <utility> 9 10 #include <gmock/gmock.h> 11 #include <gtest/gtest.h> 12 13 #include "base/callback.h" 14 #include "base/macros.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/memory/weak_ptr.h" 18 #include "build/build_config.h" 19 20 using ::testing::Mock; 21 using ::testing::Return; 22 using ::testing::StrictMock; 23 24 namespace base { 25 namespace { 26 27 class IncompleteType; 28 29 class NoRef { 30 public: 31 NoRef() {} 32 33 MOCK_METHOD0(VoidMethod0, void()); 34 MOCK_CONST_METHOD0(VoidConstMethod0, void()); 35 36 MOCK_METHOD0(IntMethod0, int()); 37 MOCK_CONST_METHOD0(IntConstMethod0, int()); 38 39 private: 40 // Particularly important in this test to ensure no copies are made. 41 DISALLOW_COPY_AND_ASSIGN(NoRef); 42 }; 43 44 class HasRef : public NoRef { 45 public: 46 HasRef() {} 47 48 MOCK_CONST_METHOD0(AddRef, void()); 49 MOCK_CONST_METHOD0(Release, bool()); 50 51 private: 52 // Particularly important in this test to ensure no copies are made. 53 DISALLOW_COPY_AND_ASSIGN(HasRef); 54 }; 55 56 class HasRefPrivateDtor : public HasRef { 57 private: 58 ~HasRefPrivateDtor() {} 59 }; 60 61 static const int kParentValue = 1; 62 static const int kChildValue = 2; 63 64 class Parent { 65 public: 66 virtual ~Parent() = default; 67 void AddRef() const {} 68 void Release() const {} 69 virtual void VirtualSet() { value = kParentValue; } 70 void NonVirtualSet() { value = kParentValue; } 71 int value; 72 }; 73 74 class Child : public Parent { 75 public: 76 ~Child() override = default; 77 void VirtualSet() override { value = kChildValue; } 78 void NonVirtualSet() { value = kChildValue; } 79 }; 80 81 class NoRefParent { 82 public: 83 virtual ~NoRefParent() = default; 84 virtual void VirtualSet() { value = kParentValue; } 85 void NonVirtualSet() { value = kParentValue; } 86 int value; 87 }; 88 89 class NoRefChild : public NoRefParent { 90 public: 91 ~NoRefChild() override = default; 92 void VirtualSet() override { value = kChildValue; } 93 void NonVirtualSet() { value = kChildValue; } 94 }; 95 96 // Used for probing the number of copies that occur if a type must be coerced 97 // during argument forwarding in the Run() methods. 98 struct DerivedCopyCounter { 99 DerivedCopyCounter(int* copies, int* assigns) 100 : copies_(copies), assigns_(assigns) { 101 } 102 int* copies_; 103 int* assigns_; 104 }; 105 106 // Used for probing the number of copies in an argument. 107 class CopyCounter { 108 public: 109 CopyCounter(int* copies, int* assigns) 110 : copies_(copies), assigns_(assigns) { 111 } 112 113 CopyCounter(const CopyCounter& other) 114 : copies_(other.copies_), 115 assigns_(other.assigns_) { 116 (*copies_)++; 117 } 118 119 // Probing for copies from coercion. 120 explicit CopyCounter(const DerivedCopyCounter& other) 121 : copies_(other.copies_), 122 assigns_(other.assigns_) { 123 (*copies_)++; 124 } 125 126 const CopyCounter& operator=(const CopyCounter& rhs) { 127 copies_ = rhs.copies_; 128 assigns_ = rhs.assigns_; 129 130 if (assigns_) { 131 (*assigns_)++; 132 } 133 134 return *this; 135 } 136 137 int copies() const { 138 return *copies_; 139 } 140 141 private: 142 int* copies_; 143 int* assigns_; 144 }; 145 146 class DeleteCounter { 147 public: 148 explicit DeleteCounter(int* deletes) 149 : deletes_(deletes) { 150 } 151 152 ~DeleteCounter() { 153 (*deletes_)++; 154 } 155 156 void VoidMethod0() {} 157 158 private: 159 int* deletes_; 160 }; 161 162 template <typename T> 163 T PassThru(T scoper) { 164 return scoper; 165 } 166 167 // Some test functions that we can Bind to. 168 template <typename T> 169 T PolymorphicIdentity(T t) { 170 return t; 171 } 172 173 template <typename... Ts> 174 struct VoidPolymorphic { 175 static void Run(Ts... t) {} 176 }; 177 178 int Identity(int n) { 179 return n; 180 } 181 182 int ArrayGet(const int array[], int n) { 183 return array[n]; 184 } 185 186 int Sum(int a, int b, int c, int d, int e, int f) { 187 return a + b + c + d + e + f; 188 } 189 190 const char* CStringIdentity(const char* s) { 191 return s; 192 } 193 194 int GetCopies(const CopyCounter& counter) { 195 return counter.copies(); 196 } 197 198 int UnwrapNoRefParent(NoRefParent p) { 199 return p.value; 200 } 201 202 int UnwrapNoRefParentPtr(NoRefParent* p) { 203 return p->value; 204 } 205 206 int UnwrapNoRefParentConstRef(const NoRefParent& p) { 207 return p.value; 208 } 209 210 void RefArgSet(int &n) { 211 n = 2; 212 } 213 214 void PtrArgSet(int *n) { 215 *n = 2; 216 } 217 218 int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) { 219 return n; 220 } 221 222 int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) { 223 return n; 224 } 225 226 void TakesACallback(const Closure& callback) { 227 callback.Run(); 228 } 229 230 class BindTest : public ::testing::Test { 231 public: 232 BindTest() { 233 const_has_ref_ptr_ = &has_ref_; 234 const_no_ref_ptr_ = &no_ref_; 235 static_func_mock_ptr = &static_func_mock_; 236 } 237 238 virtual ~BindTest() { 239 } 240 241 static void VoidFunc0() { 242 static_func_mock_ptr->VoidMethod0(); 243 } 244 245 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); } 246 247 protected: 248 StrictMock<NoRef> no_ref_; 249 StrictMock<HasRef> has_ref_; 250 const HasRef* const_has_ref_ptr_; 251 const NoRef* const_no_ref_ptr_; 252 StrictMock<NoRef> static_func_mock_; 253 254 // Used by the static functions to perform expectations. 255 static StrictMock<NoRef>* static_func_mock_ptr; 256 257 private: 258 DISALLOW_COPY_AND_ASSIGN(BindTest); 259 }; 260 261 StrictMock<NoRef>* BindTest::static_func_mock_ptr; 262 263 // Sanity check that we can instantiate a callback for each arity. 264 TEST_F(BindTest, ArityTest) { 265 Callback<int()> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1); 266 EXPECT_EQ(63, c0.Run()); 267 268 Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2); 269 EXPECT_EQ(75, c1.Run(13)); 270 271 Callback<int(int,int)> c2 = Bind(&Sum, 32, 16, 8, 4); 272 EXPECT_EQ(85, c2.Run(13, 12)); 273 274 Callback<int(int,int,int)> c3 = Bind(&Sum, 32, 16, 8); 275 EXPECT_EQ(92, c3.Run(13, 12, 11)); 276 277 Callback<int(int,int,int,int)> c4 = Bind(&Sum, 32, 16); 278 EXPECT_EQ(94, c4.Run(13, 12, 11, 10)); 279 280 Callback<int(int,int,int,int,int)> c5 = Bind(&Sum, 32); 281 EXPECT_EQ(87, c5.Run(13, 12, 11, 10, 9)); 282 283 Callback<int(int,int,int,int,int,int)> c6 = Bind(&Sum); 284 EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14)); 285 } 286 287 // Test the Currying ability of the Callback system. 288 TEST_F(BindTest, CurryingTest) { 289 Callback<int(int,int,int,int,int,int)> c6 = Bind(&Sum); 290 EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14)); 291 292 Callback<int(int,int,int,int,int)> c5 = Bind(c6, 32); 293 EXPECT_EQ(87, c5.Run(13, 12, 11, 10, 9)); 294 295 Callback<int(int,int,int,int)> c4 = Bind(c5, 16); 296 EXPECT_EQ(94, c4.Run(13, 12, 11, 10)); 297 298 Callback<int(int,int,int)> c3 = Bind(c4, 8); 299 EXPECT_EQ(92, c3.Run(13, 12, 11)); 300 301 Callback<int(int,int)> c2 = Bind(c3, 4); 302 EXPECT_EQ(85, c2.Run(13, 12)); 303 304 Callback<int(int)> c1 = Bind(c2, 2); 305 EXPECT_EQ(75, c1.Run(13)); 306 307 Callback<int()> c0 = Bind(c1, 1); 308 EXPECT_EQ(63, c0.Run()); 309 } 310 311 // Test that currying the rvalue result of another Bind() works correctly. 312 // - rvalue should be usable as argument to Bind(). 313 // - multiple runs of resulting Callback remain valid. 314 TEST_F(BindTest, CurryingRvalueResultOfBind) { 315 int n = 0; 316 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n)); 317 318 // If we implement Bind() such that the return value has auto_ptr-like 319 // semantics, the second call here will fail because ownership of 320 // the internal BindState<> would have been transfered to a *temporary* 321 // constructon of a Callback object on the first call. 322 cb.Run(); 323 EXPECT_EQ(2, n); 324 325 n = 0; 326 cb.Run(); 327 EXPECT_EQ(2, n); 328 } 329 330 // Function type support. 331 // - Normal function. 332 // - Normal function bound with non-refcounted first argument. 333 // - Method bound to non-const object. 334 // - Method bound to scoped_refptr. 335 // - Const method bound to non-const object. 336 // - Const method bound to const object. 337 // - Derived classes can be used with pointers to non-virtual base functions. 338 // - Derived classes can be used with pointers to virtual base functions (and 339 // preserve virtual dispatch). 340 TEST_F(BindTest, FunctionTypeSupport) { 341 EXPECT_CALL(static_func_mock_, VoidMethod0()); 342 EXPECT_CALL(has_ref_, AddRef()).Times(5); 343 EXPECT_CALL(has_ref_, Release()).Times(5); 344 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2); 345 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2); 346 347 Closure normal_cb = Bind(&VoidFunc0); 348 Callback<NoRef*()> normal_non_refcounted_cb = 349 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_); 350 normal_cb.Run(); 351 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run()); 352 353 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); 354 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0, 355 make_scoped_refptr(&has_ref_)); 356 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0, 357 &has_ref_); 358 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0, 359 const_has_ref_ptr_); 360 method_cb.Run(); 361 method_refptr_cb.Run(); 362 const_method_nonconst_obj_cb.Run(); 363 const_method_const_obj_cb.Run(); 364 365 Child child; 366 child.value = 0; 367 Closure virtual_set_cb = Bind(&Parent::VirtualSet, &child); 368 virtual_set_cb.Run(); 369 EXPECT_EQ(kChildValue, child.value); 370 371 child.value = 0; 372 Closure non_virtual_set_cb = Bind(&Parent::NonVirtualSet, &child); 373 non_virtual_set_cb.Run(); 374 EXPECT_EQ(kParentValue, child.value); 375 } 376 377 // Return value support. 378 // - Function with return value. 379 // - Method with return value. 380 // - Const method with return value. 381 TEST_F(BindTest, ReturnValues) { 382 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); 383 EXPECT_CALL(has_ref_, AddRef()).Times(3); 384 EXPECT_CALL(has_ref_, Release()).Times(3); 385 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337)); 386 EXPECT_CALL(has_ref_, IntConstMethod0()) 387 .WillOnce(Return(41337)) 388 .WillOnce(Return(51337)); 389 390 Callback<int()> normal_cb = Bind(&IntFunc0); 391 Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_); 392 Callback<int()> const_method_nonconst_obj_cb = 393 Bind(&HasRef::IntConstMethod0, &has_ref_); 394 Callback<int()> const_method_const_obj_cb = 395 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_); 396 EXPECT_EQ(1337, normal_cb.Run()); 397 EXPECT_EQ(31337, method_cb.Run()); 398 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run()); 399 EXPECT_EQ(51337, const_method_const_obj_cb.Run()); 400 } 401 402 // IgnoreResult adapter test. 403 // - Function with return value. 404 // - Method with return value. 405 // - Const Method with return. 406 // - Method with return value bound to WeakPtr<>. 407 // - Const Method with return bound to WeakPtr<>. 408 TEST_F(BindTest, IgnoreResult) { 409 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); 410 EXPECT_CALL(has_ref_, AddRef()).Times(2); 411 EXPECT_CALL(has_ref_, Release()).Times(2); 412 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10)); 413 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11)); 414 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12)); 415 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13)); 416 417 Closure normal_func_cb = Bind(IgnoreResult(&IntFunc0)); 418 normal_func_cb.Run(); 419 420 Closure non_void_method_cb = 421 Bind(IgnoreResult(&HasRef::IntMethod0), &has_ref_); 422 non_void_method_cb.Run(); 423 424 Closure non_void_const_method_cb = 425 Bind(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_); 426 non_void_const_method_cb.Run(); 427 428 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 429 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 430 431 Closure non_void_weak_method_cb = 432 Bind(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr()); 433 non_void_weak_method_cb.Run(); 434 435 Closure non_void_weak_const_method_cb = 436 Bind(IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr()); 437 non_void_weak_const_method_cb.Run(); 438 439 weak_factory.InvalidateWeakPtrs(); 440 non_void_weak_const_method_cb.Run(); 441 non_void_weak_method_cb.Run(); 442 } 443 444 // Argument binding tests. 445 // - Argument binding to primitive. 446 // - Argument binding to primitive pointer. 447 // - Argument binding to a literal integer. 448 // - Argument binding to a literal string. 449 // - Argument binding with template function. 450 // - Argument binding to an object. 451 // - Argument binding to pointer to incomplete type. 452 // - Argument gets type converted. 453 // - Pointer argument gets converted. 454 // - Const Reference forces conversion. 455 TEST_F(BindTest, ArgumentBinding) { 456 int n = 2; 457 458 Callback<int()> bind_primitive_cb = Bind(&Identity, n); 459 EXPECT_EQ(n, bind_primitive_cb.Run()); 460 461 Callback<int*()> bind_primitive_pointer_cb = 462 Bind(&PolymorphicIdentity<int*>, &n); 463 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run()); 464 465 Callback<int()> bind_int_literal_cb = Bind(&Identity, 3); 466 EXPECT_EQ(3, bind_int_literal_cb.Run()); 467 468 Callback<const char*()> bind_string_literal_cb = 469 Bind(&CStringIdentity, "hi"); 470 EXPECT_STREQ("hi", bind_string_literal_cb.Run()); 471 472 Callback<int()> bind_template_function_cb = 473 Bind(&PolymorphicIdentity<int>, 4); 474 EXPECT_EQ(4, bind_template_function_cb.Run()); 475 476 NoRefParent p; 477 p.value = 5; 478 Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p); 479 EXPECT_EQ(5, bind_object_cb.Run()); 480 481 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123); 482 Callback<IncompleteType*()> bind_incomplete_ptr_cb = 483 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr); 484 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run()); 485 486 NoRefChild c; 487 c.value = 6; 488 Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c); 489 EXPECT_EQ(6, bind_promotes_cb.Run()); 490 491 c.value = 7; 492 Callback<int()> bind_pointer_promotes_cb = 493 Bind(&UnwrapNoRefParentPtr, &c); 494 EXPECT_EQ(7, bind_pointer_promotes_cb.Run()); 495 496 c.value = 8; 497 Callback<int()> bind_const_reference_promotes_cb = 498 Bind(&UnwrapNoRefParentConstRef, c); 499 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run()); 500 } 501 502 // Unbound argument type support tests. 503 // - Unbound value. 504 // - Unbound pointer. 505 // - Unbound reference. 506 // - Unbound const reference. 507 // - Unbound unsized array. 508 // - Unbound sized array. 509 // - Unbound array-of-arrays. 510 TEST_F(BindTest, UnboundArgumentTypeSupport) { 511 Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic<int>::Run); 512 Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic<int*>::Run); 513 Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic<int&>::Run); 514 Callback<void(const int&)> unbound_const_ref_cb = 515 Bind(&VoidPolymorphic<const int&>::Run); 516 Callback<void(int[])> unbound_unsized_array_cb = 517 Bind(&VoidPolymorphic<int[]>::Run); 518 Callback<void(int[2])> unbound_sized_array_cb = 519 Bind(&VoidPolymorphic<int[2]>::Run); 520 Callback<void(int[][2])> unbound_array_of_arrays_cb = 521 Bind(&VoidPolymorphic<int[][2]>::Run); 522 523 Callback<void(int&)> unbound_ref_with_bound_arg = 524 Bind(&VoidPolymorphic<int, int&>::Run, 1); 525 } 526 527 // Function with unbound reference parameter. 528 // - Original parameter is modified by callback. 529 TEST_F(BindTest, UnboundReferenceSupport) { 530 int n = 0; 531 Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet); 532 unbound_ref_cb.Run(n); 533 EXPECT_EQ(2, n); 534 } 535 536 // Functions that take reference parameters. 537 // - Forced reference parameter type still stores a copy. 538 // - Forced const reference parameter type still stores a copy. 539 TEST_F(BindTest, ReferenceArgumentBinding) { 540 int n = 1; 541 int& ref_n = n; 542 const int& const_ref_n = n; 543 544 Callback<int()> ref_copies_cb = Bind(&Identity, ref_n); 545 EXPECT_EQ(n, ref_copies_cb.Run()); 546 n++; 547 EXPECT_EQ(n - 1, ref_copies_cb.Run()); 548 549 Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n); 550 EXPECT_EQ(n, const_ref_copies_cb.Run()); 551 n++; 552 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); 553 } 554 555 // Check that we can pass in arrays and have them be stored as a pointer. 556 // - Array of values stores a pointer. 557 // - Array of const values stores a pointer. 558 TEST_F(BindTest, ArrayArgumentBinding) { 559 int array[4] = {1, 1, 1, 1}; 560 const int (*const_array_ptr)[4] = &array; 561 562 Callback<int()> array_cb = Bind(&ArrayGet, array, 1); 563 EXPECT_EQ(1, array_cb.Run()); 564 565 Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1); 566 EXPECT_EQ(1, const_array_cb.Run()); 567 568 array[1] = 3; 569 EXPECT_EQ(3, array_cb.Run()); 570 EXPECT_EQ(3, const_array_cb.Run()); 571 } 572 573 // Verify SupportsAddRefAndRelease correctly introspects the class type for 574 // AddRef() and Release(). 575 // - Class with AddRef() and Release() 576 // - Class without AddRef() and Release() 577 // - Derived Class with AddRef() and Release() 578 // - Derived Class without AddRef() and Release() 579 // - Derived Class with AddRef() and Release() and a private destructor. 580 TEST_F(BindTest, SupportsAddRefAndRelease) { 581 EXPECT_TRUE(internal::SupportsAddRefAndRelease<HasRef>::value); 582 EXPECT_FALSE(internal::SupportsAddRefAndRelease<NoRef>::value); 583 584 // StrictMock<T> is a derived class of T. So, we use StrictMock<HasRef> and 585 // StrictMock<NoRef> to test that SupportsAddRefAndRelease works over 586 // inheritance. 587 EXPECT_TRUE(internal::SupportsAddRefAndRelease<StrictMock<HasRef> >::value); 588 EXPECT_FALSE(internal::SupportsAddRefAndRelease<StrictMock<NoRef> >::value); 589 590 // This matters because the implementation creates a dummy class that 591 // inherits from the template type. 592 EXPECT_TRUE(internal::SupportsAddRefAndRelease<HasRefPrivateDtor>::value); 593 } 594 595 // Unretained() wrapper support. 596 // - Method bound to Unretained() non-const object. 597 // - Const method bound to Unretained() non-const object. 598 // - Const method bound to Unretained() const object. 599 TEST_F(BindTest, Unretained) { 600 EXPECT_CALL(no_ref_, VoidMethod0()); 601 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); 602 603 Callback<void()> method_cb = 604 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_)); 605 method_cb.Run(); 606 607 Callback<void()> const_method_cb = 608 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_)); 609 const_method_cb.Run(); 610 611 Callback<void()> const_method_const_ptr_cb = 612 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_)); 613 const_method_const_ptr_cb.Run(); 614 } 615 616 // WeakPtr() support. 617 // - Method bound to WeakPtr<> to non-const object. 618 // - Const method bound to WeakPtr<> to non-const object. 619 // - Const method bound to WeakPtr<> to const object. 620 // - Normal Function with WeakPtr<> as P1 can have return type and is 621 // not canceled. 622 TEST_F(BindTest, WeakPtr) { 623 EXPECT_CALL(no_ref_, VoidMethod0()); 624 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); 625 626 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 627 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 628 629 Closure method_cb = 630 Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr()); 631 method_cb.Run(); 632 633 Closure const_method_cb = 634 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 635 const_method_cb.Run(); 636 637 Closure const_method_const_ptr_cb = 638 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 639 const_method_const_ptr_cb.Run(); 640 641 Callback<int(int)> normal_func_cb = 642 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr()); 643 EXPECT_EQ(1, normal_func_cb.Run(1)); 644 645 weak_factory.InvalidateWeakPtrs(); 646 const_weak_factory.InvalidateWeakPtrs(); 647 648 method_cb.Run(); 649 const_method_cb.Run(); 650 const_method_const_ptr_cb.Run(); 651 652 // Still runs even after the pointers are invalidated. 653 EXPECT_EQ(2, normal_func_cb.Run(2)); 654 } 655 656 // ConstRef() wrapper support. 657 // - Binding w/o ConstRef takes a copy. 658 // - Binding a ConstRef takes a reference. 659 // - Binding ConstRef to a function ConstRef does not copy on invoke. 660 TEST_F(BindTest, ConstRef) { 661 int n = 1; 662 663 Callback<int()> copy_cb = Bind(&Identity, n); 664 Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n)); 665 EXPECT_EQ(n, copy_cb.Run()); 666 EXPECT_EQ(n, const_ref_cb.Run()); 667 n++; 668 EXPECT_EQ(n - 1, copy_cb.Run()); 669 EXPECT_EQ(n, const_ref_cb.Run()); 670 671 int copies = 0; 672 int assigns = 0; 673 CopyCounter counter(&copies, &assigns); 674 Callback<int()> all_const_ref_cb = 675 Bind(&GetCopies, ConstRef(counter)); 676 EXPECT_EQ(0, all_const_ref_cb.Run()); 677 EXPECT_EQ(0, copies); 678 EXPECT_EQ(0, assigns); 679 } 680 681 TEST_F(BindTest, ScopedRefptr) { 682 // BUG: The scoped_refptr should cause the only AddRef()/Release() pair. But 683 // due to a bug in base::Bind(), there's an extra call when invoking the 684 // callback. 685 // https://code.google.com/p/chromium/issues/detail?id=251937 686 EXPECT_CALL(has_ref_, AddRef()).Times(2); 687 EXPECT_CALL(has_ref_, Release()).Times(2); 688 689 const scoped_refptr<StrictMock<HasRef> > refptr(&has_ref_); 690 691 Callback<int()> scoped_refptr_const_ref_cb = 692 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1); 693 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run()); 694 } 695 696 // Test Owned() support. 697 TEST_F(BindTest, Owned) { 698 int deletes = 0; 699 DeleteCounter* counter = new DeleteCounter(&deletes); 700 701 // If we don't capture, delete happens on Callback destruction/reset. 702 // return the same value. 703 Callback<DeleteCounter*()> no_capture_cb = 704 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); 705 ASSERT_EQ(counter, no_capture_cb.Run()); 706 ASSERT_EQ(counter, no_capture_cb.Run()); 707 EXPECT_EQ(0, deletes); 708 no_capture_cb.Reset(); // This should trigger a delete. 709 EXPECT_EQ(1, deletes); 710 711 deletes = 0; 712 counter = new DeleteCounter(&deletes); 713 base::Closure own_object_cb = 714 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); 715 own_object_cb.Run(); 716 EXPECT_EQ(0, deletes); 717 own_object_cb.Reset(); 718 EXPECT_EQ(1, deletes); 719 } 720 721 // Passed() wrapper support. 722 // - Passed() can be constructed from a pointer to scoper. 723 // - Passed() can be constructed from a scoper rvalue. 724 // - Using Passed() gives Callback Ownership. 725 // - Ownership is transferred from Callback to callee on the first Run(). 726 // - Callback supports unbound arguments. 727 TEST_F(BindTest, ScopedPtr) { 728 int deletes = 0; 729 730 // Tests the Passed() function's support for pointers. 731 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); 732 Callback<scoped_ptr<DeleteCounter>()> unused_callback = 733 Bind(&PassThru<scoped_ptr<DeleteCounter> >, Passed(&ptr)); 734 EXPECT_FALSE(ptr.get()); 735 EXPECT_EQ(0, deletes); 736 737 // If we never invoke the Callback, it retains ownership and deletes. 738 unused_callback.Reset(); 739 EXPECT_EQ(1, deletes); 740 741 // Tests the Passed() function's support for rvalues. 742 deletes = 0; 743 DeleteCounter* counter = new DeleteCounter(&deletes); 744 Callback<scoped_ptr<DeleteCounter>()> callback = 745 Bind(&PassThru<scoped_ptr<DeleteCounter> >, 746 Passed(scoped_ptr<DeleteCounter>(counter))); 747 EXPECT_FALSE(ptr.get()); 748 EXPECT_EQ(0, deletes); 749 750 // Check that ownership can be transferred back out. 751 scoped_ptr<DeleteCounter> result = callback.Run(); 752 ASSERT_EQ(counter, result.get()); 753 EXPECT_EQ(0, deletes); 754 755 // Resetting does not delete since ownership was transferred. 756 callback.Reset(); 757 EXPECT_EQ(0, deletes); 758 759 // Ensure that we actually did get ownership. 760 result.reset(); 761 EXPECT_EQ(1, deletes); 762 763 // Test unbound argument forwarding. 764 Callback<scoped_ptr<DeleteCounter>(scoped_ptr<DeleteCounter>)> cb_unbound = 765 Bind(&PassThru<scoped_ptr<DeleteCounter> >); 766 ptr.reset(new DeleteCounter(&deletes)); 767 cb_unbound.Run(std::move(ptr)); 768 } 769 770 TEST_F(BindTest, UniquePtr) { 771 int deletes = 0; 772 773 // Tests the Passed() function's support for pointers. 774 std::unique_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); 775 Callback<std::unique_ptr<DeleteCounter>()> unused_callback = 776 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, Passed(&ptr)); 777 EXPECT_FALSE(ptr.get()); 778 EXPECT_EQ(0, deletes); 779 780 // If we never invoke the Callback, it retains ownership and deletes. 781 unused_callback.Reset(); 782 EXPECT_EQ(1, deletes); 783 784 // Tests the Passed() function's support for rvalues. 785 deletes = 0; 786 DeleteCounter* counter = new DeleteCounter(&deletes); 787 Callback<std::unique_ptr<DeleteCounter>()> callback = 788 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, 789 Passed(std::unique_ptr<DeleteCounter>(counter))); 790 EXPECT_FALSE(ptr.get()); 791 EXPECT_EQ(0, deletes); 792 793 // Check that ownership can be transferred back out. 794 std::unique_ptr<DeleteCounter> result = callback.Run(); 795 ASSERT_EQ(counter, result.get()); 796 EXPECT_EQ(0, deletes); 797 798 // Resetting does not delete since ownership was transferred. 799 callback.Reset(); 800 EXPECT_EQ(0, deletes); 801 802 // Ensure that we actually did get ownership. 803 result.reset(); 804 EXPECT_EQ(1, deletes); 805 806 // Test unbound argument forwarding. 807 Callback<std::unique_ptr<DeleteCounter>(std::unique_ptr<DeleteCounter>)> 808 cb_unbound = Bind(&PassThru<std::unique_ptr<DeleteCounter>>); 809 ptr.reset(new DeleteCounter(&deletes)); 810 cb_unbound.Run(std::move(ptr)); 811 } 812 813 // Argument Copy-constructor usage for non-reference parameters. 814 // - Bound arguments are only copied once. 815 // - Forwarded arguments are only copied once. 816 // - Forwarded arguments with coercions are only copied twice (once for the 817 // coercion, and one for the final dispatch). 818 TEST_F(BindTest, ArgumentCopies) { 819 int copies = 0; 820 int assigns = 0; 821 822 CopyCounter counter(&copies, &assigns); 823 824 Callback<void()> copy_cb = 825 Bind(&VoidPolymorphic<CopyCounter>::Run, counter); 826 EXPECT_GE(1, copies); 827 EXPECT_EQ(0, assigns); 828 829 copies = 0; 830 assigns = 0; 831 Callback<void(CopyCounter)> forward_cb = 832 Bind(&VoidPolymorphic<CopyCounter>::Run); 833 forward_cb.Run(counter); 834 EXPECT_GE(1, copies); 835 EXPECT_EQ(0, assigns); 836 837 copies = 0; 838 assigns = 0; 839 DerivedCopyCounter derived(&copies, &assigns); 840 Callback<void(CopyCounter)> coerce_cb = 841 Bind(&VoidPolymorphic<CopyCounter>::Run); 842 coerce_cb.Run(CopyCounter(derived)); 843 EXPECT_GE(2, copies); 844 EXPECT_EQ(0, assigns); 845 } 846 847 // Callback construction and assignment tests. 848 // - Construction from an InvokerStorageHolder should not cause ref/deref. 849 // - Assignment from other callback should only cause one ref 850 // 851 // TODO(ajwong): Is there actually a way to test this? 852 853 #if defined(OS_WIN) 854 int __fastcall FastCallFunc(int n) { 855 return n; 856 } 857 858 int __stdcall StdCallFunc(int n) { 859 return n; 860 } 861 862 // Windows specific calling convention support. 863 // - Can bind a __fastcall function. 864 // - Can bind a __stdcall function. 865 TEST_F(BindTest, WindowsCallingConventions) { 866 Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1); 867 EXPECT_EQ(1, fastcall_cb.Run()); 868 869 Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2); 870 EXPECT_EQ(2, stdcall_cb.Run()); 871 } 872 #endif 873 874 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST 875 876 // Test null callbacks cause a DCHECK. 877 TEST(BindDeathTest, NullCallback) { 878 base::Callback<void(int)> null_cb; 879 ASSERT_TRUE(null_cb.is_null()); 880 EXPECT_DEATH(base::Bind(null_cb, 42), ""); 881 } 882 883 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && 884 // GTEST_HAS_DEATH_TEST 885 886 } // namespace 887 } // namespace base 888