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

Side by Side Diff: base/bind_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698