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

Side by Side Diff: base/bind_unittest.cc

Issue 2122543002: Replace Closure in TaskRunner::PostTask with OneShotCallback (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@07_oneshot
Patch Set: fix Created 4 years, 3 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
« no previous file with comments | « base/bind.h ('k') | base/callback_forward.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
25 namespace base { 26 namespace base {
26 namespace { 27 namespace {
27 28
28 class IncompleteType; 29 class IncompleteType;
29 30
30 class NoRef { 31 class NoRef {
31 public: 32 public:
32 NoRef() {} 33 NoRef() {}
33 34
34 MOCK_METHOD0(VoidMethod0, void()); 35 MOCK_METHOD0(VoidMethod0, void());
35 MOCK_CONST_METHOD0(VoidConstMethod0, void()); 36 MOCK_CONST_METHOD0(VoidConstMethod0, void());
36 37
37 MOCK_METHOD0(IntMethod0, int()); 38 MOCK_METHOD0(IntMethod0, int());
38 MOCK_CONST_METHOD0(IntConstMethod0, int()); 39 MOCK_CONST_METHOD0(IntConstMethod0, int());
39 40
41 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
42
40 private: 43 private:
41 // Particularly important in this test to ensure no copies are made. 44 // Particularly important in this test to ensure no copies are made.
42 DISALLOW_COPY_AND_ASSIGN(NoRef); 45 DISALLOW_COPY_AND_ASSIGN(NoRef);
43 }; 46 };
44 47
45 class HasRef : public NoRef { 48 class HasRef : public NoRef {
46 public: 49 public:
47 HasRef() {} 50 HasRef() {}
48 51
49 MOCK_CONST_METHOD0(AddRef, void()); 52 MOCK_CONST_METHOD0(AddRef, void());
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 StrictMock<NoRef> static_func_mock_; 336 StrictMock<NoRef> static_func_mock_;
334 337
335 // Used by the static functions to perform expectations. 338 // Used by the static functions to perform expectations.
336 static StrictMock<NoRef>* static_func_mock_ptr; 339 static StrictMock<NoRef>* static_func_mock_ptr;
337 340
338 private: 341 private:
339 DISALLOW_COPY_AND_ASSIGN(BindTest); 342 DISALLOW_COPY_AND_ASSIGN(BindTest);
340 }; 343 };
341 344
342 StrictMock<NoRef>* BindTest::static_func_mock_ptr; 345 StrictMock<NoRef>* BindTest::static_func_mock_ptr;
346 StrictMock<NoRef>* g_func_mock_ptr;
347
348 void VoidFunc0() {
349 g_func_mock_ptr->VoidMethod0();
350 }
351
352 int IntFunc0() {
353 return g_func_mock_ptr->IntMethod0();
354 }
343 355
344 TEST_F(BindTest, BasicTest) { 356 TEST_F(BindTest, BasicTest) {
345 Callback<int(int, int, int)> cb = Bind(&Sum, 32, 16, 8); 357 Callback<int(int, int, int)> cb = Bind(&Sum, 32, 16, 8);
346 EXPECT_EQ(92, cb.Run(13, 12, 11)); 358 EXPECT_EQ(92, cb.Run(13, 12, 11));
347 359
348 Callback<int(int, int, int, int, int, int)> c1 = Bind(&Sum); 360 Callback<int(int, int, int, int, int, int)> c1 = Bind(&Sum);
349 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9)); 361 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
350 362
351 Callback<int(int, int, int)> c2 = Bind(c1, 32, 16, 8); 363 Callback<int(int, int, int)> c2 = Bind(c1, 32, 16, 8);
352 EXPECT_EQ(86, c2.Run(11, 10, 9)); 364 EXPECT_EQ(86, c2.Run(11, 10, 9));
353 365
354 Callback<int()> c3 = Bind(c2, 4, 2, 1); 366 Callback<int()> c3 = Bind(c2, 4, 2, 1);
355 EXPECT_EQ(63, c3.Run()); 367 EXPECT_EQ(63, c3.Run());
356 } 368 }
357 369
358 // Test that currying the rvalue result of another Bind() works correctly. 370 // Test that currying the rvalue result of another Bind() works correctly.
359 // - rvalue should be usable as argument to Bind(). 371 // - rvalue should be usable as argument to Bind().
360 // - multiple runs of resulting Callback remain valid. 372 // - multiple runs of resulting Callback remain valid.
361 TEST_F(BindTest, CurryingRvalueResultOfBind) { 373 TEST_F(BindTest, CurryingRvalueResultOfBind) {
362 int n = 0; 374 int n = 0;
363 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n)); 375 RepeatingClosure cb = BindRepeating(&TakesACallback,
376 BindRepeating(&PtrArgSet, &n));
364 377
365 // If we implement Bind() such that the return value has auto_ptr-like 378 // If we implement Bind() such that the return value has auto_ptr-like
366 // semantics, the second call here will fail because ownership of 379 // semantics, the second call here will fail because ownership of
367 // the internal BindState<> would have been transfered to a *temporary* 380 // the internal BindState<> would have been transfered to a *temporary*
368 // constructon of a Callback object on the first call. 381 // constructon of a Callback object on the first call.
369 cb.Run(); 382 cb.Run();
370 EXPECT_EQ(2, n); 383 EXPECT_EQ(2, n);
371 384
372 n = 0; 385 n = 0;
373 cb.Run(); 386 cb.Run();
374 EXPECT_EQ(2, n); 387 EXPECT_EQ(2, n);
375 } 388 }
376 389
377 // Function type support. 390 TEST_F(BindTest, RepeatingCallbackBasicTest) {
378 // - Normal function. 391 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
379 // - Normal function bound with non-refcounted first argument.
380 // - Method bound to non-const object.
381 // - Method bound to scoped_refptr.
382 // - Const method bound to non-const object.
383 // - Const method bound to const object.
384 // - Derived classes can be used with pointers to non-virtual base functions.
385 // - Derived classes can be used with pointers to virtual base functions (and
386 // preserve virtual dispatch).
387 TEST_F(BindTest, FunctionTypeSupport) {
388 EXPECT_CALL(static_func_mock_, VoidMethod0());
389 EXPECT_CALL(has_ref_, AddRef()).Times(4);
390 EXPECT_CALL(has_ref_, Release()).Times(4);
391 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2);
392 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2);
393 392
394 Closure normal_cb = Bind(&VoidFunc0); 393 // RepeatingCallback can run via a lvalue-reference.
395 Callback<NoRef*()> normal_non_refcounted_cb = 394 EXPECT_EQ(63, c0.Run(32));
396 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_);
397 normal_cb.Run();
398 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run());
399 395
400 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); 396 // It is valid to call a RepeatingCallback more than once.
401 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0, 397 EXPECT_EQ(54, c0.Run(23));
402 make_scoped_refptr(&has_ref_));
403 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0,
404 &has_ref_);
405 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0,
406 const_has_ref_ptr_);
407 method_cb.Run();
408 method_refptr_cb.Run();
409 const_method_nonconst_obj_cb.Run();
410 const_method_const_obj_cb.Run();
411 398
412 Child child; 399 // BindRepeating can handle a RepeatingCallback as the target functor.
413 child.value = 0; 400 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
414 Closure virtual_set_cb = Bind(&Parent::VirtualSet, &child);
415 virtual_set_cb.Run();
416 EXPECT_EQ(kChildValue, child.value);
417 401
418 child.value = 0; 402 // RepeatingCallback can run via a rvalue-referenc.
419 Closure non_virtual_set_cb = Bind(&Parent::NonVirtualSet, &child); 403 EXPECT_EQ(42, std::move(c1).Run());
420 non_virtual_set_cb.Run(); 404
421 EXPECT_EQ(kParentValue, child.value); 405 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
406 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
422 } 407 }
423 408
424 // Return value support. 409 TEST_F(BindTest, OnceCallbackBasicTest) {
425 // - Function with return value. 410 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
426 // - Method with return value.
427 // - Const method with return value.
428 TEST_F(BindTest, ReturnValues) {
429 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
430 EXPECT_CALL(has_ref_, AddRef()).Times(3);
431 EXPECT_CALL(has_ref_, Release()).Times(3);
432 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337));
433 EXPECT_CALL(has_ref_, IntConstMethod0())
434 .WillOnce(Return(41337))
435 .WillOnce(Return(51337));
436 411
437 Callback<int()> normal_cb = Bind(&IntFunc0); 412 // OnceCallback can run via a rvalue-reference.
438 Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_); 413 EXPECT_EQ(63, std::move(c0).Run(32));
439 Callback<int()> const_method_nonconst_obj_cb = 414
440 Bind(&HasRef::IntConstMethod0, &has_ref_); 415 // After running via the rvalue-reference, the value of the OnceCallback
441 Callback<int()> const_method_const_obj_cb = 416 // is undefined. The implementation simply clears the instance after the
442 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_); 417 // invocation.
443 EXPECT_EQ(1337, normal_cb.Run()); 418 EXPECT_TRUE(c0.is_null());
444 EXPECT_EQ(31337, method_cb.Run()); 419
445 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run()); 420 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
446 EXPECT_EQ(51337, const_method_const_obj_cb.Run()); 421
422 // BindOnce can handle a rvalue-reference of OnceCallback as the target
423 // functor.
424 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
425 EXPECT_EQ(41, std::move(c1).Run());
426
427 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
428 EXPECT_EQ(41, BindOnce(c2, 13).Run());
447 } 429 }
448 430
449 // IgnoreResult adapter test. 431 // IgnoreResult adapter test.
450 // - Function with return value. 432 // - Function with return value.
451 // - Method with return value. 433 // - Method with return value.
452 // - Const Method with return. 434 // - Const Method with return.
453 // - Method with return value bound to WeakPtr<>. 435 // - Method with return value bound to WeakPtr<>.
454 // - Const Method with return bound to WeakPtr<>. 436 // - Const Method with return bound to WeakPtr<>.
455 TEST_F(BindTest, IgnoreResult) { 437 TEST_F(BindTest, IgnoreResultForRepeating) {
456 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337)); 438 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
457 EXPECT_CALL(has_ref_, AddRef()).Times(2); 439 EXPECT_CALL(has_ref_, AddRef()).Times(2);
458 EXPECT_CALL(has_ref_, Release()).Times(2); 440 EXPECT_CALL(has_ref_, Release()).Times(2);
459 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10)); 441 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
460 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11)); 442 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
461 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12)); 443 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
462 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13)); 444 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
463 445
464 Closure normal_func_cb = Bind(IgnoreResult(&IntFunc0)); 446 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
465 normal_func_cb.Run(); 447 normal_func_cb.Run();
466 448
467 Closure non_void_method_cb = 449 RepeatingClosure non_void_method_cb =
468 Bind(IgnoreResult(&HasRef::IntMethod0), &has_ref_); 450 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
469 non_void_method_cb.Run(); 451 non_void_method_cb.Run();
470 452
471 Closure non_void_const_method_cb = 453 RepeatingClosure non_void_const_method_cb =
472 Bind(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_); 454 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
473 non_void_const_method_cb.Run(); 455 non_void_const_method_cb.Run();
474 456
475 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 457 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
476 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 458 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
477 459
478 Closure non_void_weak_method_cb = 460 RepeatingClosure non_void_weak_method_cb =
479 Bind(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr()); 461 BindRepeating(IgnoreResult(&NoRef::IntMethod0),
462 weak_factory.GetWeakPtr());
480 non_void_weak_method_cb.Run(); 463 non_void_weak_method_cb.Run();
481 464
482 Closure non_void_weak_const_method_cb = 465 RepeatingClosure non_void_weak_const_method_cb =
483 Bind(IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr()); 466 BindRepeating(IgnoreResult(&NoRef::IntConstMethod0),
467 weak_factory.GetWeakPtr());
484 non_void_weak_const_method_cb.Run(); 468 non_void_weak_const_method_cb.Run();
485 469
486 weak_factory.InvalidateWeakPtrs(); 470 weak_factory.InvalidateWeakPtrs();
487 non_void_weak_const_method_cb.Run(); 471 non_void_weak_const_method_cb.Run();
488 non_void_weak_method_cb.Run(); 472 non_void_weak_method_cb.Run();
489 } 473 }
490 474
491 // Argument binding tests. 475 TEST_F(BindTest, IgnoreResultForOnce) {
492 // - Argument binding to primitive. 476 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
493 // - Argument binding to primitive pointer. 477 EXPECT_CALL(has_ref_, AddRef()).Times(2);
494 // - Argument binding to a literal integer. 478 EXPECT_CALL(has_ref_, Release()).Times(2);
495 // - Argument binding to a literal string. 479 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
496 // - Argument binding with template function. 480 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
497 // - Argument binding to an object.
498 // - Argument binding to pointer to incomplete type.
499 // - Argument gets type converted.
500 // - Pointer argument gets converted.
501 // - Const Reference forces conversion.
502 TEST_F(BindTest, ArgumentBinding) {
503 int n = 2;
504 481
505 Callback<int()> bind_primitive_cb = Bind(&Identity, n); 482 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
506 EXPECT_EQ(n, bind_primitive_cb.Run()); 483 std::move(normal_func_cb).Run();
507 484
508 Callback<int*()> bind_primitive_pointer_cb = 485 OnceClosure non_void_method_cb =
509 Bind(&PolymorphicIdentity<int*>, &n); 486 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
510 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run()); 487 std::move(non_void_method_cb).Run();
511 488
512 Callback<int()> bind_int_literal_cb = Bind(&Identity, 3); 489 OnceClosure non_void_const_method_cb =
513 EXPECT_EQ(3, bind_int_literal_cb.Run()); 490 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
491 std::move(non_void_const_method_cb).Run();
514 492
515 Callback<const char*()> bind_string_literal_cb = 493 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
516 Bind(&CStringIdentity, "hi"); 494 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
517 EXPECT_STREQ("hi", bind_string_literal_cb.Run());
518 495
519 Callback<int()> bind_template_function_cb = 496 OnceClosure non_void_weak_method_cb =
520 Bind(&PolymorphicIdentity<int>, 4); 497 BindOnce(IgnoreResult(&NoRef::IntMethod0),
521 EXPECT_EQ(4, bind_template_function_cb.Run()); 498 weak_factory.GetWeakPtr());
499 OnceClosure non_void_weak_const_method_cb =
500 BindOnce(IgnoreResult(&NoRef::IntConstMethod0),
501 weak_factory.GetWeakPtr());
522 502
523 NoRefParent p; 503 weak_factory.InvalidateWeakPtrs();
524 p.value = 5; 504 std::move(non_void_weak_const_method_cb).Run();
525 Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p); 505 std::move(non_void_weak_method_cb).Run();
526 EXPECT_EQ(5, bind_object_cb.Run());
527
528 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
529 Callback<IncompleteType*()> bind_incomplete_ptr_cb =
530 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr);
531 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run());
532
533 NoRefChild c;
534 c.value = 6;
535 Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c);
536 EXPECT_EQ(6, bind_promotes_cb.Run());
537
538 c.value = 7;
539 Callback<int()> bind_pointer_promotes_cb =
540 Bind(&UnwrapNoRefParentPtr, &c);
541 EXPECT_EQ(7, bind_pointer_promotes_cb.Run());
542
543 c.value = 8;
544 Callback<int()> bind_const_reference_promotes_cb =
545 Bind(&UnwrapNoRefParentConstRef, c);
546 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run());
547 }
548
549 // Unbound argument type support tests.
550 // - Unbound value.
551 // - Unbound pointer.
552 // - Unbound reference.
553 // - Unbound const reference.
554 // - Unbound unsized array.
555 // - Unbound sized array.
556 // - Unbound array-of-arrays.
557 TEST_F(BindTest, UnboundArgumentTypeSupport) {
558 Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic<int>::Run);
559 Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic<int*>::Run);
560 Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic<int&>::Run);
561 Callback<void(const int&)> unbound_const_ref_cb =
562 Bind(&VoidPolymorphic<const int&>::Run);
563 Callback<void(int[])> unbound_unsized_array_cb =
564 Bind(&VoidPolymorphic<int[]>::Run);
565 Callback<void(int[2])> unbound_sized_array_cb =
566 Bind(&VoidPolymorphic<int[2]>::Run);
567 Callback<void(int[][2])> unbound_array_of_arrays_cb =
568 Bind(&VoidPolymorphic<int[][2]>::Run);
569
570 Callback<void(int&)> unbound_ref_with_bound_arg =
571 Bind(&VoidPolymorphic<int, int&>::Run, 1);
572 }
573
574 // Function with unbound reference parameter.
575 // - Original parameter is modified by callback.
576 TEST_F(BindTest, UnboundReferenceSupport) {
577 int n = 0;
578 Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet);
579 unbound_ref_cb.Run(n);
580 EXPECT_EQ(2, n);
581 } 506 }
582 507
583 // Functions that take reference parameters. 508 // Functions that take reference parameters.
584 // - Forced reference parameter type still stores a copy. 509 // - Forced reference parameter type still stores a copy.
585 // - Forced const reference parameter type still stores a copy. 510 // - Forced const reference parameter type still stores a copy.
586 TEST_F(BindTest, ReferenceArgumentBinding) { 511 TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
587 int n = 1; 512 int n = 1;
588 int& ref_n = n; 513 int& ref_n = n;
589 const int& const_ref_n = n; 514 const int& const_ref_n = n;
590 515
591 Callback<int()> ref_copies_cb = Bind(&Identity, ref_n); 516 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
592 EXPECT_EQ(n, ref_copies_cb.Run()); 517 EXPECT_EQ(n, ref_copies_cb.Run());
593 n++; 518 n++;
594 EXPECT_EQ(n - 1, ref_copies_cb.Run()); 519 EXPECT_EQ(n - 1, ref_copies_cb.Run());
595 520
596 Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n); 521 RepeatingCallback<int()> const_ref_copies_cb =
522 BindRepeating(&Identity, const_ref_n);
597 EXPECT_EQ(n, const_ref_copies_cb.Run()); 523 EXPECT_EQ(n, const_ref_copies_cb.Run());
598 n++; 524 n++;
599 EXPECT_EQ(n - 1, const_ref_copies_cb.Run()); 525 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
600 } 526 }
601 527
528 TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
529 int n = 1;
530 int& ref_n = n;
531 const int& const_ref_n = n;
532
533 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
534 n++;
535 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
536
537 OnceCallback<int()> const_ref_copies_cb =
538 BindOnce(&Identity, const_ref_n);
539 n++;
540 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
541 }
542
602 // Check that we can pass in arrays and have them be stored as a pointer. 543 // Check that we can pass in arrays and have them be stored as a pointer.
603 // - Array of values stores a pointer. 544 // - Array of values stores a pointer.
604 // - Array of const values stores a pointer. 545 // - Array of const values stores a pointer.
605 TEST_F(BindTest, ArrayArgumentBinding) { 546 TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
606 int array[4] = {1, 1, 1, 1}; 547 int array[4] = {1, 1, 1, 1};
607 const int (*const_array_ptr)[4] = &array; 548 const int (*const_array_ptr)[4] = &array;
608 549
609 Callback<int()> array_cb = Bind(&ArrayGet, array, 1); 550 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
610 EXPECT_EQ(1, array_cb.Run()); 551 EXPECT_EQ(1, array_cb.Run());
611 552
612 Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1); 553 RepeatingCallback<int()> const_array_cb =
554 BindRepeating(&ArrayGet, *const_array_ptr, 1);
613 EXPECT_EQ(1, const_array_cb.Run()); 555 EXPECT_EQ(1, const_array_cb.Run());
614 556
615 array[1] = 3; 557 array[1] = 3;
616 EXPECT_EQ(3, array_cb.Run()); 558 EXPECT_EQ(3, array_cb.Run());
617 EXPECT_EQ(3, const_array_cb.Run()); 559 EXPECT_EQ(3, const_array_cb.Run());
618 } 560 }
619 561
620 // Unretained() wrapper support. 562 TEST_F(BindTest, ArrayArgumentBindingForOnce) {
621 // - Method bound to Unretained() non-const object. 563 int array[4] = {1, 1, 1, 1};
622 // - Const method bound to Unretained() non-const object. 564 const int (*const_array_ptr)[4] = &array;
623 // - Const method bound to Unretained() const object.
624 TEST_F(BindTest, Unretained) {
625 EXPECT_CALL(no_ref_, VoidMethod0());
626 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
627 565
628 Callback<void()> method_cb = 566 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
629 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_)); 567 OnceCallback<int()> const_array_cb =
630 method_cb.Run(); 568 BindOnce(&ArrayGet, *const_array_ptr, 1);
631 569
632 Callback<void()> const_method_cb = 570 array[1] = 3;
633 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_)); 571 EXPECT_EQ(3, std::move(array_cb).Run());
634 const_method_cb.Run(); 572 EXPECT_EQ(3, std::move(const_array_cb).Run());
635
636 Callback<void()> const_method_const_ptr_cb =
637 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_));
638 const_method_const_ptr_cb.Run();
639 } 573 }
640 574
641 // WeakPtr() support. 575 // WeakPtr() support.
642 // - Method bound to WeakPtr<> to non-const object. 576 // - Method bound to WeakPtr<> to non-const object.
643 // - Const method bound to WeakPtr<> to non-const object. 577 // - Const method bound to WeakPtr<> to non-const object.
644 // - Const method bound to WeakPtr<> to const object. 578 // - Const method bound to WeakPtr<> to const object.
645 // - Normal Function with WeakPtr<> as P1 can have return type and is 579 // - Normal Function with WeakPtr<> as P1 can have return type and is
646 // not canceled. 580 // not canceled.
647 TEST_F(BindTest, WeakPtr) { 581 TEST_F(BindTest, WeakPtrForRepeating) {
648 EXPECT_CALL(no_ref_, VoidMethod0()); 582 EXPECT_CALL(no_ref_, VoidMethod0());
649 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2); 583 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
650 584
651 WeakPtrFactory<NoRef> weak_factory(&no_ref_); 585 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
652 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_); 586 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
653 587
654 Closure method_cb = 588 RepeatingClosure method_cb =
655 Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr()); 589 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
656 method_cb.Run(); 590 method_cb.Run();
657 591
658 Closure const_method_cb = 592 RepeatingClosure const_method_cb =
659 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 593 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
660 const_method_cb.Run(); 594 const_method_cb.Run();
661 595
662 Closure const_method_const_ptr_cb = 596 RepeatingClosure const_method_const_ptr_cb =
663 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr()); 597 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
664 const_method_const_ptr_cb.Run(); 598 const_method_const_ptr_cb.Run();
665 599
666 Callback<int(int)> normal_func_cb = 600 RepeatingCallback<int(int)> normal_func_cb =
667 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr()); 601 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
668 EXPECT_EQ(1, normal_func_cb.Run(1)); 602 EXPECT_EQ(1, normal_func_cb.Run(1));
669 603
670 weak_factory.InvalidateWeakPtrs(); 604 weak_factory.InvalidateWeakPtrs();
671 const_weak_factory.InvalidateWeakPtrs(); 605 const_weak_factory.InvalidateWeakPtrs();
672 606
673 method_cb.Run(); 607 method_cb.Run();
674 const_method_cb.Run(); 608 const_method_cb.Run();
675 const_method_const_ptr_cb.Run(); 609 const_method_const_ptr_cb.Run();
676 610
677 // Still runs even after the pointers are invalidated. 611 // Still runs even after the pointers are invalidated.
678 EXPECT_EQ(2, normal_func_cb.Run(2)); 612 EXPECT_EQ(2, normal_func_cb.Run(2));
679 } 613 }
680 614
615 TEST_F(BindTest, WeakPtrForOnce) {
616 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
617 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
618
619 OnceClosure method_cb =
620 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
621 OnceClosure const_method_cb =
622 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
623 OnceClosure const_method_const_ptr_cb =
624 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
625 Callback<int(int)> normal_func_cb =
626 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
627
628 weak_factory.InvalidateWeakPtrs();
629 const_weak_factory.InvalidateWeakPtrs();
630
631 std::move(method_cb).Run();
632 std::move(const_method_cb).Run();
633 std::move(const_method_const_ptr_cb).Run();
634
635 // Still runs even after the pointers are invalidated.
636 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
637 }
638
681 // ConstRef() wrapper support. 639 // ConstRef() wrapper support.
682 // - Binding w/o ConstRef takes a copy. 640 // - Binding w/o ConstRef takes a copy.
683 // - Binding a ConstRef takes a reference. 641 // - Binding a ConstRef takes a reference.
684 // - Binding ConstRef to a function ConstRef does not copy on invoke. 642 // - Binding ConstRef to a function ConstRef does not copy on invoke.
685 TEST_F(BindTest, ConstRef) { 643 TEST_F(BindTest, ConstRefForRepeating) {
686 int n = 1; 644 int n = 1;
687 645
688 Callback<int()> copy_cb = Bind(&Identity, n); 646 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
689 Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n)); 647 RepeatingCallback<int()> const_ref_cb = BindRepeating(&Identity, ConstRef(n));
690 EXPECT_EQ(n, copy_cb.Run()); 648 EXPECT_EQ(n, copy_cb.Run());
691 EXPECT_EQ(n, const_ref_cb.Run()); 649 EXPECT_EQ(n, const_ref_cb.Run());
692 n++; 650 n++;
693 EXPECT_EQ(n - 1, copy_cb.Run()); 651 EXPECT_EQ(n - 1, copy_cb.Run());
694 EXPECT_EQ(n, const_ref_cb.Run()); 652 EXPECT_EQ(n, const_ref_cb.Run());
695 653
696 int copies = 0; 654 int copies = 0;
697 int assigns = 0; 655 int assigns = 0;
698 int move_constructs = 0; 656 int move_constructs = 0;
699 int move_assigns = 0; 657 int move_assigns = 0;
700 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns); 658 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
701 Callback<int()> all_const_ref_cb = 659 RepeatingCallback<int()> all_const_ref_cb =
702 Bind(&GetCopies, ConstRef(counter)); 660 BindRepeating(&GetCopies, ConstRef(counter));
703 EXPECT_EQ(0, all_const_ref_cb.Run()); 661 EXPECT_EQ(0, all_const_ref_cb.Run());
704 EXPECT_EQ(0, copies); 662 EXPECT_EQ(0, copies);
705 EXPECT_EQ(0, assigns); 663 EXPECT_EQ(0, assigns);
706 EXPECT_EQ(0, move_constructs); 664 EXPECT_EQ(0, move_constructs);
707 EXPECT_EQ(0, move_assigns); 665 EXPECT_EQ(0, move_assigns);
708 } 666 }
709 667
710 TEST_F(BindTest, ScopedRefptr) { 668 TEST_F(BindTest, ConstRefForOnce) {
711 EXPECT_CALL(has_ref_, AddRef()).Times(1); 669 int n = 1;
712 EXPECT_CALL(has_ref_, Release()).Times(1);
713 670
714 const scoped_refptr<HasRef> refptr(&has_ref_); 671 OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
715 Callback<int()> scoped_refptr_const_ref_cb = 672 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, ConstRef(n));
716 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1); 673 n++;
717 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run()); 674 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
675 EXPECT_EQ(n, std::move(const_ref_cb).Run());
676
677 int copies = 0;
678 int assigns = 0;
679 int move_constructs = 0;
680 int move_assigns = 0;
681 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
682 OnceCallback<int()> all_const_ref_cb =
683 BindOnce(&GetCopies, ConstRef(counter));
684 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
685 EXPECT_EQ(0, copies);
686 EXPECT_EQ(0, assigns);
687 EXPECT_EQ(0, move_constructs);
688 EXPECT_EQ(0, move_assigns);
718 } 689 }
719 690
720 // Test Owned() support. 691 // Test Owned() support.
721 TEST_F(BindTest, Owned) { 692 TEST_F(BindTest, OwnedForRepeating) {
722 int deletes = 0; 693 int deletes = 0;
723 DeleteCounter* counter = new DeleteCounter(&deletes); 694 DeleteCounter* counter = new DeleteCounter(&deletes);
724 695
725 // If we don't capture, delete happens on Callback destruction/reset. 696 // If we don't capture, delete happens on Callback destruction/reset.
726 // return the same value. 697 // return the same value.
727 Callback<DeleteCounter*()> no_capture_cb = 698 RepeatingCallback<DeleteCounter*()> no_capture_cb =
728 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter)); 699 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
729 ASSERT_EQ(counter, no_capture_cb.Run()); 700 ASSERT_EQ(counter, no_capture_cb.Run());
730 ASSERT_EQ(counter, no_capture_cb.Run()); 701 ASSERT_EQ(counter, no_capture_cb.Run());
731 EXPECT_EQ(0, deletes); 702 EXPECT_EQ(0, deletes);
732 no_capture_cb.Reset(); // This should trigger a delete. 703 no_capture_cb.Reset(); // This should trigger a delete.
733 EXPECT_EQ(1, deletes); 704 EXPECT_EQ(1, deletes);
734 705
735 deletes = 0; 706 deletes = 0;
736 counter = new DeleteCounter(&deletes); 707 counter = new DeleteCounter(&deletes);
737 base::Closure own_object_cb = 708 RepeatingClosure own_object_cb =
738 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); 709 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
739 own_object_cb.Run(); 710 own_object_cb.Run();
740 EXPECT_EQ(0, deletes); 711 EXPECT_EQ(0, deletes);
741 own_object_cb.Reset(); 712 own_object_cb.Reset();
742 EXPECT_EQ(1, deletes); 713 EXPECT_EQ(1, deletes);
743 } 714 }
744 715
745 TEST_F(BindTest, UniquePtrReceiver) { 716 TEST_F(BindTest, OwnedForOnce) {
717 int deletes = 0;
718 DeleteCounter* counter = new DeleteCounter(&deletes);
719
720 // If we don't capture, delete happens on Callback destruction/reset.
721 // return the same value.
722 OnceCallback<DeleteCounter*()> no_capture_cb =
723 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
724 EXPECT_EQ(0, deletes);
725 no_capture_cb.Reset(); // This should trigger a delete.
726 EXPECT_EQ(1, deletes);
727
728 deletes = 0;
729 counter = new DeleteCounter(&deletes);
730 OnceClosure own_object_cb =
731 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
732 EXPECT_EQ(0, deletes);
733 own_object_cb.Reset();
734 EXPECT_EQ(1, deletes);
735 }
736
737 template <typename T>
738 class BindVariantsTest : public ::testing::Test {
739 };
740
741 struct RepeatingTestConfig {
742 template <typename Signature>
743 using CallbackType = RepeatingCallback<Signature>;
744 using ClosureType = RepeatingClosure;
745
746 template <typename F, typename... Args>
747 static CallbackType<MakeUnboundRunType<F, Args...>>
748 Bind(F&& f, Args&&... args) {
749 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
750 }
751 };
752
753 struct OnceTestConfig {
754 template <typename Signature>
755 using CallbackType = OnceCallback<Signature>;
756 using ClosureType = OnceClosure;
757
758 template <typename F, typename... Args>
759 static CallbackType<MakeUnboundRunType<F, Args...>>
760 Bind(F&& f, Args&&... args) {
761 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
762 }
763 };
764
765 using BindVariantsTestConfig = ::testing::Types<
766 RepeatingTestConfig, OnceTestConfig>;
767 TYPED_TEST_CASE(BindVariantsTest, BindVariantsTestConfig);
768
769 template <typename TypeParam, typename Signature>
770 using CallbackType = typename TypeParam::template CallbackType<Signature>;
771
772 // Function type support.
773 // - Normal function.
774 // - Normal function bound with non-refcounted first argument.
775 // - Method bound to non-const object.
776 // - Method bound to scoped_refptr.
777 // - Const method bound to non-const object.
778 // - Const method bound to const object.
779 // - Derived classes can be used with pointers to non-virtual base functions.
780 // - Derived classes can be used with pointers to virtual base functions (and
781 // preserve virtual dispatch).
782 TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
783 using ClosureType = typename TypeParam::ClosureType;
784
785 StrictMock<HasRef> has_ref;
786 StrictMock<NoRef> no_ref;
787 StrictMock<NoRef> static_func_mock;
788 const HasRef* const_has_ref_ptr = &has_ref;
789 g_func_mock_ptr = &static_func_mock;
790
791 EXPECT_CALL(static_func_mock, VoidMethod0());
792 EXPECT_CALL(has_ref, AddRef()).Times(4);
793 EXPECT_CALL(has_ref, Release()).Times(4);
794 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
795 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
796
797 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
798 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
799 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
800 std::move(normal_cb).Run();
801 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
802
803 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
804 ClosureType method_refptr_cb = TypeParam::Bind(&HasRef::VoidMethod0,
805 make_scoped_refptr(&has_ref));
806 ClosureType const_method_nonconst_obj_cb =
807 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
808 ClosureType const_method_const_obj_cb =
809 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
810 std::move(method_cb).Run();
811 std::move(method_refptr_cb).Run();
812 std::move(const_method_nonconst_obj_cb).Run();
813 std::move(const_method_const_obj_cb).Run();
814
815 Child child;
816 child.value = 0;
817 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
818 std::move(virtual_set_cb).Run();
819 EXPECT_EQ(kChildValue, child.value);
820
821 child.value = 0;
822 ClosureType non_virtual_set_cb =
823 TypeParam::Bind(&Parent::NonVirtualSet, &child);
824 std::move(non_virtual_set_cb).Run();
825 EXPECT_EQ(kParentValue, child.value);
826 }
827
828 // Return value support.
829 // - Function with return value.
830 // - Method with return value.
831 // - Const method with return value.
832 // - Move-only return value.
833 TYPED_TEST(BindVariantsTest, ReturnValues) {
834 StrictMock<NoRef> static_func_mock;
835 StrictMock<HasRef> has_ref;
836 g_func_mock_ptr = &static_func_mock;
837 const HasRef* const_has_ref_ptr = &has_ref;
838
839 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
840 EXPECT_CALL(has_ref, AddRef()).Times(4);
841 EXPECT_CALL(has_ref, Release()).Times(4);
842 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
843 EXPECT_CALL(has_ref, IntConstMethod0())
844 .WillOnce(Return(41337))
845 .WillOnce(Return(51337));
846 EXPECT_CALL(has_ref, UniquePtrMethod0())
847 .WillOnce(Return(ByMove(MakeUnique<int>(42))));
848
849 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
850 CallbackType<TypeParam, int()> method_cb =
851 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
852 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
853 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
854 CallbackType<TypeParam, int()> const_method_const_obj_cb =
855 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
856 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
857 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
858 EXPECT_EQ(1337, std::move(normal_cb).Run());
859 EXPECT_EQ(31337, std::move(method_cb).Run());
860 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
861 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
862 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
863 }
864
865 // Argument binding tests.
866 // - Argument binding to primitive.
867 // - Argument binding to primitive pointer.
868 // - Argument binding to a literal integer.
869 // - Argument binding to a literal string.
870 // - Argument binding with template function.
871 // - Argument binding to an object.
872 // - Argument binding to pointer to incomplete type.
873 // - Argument gets type converted.
874 // - Pointer argument gets converted.
875 // - Const Reference forces conversion.
876 TYPED_TEST(BindVariantsTest, ArgumentBinding) {
877 int n = 2;
878
879 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
880 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
881 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
882 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
883 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
884
885 NoRefParent p;
886 p.value = 5;
887 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
888
889 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
890 EXPECT_EQ(incomplete_ptr,
891 TypeParam::Bind(&PolymorphicIdentity<IncompleteType*>,
892 incomplete_ptr).Run());
893
894 NoRefChild c;
895 c.value = 6;
896 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
897
898 c.value = 7;
899 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
900
901 c.value = 8;
902 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
903 }
904
905 // Unbound argument type support tests.
906 // - Unbound value.
907 // - Unbound pointer.
908 // - Unbound reference.
909 // - Unbound const reference.
910 // - Unbound unsized array.
911 // - Unbound sized array.
912 // - Unbound array-of-arrays.
913 TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
914 CallbackType<TypeParam, void(int)> unbound_value_cb =
915 TypeParam::Bind(&VoidPolymorphic<int>::Run);
916 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
917 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
918 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
919 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
920 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
921 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
922 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
923 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
924 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
925 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
926 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
927 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
928 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
929 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
930 }
931
932 // Function with unbound reference parameter.
933 // - Original parameter is modified by callback.
934 TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
935 int n = 0;
936 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
937 TypeParam::Bind(&RefArgSet);
938 std::move(unbound_ref_cb).Run(n);
939 EXPECT_EQ(2, n);
940 }
941
942 // Unretained() wrapper support.
943 // - Method bound to Unretained() non-const object.
944 // - Const method bound to Unretained() non-const object.
945 // - Const method bound to Unretained() const object.
946 TYPED_TEST(BindVariantsTest, Unretained) {
947 StrictMock<NoRef> no_ref;
948 const NoRef* const_no_ref_ptr = &no_ref;
949
950 EXPECT_CALL(no_ref, VoidMethod0());
951 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
952
953 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
954 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
955 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
956 }
957
958 TYPED_TEST(BindVariantsTest, ScopedRefptr) {
959 StrictMock<HasRef> has_ref;
960 EXPECT_CALL(has_ref, AddRef()).Times(1);
961 EXPECT_CALL(has_ref, Release()).Times(1);
962
963 const scoped_refptr<HasRef> refptr(&has_ref);
964 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb =
965 TypeParam::Bind(&FunctionWithScopedRefptrFirstParam,
966 base::ConstRef(refptr), 1);
967 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
968 }
969
970 TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
746 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>); 971 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
747 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1); 972 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
748 Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run(); 973 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
749 } 974 }
750 975
751 // Tests for Passed() wrapper support: 976 // Tests for Passed() wrapper support:
752 // - Passed() can be constructed from a pointer to scoper. 977 // - Passed() can be constructed from a pointer to scoper.
753 // - Passed() can be constructed from a scoper rvalue. 978 // - Passed() can be constructed from a scoper rvalue.
754 // - Using Passed() gives Callback Ownership. 979 // - Using Passed() gives Callback Ownership.
755 // - Ownership is transferred from Callback to callee on the first Run(). 980 // - Ownership is transferred from Callback to callee on the first Run().
756 // - Callback supports unbound arguments. 981 // - Callback supports unbound arguments.
757 template <typename T> 982 template <typename T>
758 class BindMoveOnlyTypeTest : public ::testing::Test { 983 class BindMoveOnlyTypeTest : public ::testing::Test {
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 1252
1028 int x = 1; 1253 int x = 1;
1029 base::Callback<void(int)> cb = 1254 base::Callback<void(int)> cb =
1030 Bind([](int* x, int i) { *x *= i; }, Unretained(&x)); 1255 Bind([](int* x, int i) { *x *= i; }, Unretained(&x));
1031 cb.Run(6); 1256 cb.Run(6);
1032 EXPECT_EQ(6, x); 1257 EXPECT_EQ(6, x);
1033 cb.Run(7); 1258 cb.Run(7);
1034 EXPECT_EQ(42, x); 1259 EXPECT_EQ(42, x);
1035 } 1260 }
1036 1261
1037 TEST_F(BindTest, Cancellation) {
1038 EXPECT_CALL(no_ref_, VoidMethod0()).Times(2);
1039
1040 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
1041 Closure cb = Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
1042 Closure cb2 = Bind(cb);
1043
1044 EXPECT_FALSE(cb.IsCancelled());
1045 EXPECT_FALSE(cb2.IsCancelled());
1046
1047 cb.Run();
1048 cb2.Run();
1049
1050 weak_factory.InvalidateWeakPtrs();
1051
1052 EXPECT_TRUE(cb.IsCancelled());
1053 EXPECT_TRUE(cb2.IsCancelled());
1054
1055 cb.Run();
1056 cb2.Run();
1057 }
1058
1059 TEST_F(BindTest, OnceCallback) { 1262 TEST_F(BindTest, OnceCallback) {
1060 using internal::OnceClosure;
1061 using internal::RepeatingClosure;
1062 using internal::BindOnce;
1063 using internal::BindRepeating;
1064 using internal::OnceCallback;
1065
1066 // Check if Callback variants have declarations of conversions as expected. 1263 // Check if Callback variants have declarations of conversions as expected.
1067 // Copy constructor and assignment of RepeatingCallback. 1264 // Copy constructor and assignment of RepeatingCallback.
1068 static_assert(std::is_constructible< 1265 static_assert(std::is_constructible<
1069 RepeatingClosure, const RepeatingClosure&>::value, 1266 RepeatingClosure, const RepeatingClosure&>::value,
1070 "RepeatingClosure should be copyable."); 1267 "RepeatingClosure should be copyable.");
1071 static_assert(is_assignable< 1268 static_assert(is_assignable<
1072 RepeatingClosure, const RepeatingClosure&>::value, 1269 RepeatingClosure, const RepeatingClosure&>::value,
1073 "RepeatingClosure should be copy-assignable."); 1270 "RepeatingClosure should be copy-assignable.");
1074 1271
1075 // Move constructor and assignment of RepeatingCallback. 1272 // Move constructor and assignment of RepeatingCallback.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 cb = cb3; 1336 cb = cb3;
1140 std::move(cb).Run(); 1337 std::move(cb).Run();
1141 1338
1142 cb = std::move(cb2); 1339 cb = std::move(cb2);
1143 1340
1144 OnceCallback<void(int)> cb4 = BindOnce( 1341 OnceCallback<void(int)> cb4 = BindOnce(
1145 &VoidPolymorphic<std::unique_ptr<int>, int>::Run, MakeUnique<int>(0)); 1342 &VoidPolymorphic<std::unique_ptr<int>, int>::Run, MakeUnique<int>(0));
1146 BindOnce(std::move(cb4), 1).Run(); 1343 BindOnce(std::move(cb4), 1).Run();
1147 } 1344 }
1148 1345
1346 TEST_F(BindTest, Cancellation) {
1347 EXPECT_CALL(no_ref_, VoidMethod0()).Times(2);
1348
1349 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
1350 Closure cb = Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
1351 Closure cb2 = Bind(cb);
1352
1353 EXPECT_FALSE(cb.IsCancelled());
1354 EXPECT_FALSE(cb2.IsCancelled());
1355
1356 cb.Run();
1357 cb2.Run();
1358
1359 weak_factory.InvalidateWeakPtrs();
1360
1361 EXPECT_TRUE(cb.IsCancelled());
1362 EXPECT_TRUE(cb2.IsCancelled());
1363
1364 cb.Run();
1365 cb2.Run();
1366 }
1367
1149 // Callback construction and assignment tests. 1368 // Callback construction and assignment tests.
1150 // - Construction from an InvokerStorageHolder should not cause ref/deref. 1369 // - Construction from an InvokerStorageHolder should not cause ref/deref.
1151 // - Assignment from other callback should only cause one ref 1370 // - Assignment from other callback should only cause one ref
1152 // 1371 //
1153 // TODO(ajwong): Is there actually a way to test this? 1372 // TODO(ajwong): Is there actually a way to test this?
1154 1373
1155 #if defined(OS_WIN) 1374 #if defined(OS_WIN)
1156 int __fastcall FastCallFunc(int n) { 1375 int __fastcall FastCallFunc(int n) {
1157 return n; 1376 return n;
1158 } 1377 }
(...skipping 16 matching lines...) Expand all
1175 1394
1176 // Test null callbacks cause a DCHECK. 1395 // Test null callbacks cause a DCHECK.
1177 TEST(BindDeathTest, NullCallback) { 1396 TEST(BindDeathTest, NullCallback) {
1178 base::Callback<void(int)> null_cb; 1397 base::Callback<void(int)> null_cb;
1179 ASSERT_TRUE(null_cb.is_null()); 1398 ASSERT_TRUE(null_cb.is_null());
1180 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42)); 1399 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42));
1181 } 1400 }
1182 1401
1183 } // namespace 1402 } // namespace
1184 } // namespace base 1403 } // namespace base
OLDNEW
« no previous file with comments | « base/bind.h ('k') | base/callback_forward.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698