Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: base/cancelable_callback_unittest.cc

Issue 8673008: base::Bind: Implement CancelableCallback to replace CancelableTaske. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More reviewer fixes. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/cancelable_callback.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/message_loop.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace base {
13 namespace {
14
15 class TestRefCounted : public RefCountedThreadSafe<TestRefCounted> {
16 private:
17 friend class RefCountedThreadSafe<TestRefCounted>;
18 ~TestRefCounted() {};
19 };
20
21 void Increment(int* count) { (*count)++; }
22 void IncrementBy(int* count, int n) { (*count) += n; }
23 void RefCountedParam(const scoped_refptr<TestRefCounted>& ref_counted) {}
24
25 // * Callback can be run multiple times.
awong 2011/11/23 23:41:07 Formatting Nit: I've been using a "-" instead of a
James Hawkins 2011/11/24 00:11:15 Done.
26 // * After Cancel(), Run() completes but has no effect.
27 TEST(CancelableCallbackTest, Cancel) {
28 int count = 0;
29 CancelableCallback cancelable(
30 base::Bind(Increment, base::Unretained(&count)));
31
32 base::Closure callback = cancelable.callback();
33 callback.Run();
34 EXPECT_EQ(1, count);
35
36 callback.Run();
37 EXPECT_EQ(2, count);
38
39 cancelable.Cancel();
40 callback.Run();
41 EXPECT_EQ(2, count);
42 }
43
44 // * Cancel() can be called multiple times.
45 // * Cancel() cancels all copies of the wrapped callback.
46 TEST(CancelableCallbackTest, MultipleCancel) {
47 int count = 0;
48 CancelableCallback cancelable(
49 base::Bind(Increment, base::Unretained(&count)));
50
51 base::Closure callback1 = cancelable.callback();
52 cancelable.Cancel();
53
54 callback1.Run();
55 EXPECT_EQ(0, count);
56
57 base::Closure callback2 = cancelable.callback();
58 callback2.Run();
59 EXPECT_EQ(0, count);
60
61 base::Closure callback3 = cancelable.callback();
62 cancelable.Cancel();
awong 2011/11/23 23:41:07 Add comment saying this Cancel() should have no ef
James Hawkins 2011/11/24 00:11:15 Done.
63 callback3.Run();
64 EXPECT_EQ(0, count);
65 }
66
67 // * Destruction of CancelableCallback cancels outstanding callbacks.
68 TEST(CancelableCallbackTest, CallbackCanceledOnDestruction) {
69 int count = 0;
70 base::Closure callback;
71
72 {
73 CancelableCallback cancelable(
74 base::Bind(Increment, base::Unretained(&count)));
75
76 callback = cancelable.callback();
77 callback.Run();
78 EXPECT_EQ(1, count);
79 }
80
81 callback.Run();
82 EXPECT_EQ(1, count);
83 }
84
85 // * Cancel drops wrapped callback (and, implicitly, its bound arguments).
86 TEST(CancelableCallbackTest, CancelDropsCallback) {
87 scoped_refptr<TestRefCounted> ref_counted = new TestRefCounted;
88 EXPECT_TRUE(ref_counted->HasOneRef());
89
90 CancelableCallback cancelable(base::Bind(RefCountedParam, ref_counted));
91 EXPECT_FALSE(cancelable.is_null());
92 EXPECT_TRUE(ref_counted.get());
93 EXPECT_FALSE(ref_counted->HasOneRef());
94
95 // There is only one reference to |ref_counted| after the Cancel().
96 cancelable.Cancel();
97 EXPECT_TRUE(cancelable.is_null());
98 EXPECT_TRUE(ref_counted.get());
99 EXPECT_TRUE(ref_counted->HasOneRef());
100 }
101
102 // * Reset() replaces the existing wrapped callback with a new callback.
103 // * Reset() deactivates outstanding callbacks.
104 TEST(CancelableCallbackTest, Reset) {
105 int count = 0;
106 CancelableCallback cancelable(
107 base::Bind(Increment, base::Unretained(&count)));
108
109 base::Closure callback = cancelable.callback();
110 callback.Run();
111 EXPECT_EQ(1, count);
112
113 callback.Run();
114 EXPECT_EQ(2, count);
115
116 cancelable.Reset(
117 base::Bind(IncrementBy, base::Unretained(&count), 3));
118 EXPECT_FALSE(cancelable.is_null());
119
120 // The stale copy of the cancelable callback is non-null.
121 ASSERT_FALSE(callback.is_null());
122
123 // The stale copy of the cancelable callback is no longer active.
124 callback.Run();
125 EXPECT_EQ(2, count);
126
127 base::Closure callback2 = cancelable.callback();
128 ASSERT_FALSE(callback2.is_null());
129
130 callback2.Run();
131 EXPECT_EQ(5, count);
132 }
133
134 // * Cancel() transforms the CancelableCallback into null.
135 TEST(CancelableCallbackTest, IsNull) {
136 CancelableCallback cancelable;
137 EXPECT_TRUE(cancelable.is_null());
138
139 int count = 0;
140 cancelable.Reset(base::Bind(Increment,
141 base::Unretained(&count)));
142 EXPECT_FALSE(cancelable.is_null());
143
144 cancelable.Cancel();
145 EXPECT_TRUE(cancelable.is_null());
146 }
147
148 // * Callbacks posted to a MessageLoop can be cancelled.
149 TEST(CancelableCallbackTest, PostTask) {
150 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
151
152 int count = 0;
153 CancelableCallback cancelable(base::Bind(Increment,
154 base::Unretained(&count)));
155
156 MessageLoop::current()->PostTask(FROM_HERE, cancelable.callback());
157 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
158 MessageLoop::current()->Run();
159
160 EXPECT_EQ(1, count);
161
162 MessageLoop::current()->PostTask(FROM_HERE, cancelable.callback());
163 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
164
165 // Cancel before running the message loop.
166 cancelable.Cancel();
167 MessageLoop::current()->Run();
168
169 // Callback never ran due to cancellation; count is the same.
170 EXPECT_EQ(1, count);
171 }
172
173 } // namespace
174 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698