1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/callback.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/weak_ptr.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 using ::testing::Mock
;
15 using ::testing::Return
;
16 using ::testing::StrictMock
;
27 MOCK_METHOD0(VoidMethod0
, void(void));
28 MOCK_CONST_METHOD0(VoidConstMethod0
, void(void));
30 MOCK_METHOD0(IntMethod0
, int(void));
31 MOCK_CONST_METHOD0(IntConstMethod0
, int(void));
34 // Particularly important in this test to ensure no copies are made.
35 DISALLOW_COPY_AND_ASSIGN(NoRef
);
38 class HasRef
: public NoRef
{
42 MOCK_CONST_METHOD0(AddRef
, void(void));
43 MOCK_CONST_METHOD0(Release
, bool(void));
46 // Particularly important in this test to ensure no copies are made.
47 DISALLOW_COPY_AND_ASSIGN(HasRef
);
50 class HasRefPrivateDtor
: public HasRef
{
52 ~HasRefPrivateDtor() {}
55 static const int kParentValue
= 1;
56 static const int kChildValue
= 2;
60 void AddRef(void) const {}
61 void Release(void) const {}
62 virtual void VirtualSet() { value
= kParentValue
; }
63 void NonVirtualSet() { value
= kParentValue
; }
67 class Child
: public Parent
{
69 void VirtualSet() override
{ value
= kChildValue
; }
70 void NonVirtualSet() { value
= kChildValue
; }
75 virtual void VirtualSet() { value
= kParentValue
; }
76 void NonVirtualSet() { value
= kParentValue
; }
80 class NoRefChild
: public NoRefParent
{
81 void VirtualSet() override
{ value
= kChildValue
; }
82 void NonVirtualSet() { value
= kChildValue
; }
85 // Used for probing the number of copies that occur if a type must be coerced
86 // during argument forwarding in the Run() methods.
87 struct DerivedCopyCounter
{
88 DerivedCopyCounter(int* copies
, int* assigns
)
89 : copies_(copies
), assigns_(assigns
) {
95 // Used for probing the number of copies in an argument.
98 CopyCounter(int* copies
, int* assigns
)
99 : copies_(copies
), assigns_(assigns
) {
102 CopyCounter(const CopyCounter
& other
)
103 : copies_(other
.copies_
),
104 assigns_(other
.assigns_
) {
108 // Probing for copies from coercion.
109 explicit CopyCounter(const DerivedCopyCounter
& other
)
110 : copies_(other
.copies_
),
111 assigns_(other
.assigns_
) {
115 const CopyCounter
& operator=(const CopyCounter
& rhs
) {
116 copies_
= rhs
.copies_
;
117 assigns_
= rhs
.assigns_
;
135 class DeleteCounter
{
137 explicit DeleteCounter(int* deletes
)
138 : deletes_(deletes
) {
145 void VoidMethod0() {}
151 template <typename T
>
152 T
PassThru(T scoper
) {
153 return scoper
.Pass();
156 // Some test functions that we can Bind to.
157 template <typename T
>
158 T
PolymorphicIdentity(T t
) {
162 template <typename T
>
163 void VoidPolymorphic1(T t
) {
166 int Identity(int n
) {
170 int ArrayGet(const int array
[], int n
) {
174 int Sum(int a
, int b
, int c
, int d
, int e
, int f
) {
175 return a
+ b
+ c
+ d
+ e
+ f
;
178 const char* CStringIdentity(const char* s
) {
182 int GetCopies(const CopyCounter
& counter
) {
183 return counter
.copies();
186 int UnwrapNoRefParent(NoRefParent p
) {
190 int UnwrapNoRefParentPtr(NoRefParent
* p
) {
194 int UnwrapNoRefParentConstRef(const NoRefParent
& p
) {
198 void RefArgSet(int &n
) {
202 void PtrArgSet(int *n
) {
206 int FunctionWithWeakFirstParam(WeakPtr
<NoRef
> o
, int n
) {
210 int FunctionWithScopedRefptrFirstParam(const scoped_refptr
<HasRef
>& o
, int n
) {
214 void TakesACallback(const Closure
& callback
) {
218 class BindTest
: public ::testing::Test
{
221 const_has_ref_ptr_
= &has_ref_
;
222 const_no_ref_ptr_
= &no_ref_
;
223 static_func_mock_ptr
= &static_func_mock_
;
226 virtual ~BindTest() {
229 static void VoidFunc0(void) {
230 static_func_mock_ptr
->VoidMethod0();
233 static int IntFunc0(void) { return static_func_mock_ptr
->IntMethod0(); }
236 StrictMock
<NoRef
> no_ref_
;
237 StrictMock
<HasRef
> has_ref_
;
238 const HasRef
* const_has_ref_ptr_
;
239 const NoRef
* const_no_ref_ptr_
;
240 StrictMock
<NoRef
> static_func_mock_
;
242 // Used by the static functions to perform expectations.
243 static StrictMock
<NoRef
>* static_func_mock_ptr
;
246 DISALLOW_COPY_AND_ASSIGN(BindTest
);
249 StrictMock
<NoRef
>* BindTest::static_func_mock_ptr
;
251 // Sanity check that we can instantiate a callback for each arity.
252 TEST_F(BindTest
, ArityTest
) {
253 Callback
<int(void)> c0
= Bind(&Sum
, 32, 16, 8, 4, 2, 1);
254 EXPECT_EQ(63, c0
.Run());
256 Callback
<int(int)> c1
= Bind(&Sum
, 32, 16, 8, 4, 2);
257 EXPECT_EQ(75, c1
.Run(13));
259 Callback
<int(int,int)> c2
= Bind(&Sum
, 32, 16, 8, 4);
260 EXPECT_EQ(85, c2
.Run(13, 12));
262 Callback
<int(int,int,int)> c3
= Bind(&Sum
, 32, 16, 8);
263 EXPECT_EQ(92, c3
.Run(13, 12, 11));
265 Callback
<int(int,int,int,int)> c4
= Bind(&Sum
, 32, 16);
266 EXPECT_EQ(94, c4
.Run(13, 12, 11, 10));
268 Callback
<int(int,int,int,int,int)> c5
= Bind(&Sum
, 32);
269 EXPECT_EQ(87, c5
.Run(13, 12, 11, 10, 9));
271 Callback
<int(int,int,int,int,int,int)> c6
= Bind(&Sum
);
272 EXPECT_EQ(69, c6
.Run(13, 12, 11, 10, 9, 14));
275 // Test the Currying ability of the Callback system.
276 TEST_F(BindTest
, CurryingTest
) {
277 Callback
<int(int,int,int,int,int,int)> c6
= Bind(&Sum
);
278 EXPECT_EQ(69, c6
.Run(13, 12, 11, 10, 9, 14));
280 Callback
<int(int,int,int,int,int)> c5
= Bind(c6
, 32);
281 EXPECT_EQ(87, c5
.Run(13, 12, 11, 10, 9));
283 Callback
<int(int,int,int,int)> c4
= Bind(c5
, 16);
284 EXPECT_EQ(94, c4
.Run(13, 12, 11, 10));
286 Callback
<int(int,int,int)> c3
= Bind(c4
, 8);
287 EXPECT_EQ(92, c3
.Run(13, 12, 11));
289 Callback
<int(int,int)> c2
= Bind(c3
, 4);
290 EXPECT_EQ(85, c2
.Run(13, 12));
292 Callback
<int(int)> c1
= Bind(c2
, 2);
293 EXPECT_EQ(75, c1
.Run(13));
295 Callback
<int(void)> c0
= Bind(c1
, 1);
296 EXPECT_EQ(63, c0
.Run());
299 // Test that currying the rvalue result of another Bind() works correctly.
300 // - rvalue should be usable as argument to Bind().
301 // - multiple runs of resulting Callback remain valid.
302 TEST_F(BindTest
, CurryingRvalueResultOfBind
) {
304 Closure cb
= base::Bind(&TakesACallback
, base::Bind(&PtrArgSet
, &n
));
306 // If we implement Bind() such that the return value has auto_ptr-like
307 // semantics, the second call here will fail because ownership of
308 // the internal BindState<> would have been transfered to a *temporary*
309 // constructon of a Callback object on the first call.
318 // Function type support.
319 // - Normal function.
320 // - Normal function bound with non-refcounted first argument.
321 // - Method bound to non-const object.
322 // - Method bound to scoped_refptr.
323 // - Const method bound to non-const object.
324 // - Const method bound to const object.
325 // - Derived classes can be used with pointers to non-virtual base functions.
326 // - Derived classes can be used with pointers to virtual base functions (and
327 // preserve virtual dispatch).
328 TEST_F(BindTest
, FunctionTypeSupport
) {
329 EXPECT_CALL(static_func_mock_
, VoidMethod0());
330 EXPECT_CALL(has_ref_
, AddRef()).Times(5);
331 EXPECT_CALL(has_ref_
, Release()).Times(5);
332 EXPECT_CALL(has_ref_
, VoidMethod0()).Times(2);
333 EXPECT_CALL(has_ref_
, VoidConstMethod0()).Times(2);
335 Closure normal_cb
= Bind(&VoidFunc0
);
336 Callback
<NoRef
*(void)> normal_non_refcounted_cb
=
337 Bind(&PolymorphicIdentity
<NoRef
*>, &no_ref_
);
339 EXPECT_EQ(&no_ref_
, normal_non_refcounted_cb
.Run());
341 Closure method_cb
= Bind(&HasRef::VoidMethod0
, &has_ref_
);
342 Closure method_refptr_cb
= Bind(&HasRef::VoidMethod0
,
343 make_scoped_refptr(&has_ref_
));
344 Closure const_method_nonconst_obj_cb
= Bind(&HasRef::VoidConstMethod0
,
346 Closure const_method_const_obj_cb
= Bind(&HasRef::VoidConstMethod0
,
349 method_refptr_cb
.Run();
350 const_method_nonconst_obj_cb
.Run();
351 const_method_const_obj_cb
.Run();
355 Closure virtual_set_cb
= Bind(&Parent::VirtualSet
, &child
);
356 virtual_set_cb
.Run();
357 EXPECT_EQ(kChildValue
, child
.value
);
360 Closure non_virtual_set_cb
= Bind(&Parent::NonVirtualSet
, &child
);
361 non_virtual_set_cb
.Run();
362 EXPECT_EQ(kParentValue
, child
.value
);
365 // Return value support.
366 // - Function with return value.
367 // - Method with return value.
368 // - Const method with return value.
369 TEST_F(BindTest
, ReturnValues
) {
370 EXPECT_CALL(static_func_mock_
, IntMethod0()).WillOnce(Return(1337));
371 EXPECT_CALL(has_ref_
, AddRef()).Times(3);
372 EXPECT_CALL(has_ref_
, Release()).Times(3);
373 EXPECT_CALL(has_ref_
, IntMethod0()).WillOnce(Return(31337));
374 EXPECT_CALL(has_ref_
, IntConstMethod0())
375 .WillOnce(Return(41337))
376 .WillOnce(Return(51337));
378 Callback
<int(void)> normal_cb
= Bind(&IntFunc0
);
379 Callback
<int(void)> method_cb
= Bind(&HasRef::IntMethod0
, &has_ref_
);
380 Callback
<int(void)> const_method_nonconst_obj_cb
=
381 Bind(&HasRef::IntConstMethod0
, &has_ref_
);
382 Callback
<int(void)> const_method_const_obj_cb
=
383 Bind(&HasRef::IntConstMethod0
, const_has_ref_ptr_
);
384 EXPECT_EQ(1337, normal_cb
.Run());
385 EXPECT_EQ(31337, method_cb
.Run());
386 EXPECT_EQ(41337, const_method_nonconst_obj_cb
.Run());
387 EXPECT_EQ(51337, const_method_const_obj_cb
.Run());
390 // IgnoreResult adapter test.
391 // - Function with return value.
392 // - Method with return value.
393 // - Const Method with return.
394 // - Method with return value bound to WeakPtr<>.
395 // - Const Method with return bound to WeakPtr<>.
396 TEST_F(BindTest
, IgnoreResult
) {
397 EXPECT_CALL(static_func_mock_
, IntMethod0()).WillOnce(Return(1337));
398 EXPECT_CALL(has_ref_
, AddRef()).Times(2);
399 EXPECT_CALL(has_ref_
, Release()).Times(2);
400 EXPECT_CALL(has_ref_
, IntMethod0()).WillOnce(Return(10));
401 EXPECT_CALL(has_ref_
, IntConstMethod0()).WillOnce(Return(11));
402 EXPECT_CALL(no_ref_
, IntMethod0()).WillOnce(Return(12));
403 EXPECT_CALL(no_ref_
, IntConstMethod0()).WillOnce(Return(13));
405 Closure normal_func_cb
= Bind(IgnoreResult(&IntFunc0
));
406 normal_func_cb
.Run();
408 Closure non_void_method_cb
=
409 Bind(IgnoreResult(&HasRef::IntMethod0
), &has_ref_
);
410 non_void_method_cb
.Run();
412 Closure non_void_const_method_cb
=
413 Bind(IgnoreResult(&HasRef::IntConstMethod0
), &has_ref_
);
414 non_void_const_method_cb
.Run();
416 WeakPtrFactory
<NoRef
> weak_factory(&no_ref_
);
417 WeakPtrFactory
<const NoRef
> const_weak_factory(const_no_ref_ptr_
);
419 Closure non_void_weak_method_cb
=
420 Bind(IgnoreResult(&NoRef::IntMethod0
), weak_factory
.GetWeakPtr());
421 non_void_weak_method_cb
.Run();
423 Closure non_void_weak_const_method_cb
=
424 Bind(IgnoreResult(&NoRef::IntConstMethod0
), weak_factory
.GetWeakPtr());
425 non_void_weak_const_method_cb
.Run();
427 weak_factory
.InvalidateWeakPtrs();
428 non_void_weak_const_method_cb
.Run();
429 non_void_weak_method_cb
.Run();
432 // Argument binding tests.
433 // - Argument binding to primitive.
434 // - Argument binding to primitive pointer.
435 // - Argument binding to a literal integer.
436 // - Argument binding to a literal string.
437 // - Argument binding with template function.
438 // - Argument binding to an object.
439 // - Argument binding to pointer to incomplete type.
440 // - Argument gets type converted.
441 // - Pointer argument gets converted.
442 // - Const Reference forces conversion.
443 TEST_F(BindTest
, ArgumentBinding
) {
446 Callback
<int(void)> bind_primitive_cb
= Bind(&Identity
, n
);
447 EXPECT_EQ(n
, bind_primitive_cb
.Run());
449 Callback
<int*(void)> bind_primitive_pointer_cb
=
450 Bind(&PolymorphicIdentity
<int*>, &n
);
451 EXPECT_EQ(&n
, bind_primitive_pointer_cb
.Run());
453 Callback
<int(void)> bind_int_literal_cb
= Bind(&Identity
, 3);
454 EXPECT_EQ(3, bind_int_literal_cb
.Run());
456 Callback
<const char*(void)> bind_string_literal_cb
=
457 Bind(&CStringIdentity
, "hi");
458 EXPECT_STREQ("hi", bind_string_literal_cb
.Run());
460 Callback
<int(void)> bind_template_function_cb
=
461 Bind(&PolymorphicIdentity
<int>, 4);
462 EXPECT_EQ(4, bind_template_function_cb
.Run());
466 Callback
<int(void)> bind_object_cb
= Bind(&UnwrapNoRefParent
, p
);
467 EXPECT_EQ(5, bind_object_cb
.Run());
469 IncompleteType
* incomplete_ptr
= reinterpret_cast<IncompleteType
*>(123);
470 Callback
<IncompleteType
*(void)> bind_incomplete_ptr_cb
=
471 Bind(&PolymorphicIdentity
<IncompleteType
*>, incomplete_ptr
);
472 EXPECT_EQ(incomplete_ptr
, bind_incomplete_ptr_cb
.Run());
476 Callback
<int(void)> bind_promotes_cb
= Bind(&UnwrapNoRefParent
, c
);
477 EXPECT_EQ(6, bind_promotes_cb
.Run());
480 Callback
<int(void)> bind_pointer_promotes_cb
=
481 Bind(&UnwrapNoRefParentPtr
, &c
);
482 EXPECT_EQ(7, bind_pointer_promotes_cb
.Run());
485 Callback
<int(void)> bind_const_reference_promotes_cb
=
486 Bind(&UnwrapNoRefParentConstRef
, c
);
487 EXPECT_EQ(8, bind_const_reference_promotes_cb
.Run());
490 // Unbound argument type support tests.
492 // - Unbound pointer.
493 // - Unbound reference.
494 // - Unbound const reference.
495 // - Unbound unsized array.
496 // - Unbound sized array.
497 // - Unbound array-of-arrays.
498 TEST_F(BindTest
, UnboundArgumentTypeSupport
) {
499 Callback
<void(int)> unbound_value_cb
= Bind(&VoidPolymorphic1
<int>);
500 Callback
<void(int*)> unbound_pointer_cb
= Bind(&VoidPolymorphic1
<int*>);
501 Callback
<void(int&)> unbound_ref_cb
= Bind(&VoidPolymorphic1
<int&>);
502 Callback
<void(const int&)> unbound_const_ref_cb
=
503 Bind(&VoidPolymorphic1
<const int&>);
504 Callback
<void(int[])> unbound_unsized_array_cb
=
505 Bind(&VoidPolymorphic1
<int[]>);
506 Callback
<void(int[2])> unbound_sized_array_cb
=
507 Bind(&VoidPolymorphic1
<int[2]>);
508 Callback
<void(int[][2])> unbound_array_of_arrays_cb
=
509 Bind(&VoidPolymorphic1
<int[][2]>);
512 // Function with unbound reference parameter.
513 // - Original parameter is modified by callback.
514 TEST_F(BindTest
, UnboundReferenceSupport
) {
516 Callback
<void(int&)> unbound_ref_cb
= Bind(&RefArgSet
);
517 unbound_ref_cb
.Run(n
);
521 // Functions that take reference parameters.
522 // - Forced reference parameter type still stores a copy.
523 // - Forced const reference parameter type still stores a copy.
524 TEST_F(BindTest
, ReferenceArgumentBinding
) {
527 const int& const_ref_n
= n
;
529 Callback
<int(void)> ref_copies_cb
= Bind(&Identity
, ref_n
);
530 EXPECT_EQ(n
, ref_copies_cb
.Run());
532 EXPECT_EQ(n
- 1, ref_copies_cb
.Run());
534 Callback
<int(void)> const_ref_copies_cb
= Bind(&Identity
, const_ref_n
);
535 EXPECT_EQ(n
, const_ref_copies_cb
.Run());
537 EXPECT_EQ(n
- 1, const_ref_copies_cb
.Run());
540 // Check that we can pass in arrays and have them be stored as a pointer.
541 // - Array of values stores a pointer.
542 // - Array of const values stores a pointer.
543 TEST_F(BindTest
, ArrayArgumentBinding
) {
544 int array
[4] = {1, 1, 1, 1};
545 const int (*const_array_ptr
)[4] = &array
;
547 Callback
<int(void)> array_cb
= Bind(&ArrayGet
, array
, 1);
548 EXPECT_EQ(1, array_cb
.Run());
550 Callback
<int(void)> const_array_cb
= Bind(&ArrayGet
, *const_array_ptr
, 1);
551 EXPECT_EQ(1, const_array_cb
.Run());
554 EXPECT_EQ(3, array_cb
.Run());
555 EXPECT_EQ(3, const_array_cb
.Run());
558 // Verify SupportsAddRefAndRelease correctly introspects the class type for
559 // AddRef() and Release().
560 // - Class with AddRef() and Release()
561 // - Class without AddRef() and Release()
562 // - Derived Class with AddRef() and Release()
563 // - Derived Class without AddRef() and Release()
564 // - Derived Class with AddRef() and Release() and a private destructor.
565 TEST_F(BindTest
, SupportsAddRefAndRelease
) {
566 EXPECT_TRUE(internal::SupportsAddRefAndRelease
<HasRef
>::value
);
567 EXPECT_FALSE(internal::SupportsAddRefAndRelease
<NoRef
>::value
);
569 // StrictMock<T> is a derived class of T. So, we use StrictMock<HasRef> and
570 // StrictMock<NoRef> to test that SupportsAddRefAndRelease works over
572 EXPECT_TRUE(internal::SupportsAddRefAndRelease
<StrictMock
<HasRef
> >::value
);
573 EXPECT_FALSE(internal::SupportsAddRefAndRelease
<StrictMock
<NoRef
> >::value
);
575 // This matters because the implementation creates a dummy class that
576 // inherits from the template type.
577 EXPECT_TRUE(internal::SupportsAddRefAndRelease
<HasRefPrivateDtor
>::value
);
580 // Unretained() wrapper support.
581 // - Method bound to Unretained() non-const object.
582 // - Const method bound to Unretained() non-const object.
583 // - Const method bound to Unretained() const object.
584 TEST_F(BindTest
, Unretained
) {
585 EXPECT_CALL(no_ref_
, VoidMethod0());
586 EXPECT_CALL(no_ref_
, VoidConstMethod0()).Times(2);
588 Callback
<void(void)> method_cb
=
589 Bind(&NoRef::VoidMethod0
, Unretained(&no_ref_
));
592 Callback
<void(void)> const_method_cb
=
593 Bind(&NoRef::VoidConstMethod0
, Unretained(&no_ref_
));
594 const_method_cb
.Run();
596 Callback
<void(void)> const_method_const_ptr_cb
=
597 Bind(&NoRef::VoidConstMethod0
, Unretained(const_no_ref_ptr_
));
598 const_method_const_ptr_cb
.Run();
601 // WeakPtr() support.
602 // - Method bound to WeakPtr<> to non-const object.
603 // - Const method bound to WeakPtr<> to non-const object.
604 // - Const method bound to WeakPtr<> to const object.
605 // - Normal Function with WeakPtr<> as P1 can have return type and is
607 TEST_F(BindTest
, WeakPtr
) {
608 EXPECT_CALL(no_ref_
, VoidMethod0());
609 EXPECT_CALL(no_ref_
, VoidConstMethod0()).Times(2);
611 WeakPtrFactory
<NoRef
> weak_factory(&no_ref_
);
612 WeakPtrFactory
<const NoRef
> const_weak_factory(const_no_ref_ptr_
);
615 Bind(&NoRef::VoidMethod0
, weak_factory
.GetWeakPtr());
618 Closure const_method_cb
=
619 Bind(&NoRef::VoidConstMethod0
, const_weak_factory
.GetWeakPtr());
620 const_method_cb
.Run();
622 Closure const_method_const_ptr_cb
=
623 Bind(&NoRef::VoidConstMethod0
, const_weak_factory
.GetWeakPtr());
624 const_method_const_ptr_cb
.Run();
626 Callback
<int(int)> normal_func_cb
=
627 Bind(&FunctionWithWeakFirstParam
, weak_factory
.GetWeakPtr());
628 EXPECT_EQ(1, normal_func_cb
.Run(1));
630 weak_factory
.InvalidateWeakPtrs();
631 const_weak_factory
.InvalidateWeakPtrs();
634 const_method_cb
.Run();
635 const_method_const_ptr_cb
.Run();
637 // Still runs even after the pointers are invalidated.
638 EXPECT_EQ(2, normal_func_cb
.Run(2));
641 // ConstRef() wrapper support.
642 // - Binding w/o ConstRef takes a copy.
643 // - Binding a ConstRef takes a reference.
644 // - Binding ConstRef to a function ConstRef does not copy on invoke.
645 TEST_F(BindTest
, ConstRef
) {
648 Callback
<int(void)> copy_cb
= Bind(&Identity
, n
);
649 Callback
<int(void)> const_ref_cb
= Bind(&Identity
, ConstRef(n
));
650 EXPECT_EQ(n
, copy_cb
.Run());
651 EXPECT_EQ(n
, const_ref_cb
.Run());
653 EXPECT_EQ(n
- 1, copy_cb
.Run());
654 EXPECT_EQ(n
, const_ref_cb
.Run());
658 CopyCounter
counter(&copies
, &assigns
);
659 Callback
<int(void)> all_const_ref_cb
=
660 Bind(&GetCopies
, ConstRef(counter
));
661 EXPECT_EQ(0, all_const_ref_cb
.Run());
662 EXPECT_EQ(0, copies
);
663 EXPECT_EQ(0, assigns
);
666 TEST_F(BindTest
, ScopedRefptr
) {
667 // BUG: The scoped_refptr should cause the only AddRef()/Release() pair. But
668 // due to a bug in base::Bind(), there's an extra call when invoking the
670 // https://code.google.com/p/chromium/issues/detail?id=251937
671 EXPECT_CALL(has_ref_
, AddRef()).Times(2);
672 EXPECT_CALL(has_ref_
, Release()).Times(2);
674 const scoped_refptr
<StrictMock
<HasRef
> > refptr(&has_ref_
);
676 Callback
<int(void)> scoped_refptr_const_ref_cb
=
677 Bind(&FunctionWithScopedRefptrFirstParam
, base::ConstRef(refptr
), 1);
678 EXPECT_EQ(1, scoped_refptr_const_ref_cb
.Run());
681 // Test Owned() support.
682 TEST_F(BindTest
, Owned
) {
684 DeleteCounter
* counter
= new DeleteCounter(&deletes
);
686 // If we don't capture, delete happens on Callback destruction/reset.
687 // return the same value.
688 Callback
<DeleteCounter
*(void)> no_capture_cb
=
689 Bind(&PolymorphicIdentity
<DeleteCounter
*>, Owned(counter
));
690 ASSERT_EQ(counter
, no_capture_cb
.Run());
691 ASSERT_EQ(counter
, no_capture_cb
.Run());
692 EXPECT_EQ(0, deletes
);
693 no_capture_cb
.Reset(); // This should trigger a delete.
694 EXPECT_EQ(1, deletes
);
697 counter
= new DeleteCounter(&deletes
);
698 base::Closure own_object_cb
=
699 Bind(&DeleteCounter::VoidMethod0
, Owned(counter
));
701 EXPECT_EQ(0, deletes
);
702 own_object_cb
.Reset();
703 EXPECT_EQ(1, deletes
);
706 // Passed() wrapper support.
707 // - Passed() can be constructed from a pointer to scoper.
708 // - Passed() can be constructed from a scoper rvalue.
709 // - Using Passed() gives Callback Ownership.
710 // - Ownership is transferred from Callback to callee on the first Run().
711 // - Callback supports unbound arguments.
712 TEST_F(BindTest
, ScopedPtr
) {
715 // Tests the Passed() function's support for pointers.
716 scoped_ptr
<DeleteCounter
> ptr(new DeleteCounter(&deletes
));
717 Callback
<scoped_ptr
<DeleteCounter
>(void)> unused_callback
=
718 Bind(&PassThru
<scoped_ptr
<DeleteCounter
> >, Passed(&ptr
));
719 EXPECT_FALSE(ptr
.get());
720 EXPECT_EQ(0, deletes
);
722 // If we never invoke the Callback, it retains ownership and deletes.
723 unused_callback
.Reset();
724 EXPECT_EQ(1, deletes
);
726 // Tests the Passed() function's support for rvalues.
728 DeleteCounter
* counter
= new DeleteCounter(&deletes
);
729 Callback
<scoped_ptr
<DeleteCounter
>(void)> callback
=
730 Bind(&PassThru
<scoped_ptr
<DeleteCounter
> >,
731 Passed(scoped_ptr
<DeleteCounter
>(counter
)));
732 EXPECT_FALSE(ptr
.get());
733 EXPECT_EQ(0, deletes
);
735 // Check that ownership can be transferred back out.
736 scoped_ptr
<DeleteCounter
> result
= callback
.Run();
737 ASSERT_EQ(counter
, result
.get());
738 EXPECT_EQ(0, deletes
);
740 // Resetting does not delete since ownership was transferred.
742 EXPECT_EQ(0, deletes
);
744 // Ensure that we actually did get ownership.
746 EXPECT_EQ(1, deletes
);
748 // Test unbound argument forwarding.
749 Callback
<scoped_ptr
<DeleteCounter
>(scoped_ptr
<DeleteCounter
>)> cb_unbound
=
750 Bind(&PassThru
<scoped_ptr
<DeleteCounter
> >);
751 ptr
.reset(new DeleteCounter(&deletes
));
752 cb_unbound
.Run(ptr
.Pass());
755 // Argument Copy-constructor usage for non-reference parameters.
756 // - Bound arguments are only copied once.
757 // - Forwarded arguments are only copied once.
758 // - Forwarded arguments with coercions are only copied twice (once for the
759 // coercion, and one for the final dispatch).
760 TEST_F(BindTest
, ArgumentCopies
) {
764 CopyCounter
counter(&copies
, &assigns
);
766 Callback
<void(void)> copy_cb
=
767 Bind(&VoidPolymorphic1
<CopyCounter
>, counter
);
768 EXPECT_GE(1, copies
);
769 EXPECT_EQ(0, assigns
);
773 Callback
<void(CopyCounter
)> forward_cb
=
774 Bind(&VoidPolymorphic1
<CopyCounter
>);
775 forward_cb
.Run(counter
);
776 EXPECT_GE(1, copies
);
777 EXPECT_EQ(0, assigns
);
781 DerivedCopyCounter
derived(&copies
, &assigns
);
782 Callback
<void(CopyCounter
)> coerce_cb
=
783 Bind(&VoidPolymorphic1
<CopyCounter
>);
784 coerce_cb
.Run(CopyCounter(derived
));
785 EXPECT_GE(2, copies
);
786 EXPECT_EQ(0, assigns
);
789 // Callback construction and assignment tests.
790 // - Construction from an InvokerStorageHolder should not cause ref/deref.
791 // - Assignment from other callback should only cause one ref
793 // TODO(ajwong): Is there actually a way to test this?
796 int __fastcall
FastCallFunc(int n
) {
800 int __stdcall
StdCallFunc(int n
) {
804 // Windows specific calling convention support.
805 // - Can bind a __fastcall function.
806 // - Can bind a __stdcall function.
807 TEST_F(BindTest
, WindowsCallingConventions
) {
808 Callback
<int(void)> fastcall_cb
= Bind(&FastCallFunc
, 1);
809 EXPECT_EQ(1, fastcall_cb
.Run());
811 Callback
<int(void)> stdcall_cb
= Bind(&StdCallFunc
, 2);
812 EXPECT_EQ(2, stdcall_cb
.Run());
816 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
818 // Test null callbacks cause a DCHECK.
819 TEST(BindDeathTest
, NullCallback
) {
820 base::Callback
<void(int)> null_cb
;
821 ASSERT_TRUE(null_cb
.is_null());
822 EXPECT_DEATH(base::Bind(null_cb
, 42), "");
825 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) &&
826 // GTEST_HAS_DEATH_TEST