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.
6 #include "base/callback.h"
7 #include "base/callback_helpers.h"
8 #include "base/callback_internal.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "testing/gtest/include/gtest/gtest.h"
18 typedef void(RunType
)(internal::BindStateBase
*);
19 static void Run(internal::BindStateBase
*) {
26 template <typename Runnable
, typename RunType
, typename BoundArgsType
>
29 // White-box testpoints to inject into a Callback<> object for checking
30 // comparators and emptiness APIs. Use a BindState that is specialized
31 // based on a type we declared in the anonymous namespace above to remove any
32 // chance of colliding with another instantiation and breaking the
33 // one-definition-rule.
35 struct BindState
<void(void), void(void), void(FakeInvoker
)>
36 : public BindStateBase
{
38 typedef FakeInvoker InvokerType
;
40 ~BindState() override
{}
44 struct BindState
<void(void), void(void),
45 void(FakeInvoker
, FakeInvoker
)>
46 : public BindStateBase
{
48 typedef FakeInvoker InvokerType
;
50 ~BindState() override
{}
52 } // namespace internal
56 typedef internal::BindState
<void(void), void(void), void(FakeInvoker
)>
58 typedef internal::BindState
<void(void), void(void),
59 void(FakeInvoker
, FakeInvoker
)>
62 class CallbackTest
: public ::testing::Test
{
65 : callback_a_(new FakeBindState1()),
66 callback_b_(new FakeBindState2()) {
69 ~CallbackTest() override
{}
72 Callback
<void(void)> callback_a_
;
73 const Callback
<void(void)> callback_b_
; // Ensure APIs work with const.
74 Callback
<void(void)> null_callback_
;
77 // Ensure we can create unbound callbacks. We need this to be able to store
78 // them in class members that can be initialized later.
79 TEST_F(CallbackTest
, DefaultConstruction
) {
80 Callback
<void(void)> c0
;
81 Callback
<void(int)> c1
;
82 Callback
<void(int,int)> c2
;
83 Callback
<void(int,int,int)> c3
;
84 Callback
<void(int,int,int,int)> c4
;
85 Callback
<void(int,int,int,int,int)> c5
;
86 Callback
<void(int,int,int,int,int,int)> c6
;
88 EXPECT_TRUE(c0
.is_null());
89 EXPECT_TRUE(c1
.is_null());
90 EXPECT_TRUE(c2
.is_null());
91 EXPECT_TRUE(c3
.is_null());
92 EXPECT_TRUE(c4
.is_null());
93 EXPECT_TRUE(c5
.is_null());
94 EXPECT_TRUE(c6
.is_null());
97 TEST_F(CallbackTest
, IsNull
) {
98 EXPECT_TRUE(null_callback_
.is_null());
99 EXPECT_FALSE(callback_a_
.is_null());
100 EXPECT_FALSE(callback_b_
.is_null());
103 TEST_F(CallbackTest
, Equals
) {
104 EXPECT_TRUE(callback_a_
.Equals(callback_a_
));
105 EXPECT_FALSE(callback_a_
.Equals(callback_b_
));
106 EXPECT_FALSE(callback_b_
.Equals(callback_a_
));
108 // We should compare based on instance, not type.
109 Callback
<void(void)> callback_c(new FakeBindState1());
110 Callback
<void(void)> callback_a2
= callback_a_
;
111 EXPECT_TRUE(callback_a_
.Equals(callback_a2
));
112 EXPECT_FALSE(callback_a_
.Equals(callback_c
));
114 // Empty, however, is always equal to empty.
115 Callback
<void(void)> empty2
;
116 EXPECT_TRUE(null_callback_
.Equals(empty2
));
119 TEST_F(CallbackTest
, Reset
) {
120 // Resetting should bring us back to empty.
121 ASSERT_FALSE(callback_a_
.is_null());
122 ASSERT_FALSE(callback_a_
.Equals(null_callback_
));
126 EXPECT_TRUE(callback_a_
.is_null());
127 EXPECT_TRUE(callback_a_
.Equals(null_callback_
));
130 struct TestForReentrancy
{
132 : cb_already_run(false),
133 cb(Bind(&TestForReentrancy::AssertCBIsNull
, Unretained(this))) {
135 void AssertCBIsNull() {
136 ASSERT_TRUE(cb
.is_null());
137 cb_already_run
= true;
143 TEST_F(CallbackTest
, ResetAndReturn
) {
144 TestForReentrancy tfr
;
145 ASSERT_FALSE(tfr
.cb
.is_null());
146 ASSERT_FALSE(tfr
.cb_already_run
);
147 ResetAndReturn(&tfr
.cb
).Run();
148 ASSERT_TRUE(tfr
.cb
.is_null());
149 ASSERT_TRUE(tfr
.cb_already_run
);
152 class CallbackOwner
: public base::RefCounted
<CallbackOwner
> {
154 explicit CallbackOwner(bool* deleted
) {
155 callback_
= Bind(&CallbackOwner::Unused
, this);
160 // We are deleted here if no-one else had a ref to us.
164 friend class base::RefCounted
<CallbackOwner
>;
165 virtual ~CallbackOwner() {
169 FAIL() << "Should never be called";
176 TEST_F(CallbackTest
, CallbackHasLastRefOnContainingObject
) {
177 bool deleted
= false;
178 CallbackOwner
* owner
= new CallbackOwner(&deleted
);
180 ASSERT_TRUE(deleted
);