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

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: Moar. 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"
willchan no longer on Chromium 2011/11/24 00:44:30 goes first
James Hawkins 2011/11/24 02:47:48 I read (on either c-style or chromium-dev) that th
awong 2011/11/24 02:56:53 Will has caught me on this previously, but it does
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 // Cancel().
26 // - Callback can be run multiple times.
27 // - After Cancel(), Run() completes but has no effect.
28 TEST(CancelableCallbackTest, Cancel) {
29 int count = 0;
30 CancelableCallback cancelable(
31 base::Bind(Increment, base::Unretained(&count)));
32
33 base::Closure callback = cancelable.callback();
34 callback.Run();
35 EXPECT_EQ(1, count);
36
37 callback.Run();
38 EXPECT_EQ(2, count);
39
40 cancelable.Cancel();
41 callback.Run();
42 EXPECT_EQ(2, count);
43 }
44
45 // Cancel() called multiple times.
46 // - Cancel() cancels all copies of the wrapped callback.
47 TEST(CancelableCallbackTest, MultipleCancel) {
48 int count = 0;
49 CancelableCallback cancelable(
50 base::Bind(Increment, base::Unretained(&count)));
willchan no longer on Chromium 2011/11/24 00:44:30 I always forget, doesn't Increment need & before i
awong 2011/11/24 01:00:03 I had thought it did, but I have again learned tha
James Hawkins 2011/11/24 02:47:48 Hmm, I was really sure I've seen this fail to comp
awong 2011/11/24 02:56:53 I *know* I went through and fixed a bunch that fai
51
52 base::Closure callback1 = cancelable.callback();
53 cancelable.Cancel();
54
55 callback1.Run();
56 EXPECT_EQ(0, count);
57
58 base::Closure callback2 = cancelable.callback();
59 callback2.Run();
60 EXPECT_EQ(0, count);
61
62 // Cancel() should have no effect, but callback() is still runnable.
63 base::Closure callback3 = cancelable.callback();
64 cancelable.Cancel();
65 callback3.Run();
66 EXPECT_EQ(0, count);
67 }
68
69 // CancelableCallback destroyed before callback is run.
70 // - Destruction of CancelableCallback cancels outstanding callbacks.
71 TEST(CancelableCallbackTest, CallbackCanceledOnDestruction) {
72 int count = 0;
73 base::Closure callback;
74
75 {
76 CancelableCallback cancelable(
77 base::Bind(Increment, base::Unretained(&count)));
78
79 callback = cancelable.callback();
80 callback.Run();
81 EXPECT_EQ(1, count);
82 }
83
84 callback.Run();
85 EXPECT_EQ(1, count);
86 }
87
88 // Cancel() called on bound closure with a RefCounted parameter.
89 // - Cancel drops wrapped callback (and, implicitly, its bound arguments).
90 TEST(CancelableCallbackTest, CancelDropsCallback) {
91 scoped_refptr<TestRefCounted> ref_counted = new TestRefCounted;
92 EXPECT_TRUE(ref_counted->HasOneRef());
93
94 CancelableCallback cancelable(base::Bind(RefCountedParam, ref_counted));
95 EXPECT_FALSE(cancelable.IsCancelled());
96 EXPECT_TRUE(ref_counted.get());
97 EXPECT_FALSE(ref_counted->HasOneRef());
98
99 // There is only one reference to |ref_counted| after the Cancel().
100 cancelable.Cancel();
101 EXPECT_TRUE(cancelable.IsCancelled());
102 EXPECT_TRUE(ref_counted.get());
103 EXPECT_TRUE(ref_counted->HasOneRef());
104 }
105
106 // Reset().
107 // - Reset() replaces the existing wrapped callback with a new callback.
108 // - Reset() deactivates outstanding callbacks.
109 TEST(CancelableCallbackTest, Reset) {
110 int count = 0;
111 CancelableCallback cancelable(
112 base::Bind(Increment, base::Unretained(&count)));
113
114 base::Closure callback = cancelable.callback();
115 callback.Run();
116 EXPECT_EQ(1, count);
117
118 callback.Run();
119 EXPECT_EQ(2, count);
120
121 cancelable.Reset(
122 base::Bind(IncrementBy, base::Unretained(&count), 3));
123 EXPECT_FALSE(cancelable.IsCancelled());
124
125 // The stale copy of the cancelable callback is non-null.
126 ASSERT_FALSE(callback.is_null());
127
128 // The stale copy of the cancelable callback is no longer active.
129 callback.Run();
130 EXPECT_EQ(2, count);
131
132 base::Closure callback2 = cancelable.callback();
133 ASSERT_FALSE(callback2.is_null());
134
135 callback2.Run();
136 EXPECT_EQ(5, count);
137 }
138
139 // IsCanceled().
140 // - Cancel() transforms the CancelableCallback into a cancelled state.
141 TEST(CancelableCallbackTest, IsNull) {
142 CancelableCallback cancelable;
143 EXPECT_TRUE(cancelable.IsCancelled());
144
145 int count = 0;
146 cancelable.Reset(base::Bind(Increment,
147 base::Unretained(&count)));
148 EXPECT_FALSE(cancelable.IsCancelled());
149
150 cancelable.Cancel();
151 EXPECT_TRUE(cancelable.IsCancelled());
152 }
153
154 // CancelableCallback posted to a MessageLoop with PostTask.
155 // - Callbacks posted to a MessageLoop can be cancelled.
156 TEST(CancelableCallbackTest, PostTask) {
157 MessageLoop loop(MessageLoop::TYPE_DEFAULT);
158
159 int count = 0;
160 CancelableCallback cancelable(base::Bind(Increment,
161 base::Unretained(&count)));
162
163 MessageLoop::current()->PostTask(FROM_HERE, cancelable.callback());
164 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
165 MessageLoop::current()->Run();
166
167 EXPECT_EQ(1, count);
168
169 MessageLoop::current()->PostTask(FROM_HERE, cancelable.callback());
170 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
171
172 // Cancel before running the message loop.
173 cancelable.Cancel();
174 MessageLoop::current()->Run();
175
176 // Callback never ran due to cancellation; count is the same.
177 EXPECT_EQ(1, count);
178 }
179
180 } // namespace
181 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698