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 BindState() : BindStateBase(&Destroy
) {}
39 typedef FakeInvoker InvokerType
;
42 static void Destroy(BindStateBase
* self
) {
43 delete static_cast<BindState
*>(self
);
48 struct BindState
<void(void), void(void),
49 void(FakeInvoker
, FakeInvoker
)>
50 : public BindStateBase
{
52 BindState() : BindStateBase(&Destroy
) {}
53 typedef FakeInvoker InvokerType
;
56 static void Destroy(BindStateBase
* self
) {
57 delete static_cast<BindState
*>(self
);
60 } // namespace internal
64 typedef internal::BindState
<void(void), void(void), void(FakeInvoker
)>
66 typedef internal::BindState
<void(void), void(void),
67 void(FakeInvoker
, FakeInvoker
)>
70 class CallbackTest
: public ::testing::Test
{
73 : callback_a_(new FakeBindState1()),
74 callback_b_(new FakeBindState2()) {
77 ~CallbackTest() override
{}
80 Callback
<void(void)> callback_a_
;
81 const Callback
<void(void)> callback_b_
; // Ensure APIs work with const.
82 Callback
<void(void)> null_callback_
;
85 // Ensure we can create unbound callbacks. We need this to be able to store
86 // them in class members that can be initialized later.
87 TEST_F(CallbackTest
, DefaultConstruction
) {
88 Callback
<void(void)> c0
;
89 Callback
<void(int)> c1
;
90 Callback
<void(int,int)> c2
;
91 Callback
<void(int,int,int)> c3
;
92 Callback
<void(int,int,int,int)> c4
;
93 Callback
<void(int,int,int,int,int)> c5
;
94 Callback
<void(int,int,int,int,int,int)> c6
;
96 EXPECT_TRUE(c0
.is_null());
97 EXPECT_TRUE(c1
.is_null());
98 EXPECT_TRUE(c2
.is_null());
99 EXPECT_TRUE(c3
.is_null());
100 EXPECT_TRUE(c4
.is_null());
101 EXPECT_TRUE(c5
.is_null());
102 EXPECT_TRUE(c6
.is_null());
105 TEST_F(CallbackTest
, IsNull
) {
106 EXPECT_TRUE(null_callback_
.is_null());
107 EXPECT_FALSE(callback_a_
.is_null());
108 EXPECT_FALSE(callback_b_
.is_null());
111 TEST_F(CallbackTest
, Equals
) {
112 EXPECT_TRUE(callback_a_
.Equals(callback_a_
));
113 EXPECT_FALSE(callback_a_
.Equals(callback_b_
));
114 EXPECT_FALSE(callback_b_
.Equals(callback_a_
));
116 // We should compare based on instance, not type.
117 Callback
<void(void)> callback_c(new FakeBindState1());
118 Callback
<void(void)> callback_a2
= callback_a_
;
119 EXPECT_TRUE(callback_a_
.Equals(callback_a2
));
120 EXPECT_FALSE(callback_a_
.Equals(callback_c
));
122 // Empty, however, is always equal to empty.
123 Callback
<void(void)> empty2
;
124 EXPECT_TRUE(null_callback_
.Equals(empty2
));
127 TEST_F(CallbackTest
, Reset
) {
128 // Resetting should bring us back to empty.
129 ASSERT_FALSE(callback_a_
.is_null());
130 ASSERT_FALSE(callback_a_
.Equals(null_callback_
));
134 EXPECT_TRUE(callback_a_
.is_null());
135 EXPECT_TRUE(callback_a_
.Equals(null_callback_
));
138 struct TestForReentrancy
{
140 : cb_already_run(false),
141 cb(Bind(&TestForReentrancy::AssertCBIsNull
, Unretained(this))) {
143 void AssertCBIsNull() {
144 ASSERT_TRUE(cb
.is_null());
145 cb_already_run
= true;
151 TEST_F(CallbackTest
, ResetAndReturn
) {
152 TestForReentrancy tfr
;
153 ASSERT_FALSE(tfr
.cb
.is_null());
154 ASSERT_FALSE(tfr
.cb_already_run
);
155 ResetAndReturn(&tfr
.cb
).Run();
156 ASSERT_TRUE(tfr
.cb
.is_null());
157 ASSERT_TRUE(tfr
.cb_already_run
);
160 class CallbackOwner
: public base::RefCounted
<CallbackOwner
> {
162 explicit CallbackOwner(bool* deleted
) {
163 callback_
= Bind(&CallbackOwner::Unused
, this);
168 // We are deleted here if no-one else had a ref to us.
172 friend class base::RefCounted
<CallbackOwner
>;
173 virtual ~CallbackOwner() {
177 FAIL() << "Should never be called";
184 TEST_F(CallbackTest
, CallbackHasLastRefOnContainingObject
) {
185 bool deleted
= false;
186 CallbackOwner
* owner
= new CallbackOwner(&deleted
);
188 ASSERT_TRUE(deleted
);