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
;
42 struct BindState
<void(void), void(void),
43 void(FakeInvoker
, FakeInvoker
)>
44 : public BindStateBase
{
46 typedef FakeInvoker InvokerType
;
48 } // namespace internal
52 typedef internal::BindState
<void(void), void(void), void(FakeInvoker
)>
54 typedef internal::BindState
<void(void), void(void),
55 void(FakeInvoker
, FakeInvoker
)>
58 class CallbackTest
: public ::testing::Test
{
61 : callback_a_(new FakeBindState1()),
62 callback_b_(new FakeBindState2()) {
65 virtual ~CallbackTest() {
69 Callback
<void(void)> callback_a_
;
70 const Callback
<void(void)> callback_b_
; // Ensure APIs work with const.
71 Callback
<void(void)> null_callback_
;
74 // Ensure we can create unbound callbacks. We need this to be able to store
75 // them in class members that can be initialized later.
76 TEST_F(CallbackTest
, DefaultConstruction
) {
77 Callback
<void(void)> c0
;
78 Callback
<void(int)> c1
;
79 Callback
<void(int,int)> c2
;
80 Callback
<void(int,int,int)> c3
;
81 Callback
<void(int,int,int,int)> c4
;
82 Callback
<void(int,int,int,int,int)> c5
;
83 Callback
<void(int,int,int,int,int,int)> c6
;
85 EXPECT_TRUE(c0
.is_null());
86 EXPECT_TRUE(c1
.is_null());
87 EXPECT_TRUE(c2
.is_null());
88 EXPECT_TRUE(c3
.is_null());
89 EXPECT_TRUE(c4
.is_null());
90 EXPECT_TRUE(c5
.is_null());
91 EXPECT_TRUE(c6
.is_null());
94 TEST_F(CallbackTest
, IsNull
) {
95 EXPECT_TRUE(null_callback_
.is_null());
96 EXPECT_FALSE(callback_a_
.is_null());
97 EXPECT_FALSE(callback_b_
.is_null());
100 TEST_F(CallbackTest
, Equals
) {
101 EXPECT_TRUE(callback_a_
.Equals(callback_a_
));
102 EXPECT_FALSE(callback_a_
.Equals(callback_b_
));
103 EXPECT_FALSE(callback_b_
.Equals(callback_a_
));
105 // We should compare based on instance, not type.
106 Callback
<void(void)> callback_c(new FakeBindState1());
107 Callback
<void(void)> callback_a2
= callback_a_
;
108 EXPECT_TRUE(callback_a_
.Equals(callback_a2
));
109 EXPECT_FALSE(callback_a_
.Equals(callback_c
));
111 // Empty, however, is always equal to empty.
112 Callback
<void(void)> empty2
;
113 EXPECT_TRUE(null_callback_
.Equals(empty2
));
116 TEST_F(CallbackTest
, Reset
) {
117 // Resetting should bring us back to empty.
118 ASSERT_FALSE(callback_a_
.is_null());
119 ASSERT_FALSE(callback_a_
.Equals(null_callback_
));
123 EXPECT_TRUE(callback_a_
.is_null());
124 EXPECT_TRUE(callback_a_
.Equals(null_callback_
));
127 struct TestForReentrancy
{
129 : cb_already_run(false),
130 cb(Bind(&TestForReentrancy::AssertCBIsNull
, Unretained(this))) {
132 void AssertCBIsNull() {
133 ASSERT_TRUE(cb
.is_null());
134 cb_already_run
= true;
140 TEST_F(CallbackTest
, ResetAndReturn
) {
141 TestForReentrancy tfr
;
142 ASSERT_FALSE(tfr
.cb
.is_null());
143 ASSERT_FALSE(tfr
.cb_already_run
);
144 ResetAndReturn(&tfr
.cb
).Run();
145 ASSERT_TRUE(tfr
.cb
.is_null());
146 ASSERT_TRUE(tfr
.cb_already_run
);
149 class CallbackOwner
: public base::RefCounted
<CallbackOwner
> {
151 explicit CallbackOwner(bool* deleted
) {
152 callback_
= Bind(&CallbackOwner::Unused
, this);
157 // We are deleted here if no-one else had a ref to us.
161 friend class base::RefCounted
<CallbackOwner
>;
162 virtual ~CallbackOwner() {
166 FAIL() << "Should never be called";
173 TEST_F(CallbackTest
, CallbackHasLastRefOnContainingObject
) {
174 bool deleted
= false;
175 CallbackOwner
* owner
= new CallbackOwner(&deleted
);
177 ASSERT_TRUE(deleted
);