OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |