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

Side by Side Diff: base/callback_registry_unittest.cc

Issue 24648002: Rename CallbackRegistry to CallbackList (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Doc fix Created 7 years, 2 months 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
« no previous file with comments | « base/callback_registry.h.pump ('k') | base/callback_registry_unittest.nc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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/callback_registry.h"
6
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace base {
14 namespace {
15
16 class Listener {
17 public:
18 Listener() : total_(0), scaler_(1) {}
19 explicit Listener(int scaler) : total_(0), scaler_(scaler) {}
20 void IncrementTotal() { total_++; }
21 void IncrementByMultipleOfScaler(int x) { total_ += x * scaler_; }
22
23 int total_;
24
25 private:
26 int scaler_;
27 DISALLOW_COPY_AND_ASSIGN(Listener);
28 };
29
30 class Remover {
31 public:
32 Remover() : total_(0) {}
33 void IncrementTotalAndRemove() {
34 total_++;
35 removal_subscription_.reset();
36 }
37 void SetSubscriptionToRemove(
38 scoped_ptr<CallbackRegistry<void(void)>::Subscription> sub) {
39 removal_subscription_ = sub.Pass();
40 }
41
42 int total_;
43
44 private:
45 scoped_ptr<CallbackRegistry<void(void)>::Subscription> removal_subscription_;
46 DISALLOW_COPY_AND_ASSIGN(Remover);
47 };
48
49 class Adder {
50 public:
51 explicit Adder(CallbackRegistry<void(void)>* cb_reg)
52 : added_(false),
53 total_(0),
54 cb_reg_(cb_reg) {}
55 void AddCallback() {
56 if (!added_) {
57 added_ = true;
58 subscription_ =
59 cb_reg_->Add(Bind(&Adder::IncrementTotal, Unretained(this)));
60 }
61 }
62 void IncrementTotal() { total_++; }
63
64 bool added_;
65 int total_;
66
67 private:
68 CallbackRegistry<void(void)>* cb_reg_;
69 scoped_ptr<CallbackRegistry<void(void)>::Subscription> subscription_;
70 DISALLOW_COPY_AND_ASSIGN(Adder);
71 };
72
73 class Summer {
74 public:
75 Summer() : value_(0) {}
76
77 void AddOneParam(int a) { value_ = a; }
78 void AddTwoParam(int a, int b) { value_ = a + b; }
79 void AddThreeParam(int a, int b, int c) { value_ = a + b + c; }
80 void AddFourParam(int a, int b, int c, int d) { value_ = a + b + c + d; }
81 void AddFiveParam(int a, int b, int c, int d, int e) {
82 value_ = a + b + c + d + e;
83 }
84 void AddSixParam(int a, int b, int c, int d, int e , int f) {
85 value_ = a + b + c + d + e + f;
86 }
87
88 int value_;
89
90 private:
91 DISALLOW_COPY_AND_ASSIGN(Summer);
92 };
93
94 // Sanity check that we can instantiate a CallbackRegistry for each arity.
95 TEST(CallbackRegistryTest, ArityTest) {
96 Summer s;
97
98 CallbackRegistry<void(int)> c1;
99 scoped_ptr<CallbackRegistry<void(int)>::Subscription> subscription1 =
100 c1.Add(Bind(&Summer::AddOneParam, Unretained(&s)));
101
102 c1.Notify(1);
103 EXPECT_EQ(1, s.value_);
104
105 CallbackRegistry<void(int, int)> c2;
106 scoped_ptr<CallbackRegistry<void(int, int)>::Subscription> subscription2 =
107 c2.Add(Bind(&Summer::AddTwoParam, Unretained(&s)));
108
109 c2.Notify(1, 2);
110 EXPECT_EQ(3, s.value_);
111
112 CallbackRegistry<void(int, int, int)> c3;
113 scoped_ptr<CallbackRegistry<void(int, int, int)>::Subscription>
114 subscription3 = c3.Add(Bind(&Summer::AddThreeParam, Unretained(&s)));
115
116 c3.Notify(1, 2, 3);
117 EXPECT_EQ(6, s.value_);
118
119 CallbackRegistry<void(int, int, int, int)> c4;
120 scoped_ptr<CallbackRegistry<void(int, int, int, int)>::Subscription>
121 subscription4 = c4.Add(Bind(&Summer::AddFourParam, Unretained(&s)));
122
123 c4.Notify(1, 2, 3, 4);
124 EXPECT_EQ(10, s.value_);
125
126 CallbackRegistry<void(int, int, int, int, int)> c5;
127 scoped_ptr<CallbackRegistry<void(int, int, int, int, int)>::Subscription>
128 subscription5 = c5.Add(Bind(&Summer::AddFiveParam, Unretained(&s)));
129
130 c5.Notify(1, 2, 3, 4, 5);
131 EXPECT_EQ(15, s.value_);
132
133 CallbackRegistry<void(int, int, int, int, int, int)> c6;
134 scoped_ptr<CallbackRegistry<void(int, int, int, int, int, int)>::Subscription>
135 subscription6 = c6.Add(Bind(&Summer::AddSixParam, Unretained(&s)));
136
137 c6.Notify(1, 2, 3, 4, 5, 6);
138 EXPECT_EQ(21, s.value_);
139 }
140
141 // Sanity check that closures added to the list will be run, and those removed
142 // from the list will not be run.
143 TEST(CallbackRegistryTest, BasicTest) {
144 CallbackRegistry<void(void)> cb_reg;
145 Listener a, b, c;
146
147 scoped_ptr<CallbackRegistry<void(void)>::Subscription> a_subscription =
148 cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&a)));
149 scoped_ptr<CallbackRegistry<void(void)>::Subscription> b_subscription =
150 cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&b)));
151
152 EXPECT_TRUE(a_subscription.get());
153 EXPECT_TRUE(b_subscription.get());
154
155 cb_reg.Notify();
156
157 EXPECT_EQ(1, a.total_);
158 EXPECT_EQ(1, b.total_);
159
160 b_subscription.reset();
161
162 scoped_ptr<CallbackRegistry<void(void)>::Subscription> c_subscription =
163 cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&c)));
164
165 cb_reg.Notify();
166
167 EXPECT_EQ(2, a.total_);
168 EXPECT_EQ(1, b.total_);
169 EXPECT_EQ(1, c.total_);
170
171 a_subscription.reset();
172 b_subscription.reset();
173 c_subscription.reset();
174 }
175
176 // Sanity check that callbacks with details added to the list will be run, with
177 // the correct details, and those removed from the list will not be run.
178 TEST(CallbackRegistryTest, BasicTestWithParams) {
179 CallbackRegistry<void(int)> cb_reg;
180 Listener a(1), b(-1), c(1);
181
182 scoped_ptr<CallbackRegistry<void(int)>::Subscription> a_subscription =
183 cb_reg.Add(Bind(&Listener::IncrementByMultipleOfScaler, Unretained(&a)));
184 scoped_ptr<CallbackRegistry<void(int)>::Subscription> b_subscription =
185 cb_reg.Add(Bind(&Listener::IncrementByMultipleOfScaler, Unretained(&b)));
186
187 EXPECT_TRUE(a_subscription.get());
188 EXPECT_TRUE(b_subscription.get());
189
190 cb_reg.Notify(10);
191
192 EXPECT_EQ(10, a.total_);
193 EXPECT_EQ(-10, b.total_);
194
195 b_subscription.reset();
196
197 scoped_ptr<CallbackRegistry<void(int)>::Subscription> c_subscription =
198 cb_reg.Add(Bind(&Listener::IncrementByMultipleOfScaler, Unretained(&c)));
199
200 cb_reg.Notify(10);
201
202 EXPECT_EQ(20, a.total_);
203 EXPECT_EQ(-10, b.total_);
204 EXPECT_EQ(10, c.total_);
205
206 a_subscription.reset();
207 b_subscription.reset();
208 c_subscription.reset();
209 }
210
211 // Test the a callback can remove itself or a different callback from the list
212 // during iteration without invalidating the iterator.
213 TEST(CallbackRegistryTest, RemoveCallbacksDuringIteration) {
214 CallbackRegistry<void(void)> cb_reg;
215 Listener a, b;
216 Remover remover_1, remover_2;
217
218 scoped_ptr<CallbackRegistry<void(void)>::Subscription> remover_1_sub =
219 cb_reg.Add(Bind(&Remover::IncrementTotalAndRemove,
220 Unretained(&remover_1)));
221 scoped_ptr<CallbackRegistry<void(void)>::Subscription> remover_2_sub =
222 cb_reg.Add(Bind(&Remover::IncrementTotalAndRemove,
223 Unretained(&remover_2)));
224 scoped_ptr<CallbackRegistry<void(void)>::Subscription> a_subscription =
225 cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&a)));
226 scoped_ptr<CallbackRegistry<void(void)>::Subscription> b_subscription =
227 cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&b)));
228
229 // |remover_1| will remove itself.
230 remover_1.SetSubscriptionToRemove(remover_1_sub.Pass());
231 // |remover_2| will remove a.
232 remover_2.SetSubscriptionToRemove(a_subscription.Pass());
233
234 cb_reg.Notify();
235
236 // |remover_1| runs once (and removes itself), |remover_2| runs once (and
237 // removes a), |a| never runs, and |b| runs once.
238 EXPECT_EQ(1, remover_1.total_);
239 EXPECT_EQ(1, remover_2.total_);
240 EXPECT_EQ(0, a.total_);
241 EXPECT_EQ(1, b.total_);
242
243 cb_reg.Notify();
244
245 // Only |remover_2| and |b| run this time.
246 EXPECT_EQ(1, remover_1.total_);
247 EXPECT_EQ(2, remover_2.total_);
248 EXPECT_EQ(0, a.total_);
249 EXPECT_EQ(2, b.total_);
250 }
251
252 // Test that a callback can add another callback to the list durning iteration
253 // without invalidating the iterator. The newly added callback should be run on
254 // the current iteration as will all other callbacks in the list.
255 TEST(CallbackRegistryTest, AddCallbacksDuringIteration) {
256 CallbackRegistry<void(void)> cb_reg;
257 Adder a(&cb_reg);
258 Listener b;
259 scoped_ptr<CallbackRegistry<void(void)>::Subscription> a_subscription =
260 cb_reg.Add(Bind(&Adder::AddCallback, Unretained(&a)));
261 scoped_ptr<CallbackRegistry<void(void)>::Subscription> b_subscription =
262 cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&b)));
263
264 cb_reg.Notify();
265
266 EXPECT_EQ(1, a.total_);
267 EXPECT_EQ(1, b.total_);
268 EXPECT_TRUE(a.added_);
269
270 cb_reg.Notify();
271
272 EXPECT_EQ(2, a.total_);
273 EXPECT_EQ(2, b.total_);
274 }
275
276 // Sanity check: notifying an empty list is a no-op.
277 TEST(CallbackRegistryTest, EmptyList) {
278 CallbackRegistry<void(void)> cb_reg;
279
280 cb_reg.Notify();
281 }
282
283 } // namespace
284 } // namespace base
OLDNEW
« no previous file with comments | « base/callback_registry.h.pump ('k') | base/callback_registry_unittest.nc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698