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 20using ::testing::Mock; 21using ::testing::Return; 22using ::testing::StrictMock; 23 24namespace base { 25namespace { 26 27class IncompleteType; 28 29class 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 44class 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 56class HasRefPrivateDtor : public HasRef { 57 private: 58 ~HasRefPrivateDtor() {} 59}; 60 61static const int kParentValue = 1; 62static const int kChildValue = 2; 63 64class 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 74class Child : public Parent { 75 public: 76 ~Child() override = default; 77 void VirtualSet() override { value = kChildValue; } 78 void NonVirtualSet() { value = kChildValue; } 79}; 80 81class NoRefParent { 82 public: 83 virtual ~NoRefParent() = default; 84 virtual void VirtualSet() { value = kParentValue; } 85 void NonVirtualSet() { value = kParentValue; } 86 int value; 87}; 88 89class 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. 98struct 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. 107class 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 146class 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 162template <typename T> 163T PassThru(T scoper) { 164 return scoper; 165} 166 167// Some test functions that we can Bind to. 168template <typename T> 169T PolymorphicIdentity(T t) { 170 return t; 171} 172 173template <typename... Ts> 174struct VoidPolymorphic { 175 static void Run(Ts... t) {} 176}; 177 178int Identity(int n) { 179 return n; 180} 181 182int ArrayGet(const int array[], int n) { 183 return array[n]; 184} 185 186int Sum(int a, int b, int c, int d, int e, int f) { 187 return a + b + c + d + e + f; 188} 189 190const char* CStringIdentity(const char* s) { 191 return s; 192} 193 194int GetCopies(const CopyCounter& counter) { 195 return counter.copies(); 196} 197 198int UnwrapNoRefParent(NoRefParent p) { 199 return p.value; 200} 201 202int UnwrapNoRefParentPtr(NoRefParent* p) { 203 return p->value; 204} 205 206int UnwrapNoRefParentConstRef(const NoRefParent& p) { 207 return p.value; 208} 209 210void RefArgSet(int &n) { 211 n = 2; 212} 213 214void PtrArgSet(int *n) { 215 *n = 2; 216} 217 218int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) { 219 return n; 220} 221 222int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) { 223 return n; 224} 225 226void TakesACallback(const Closure& callback) { 227 callback.Run(); 228} 229 230class 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 261StrictMock<NoRef>* BindTest::static_func_mock_ptr; 262 263// Sanity check that we can instantiate a callback for each arity. 264TEST_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. 288TEST_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. 314TEST_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). 340TEST_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. 381TEST_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<>. 408TEST_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. 455TEST_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. 510TEST_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. 529TEST_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. 539TEST_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. 558TEST_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. 580TEST_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. 599TEST_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. 622TEST_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. 660TEST_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 681TEST_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. 697TEST_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. 727TEST_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 770TEST_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). 818TEST_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) 854int __fastcall FastCallFunc(int n) { 855 return n; 856} 857 858int __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. 865TEST_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. 877TEST(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