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 virtual ~CallbackTest() {
73 Callback
<void(void)> callback_a_
;
74 const Callback
<void(void)> callback_b_
; // Ensure APIs work with const.
75 Callback
<void(void)> null_callback_
;
78 // Ensure we can create unbound callbacks. We need this to be able to store
79 // them in class members that can be initialized later.
80 TEST_F(CallbackTest
, DefaultConstruction
) {
81 Callback
<void(void)> c0
;
82 Callback
<void(int)> c1
;
83 Callback
<void(int,int)> c2
;
84 Callback
<void(int,int,int)> c3
;
85 Callback
<void(int,int,int,int)> c4
;
86 Callback
<void(int,int,int,int,int)> c5
;
87 Callback
<void(int,int,int,int,int,int)> c6
;
89 EXPECT_TRUE(c0
.is_null());
90 EXPECT_TRUE(c1
.is_null());
91 EXPECT_TRUE(c2
.is_null());
92 EXPECT_TRUE(c3
.is_null());
93 EXPECT_TRUE(c4
.is_null());
94 EXPECT_TRUE(c5
.is_null());
95 EXPECT_TRUE(c6
.is_null());
98 TEST_F(CallbackTest
, IsNull
) {
99 EXPECT_TRUE(null_callback_
.is_null());
100 EXPECT_FALSE(callback_a_
.is_null());
101 EXPECT_FALSE(callback_b_
.is_null());
104 TEST_F(CallbackTest
, Equals
) {
105 EXPECT_TRUE(callback_a_
.Equals(callback_a_
));
106 EXPECT_FALSE(callback_a_
.Equals(callback_b_
));
107 EXPECT_FALSE(callback_b_
.Equals(callback_a_
));
109 // We should compare based on instance, not type.
110 Callback
<void(void)> callback_c(new FakeBindState1());
111 Callback
<void(void)> callback_a2
= callback_a_
;
112 EXPECT_TRUE(callback_a_
.Equals(callback_a2
));
113 EXPECT_FALSE(callback_a_
.Equals(callback_c
));
115 // Empty, however, is always equal to empty.
116 Callback
<void(void)> empty2
;
117 EXPECT_TRUE(null_callback_
.Equals(empty2
));
120 TEST_F(CallbackTest
, Reset
) {
121 // Resetting should bring us back to empty.
122 ASSERT_FALSE(callback_a_
.is_null());
123 ASSERT_FALSE(callback_a_
.Equals(null_callback_
));
127 EXPECT_TRUE(callback_a_
.is_null());
128 EXPECT_TRUE(callback_a_
.Equals(null_callback_
));
131 struct TestForReentrancy
{
133 : cb_already_run(false),
134 cb(Bind(&TestForReentrancy::AssertCBIsNull
, Unretained(this))) {
136 void AssertCBIsNull() {
137 ASSERT_TRUE(cb
.is_null());
138 cb_already_run
= true;
144 TEST_F(CallbackTest
, ResetAndReturn
) {
145 TestForReentrancy tfr
;
146 ASSERT_FALSE(tfr
.cb
.is_null());
147 ASSERT_FALSE(tfr
.cb_already_run
);
148 ResetAndReturn(&tfr
.cb
).Run();
149 ASSERT_TRUE(tfr
.cb
.is_null());
150 ASSERT_TRUE(tfr
.cb_already_run
);
153 class CallbackOwner
: public base::RefCounted
<CallbackOwner
> {
155 explicit CallbackOwner(bool* deleted
) {
156 callback_
= Bind(&CallbackOwner::Unused
, this);
161 // We are deleted here if no-one else had a ref to us.
165 friend class base::RefCounted
<CallbackOwner
>;
166 virtual ~CallbackOwner() {
170 FAIL() << "Should never be called";
177 TEST_F(CallbackTest
, CallbackHasLastRefOnContainingObject
) {
178 bool deleted
= false;
179 CallbackOwner
* owner
= new CallbackOwner(&deleted
);
181 ASSERT_TRUE(deleted
);