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

Side by Side Diff: cc/base/observer_map_unittest.cc

Issue 1337803002: cc: Adding BeginFrameObserverMap. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing windows compile. Created 5 years, 3 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
OLDNEW
(Empty)
1 // Copyright 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 "cc/base/observer_map.h"
6
7 #include <algorithm>
8
9 #include "base/basictypes.h"
10 #include "base/gtest_prod_util.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 // We use a macro here so that we get good line number information from gtest.
15 #define EXPECT_EMPTY(obmap) \
16 EXPECT_FALSE(obmap.HasObservers()); \
17 for (auto it = obmap.begin(); it != obmap.end(); it++) \
18 NOTREACHED(); \
19 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) \
20 NOTREACHED(); \
21 EXPECT_EQ(GetConstIterators(&obmap), 0U); \
22 EXPECT_EQ(GetIterators(&obmap), 0U);
23
24 namespace cc {
25
26 // This has to be in the same name space as ObserverMap so it is correctly
27 // friended.
28 class ObserverMapTest : public ::testing::Test {
29 public:
30 template <class ObserverType, class ObserverDataType>
31 size_t GetIterators(ObserverMap<ObserverType, ObserverDataType>* obmap) {
32 return obmap->iterators_;
33 }
34
35 template <class ObserverType, class ObserverDataType>
36 size_t GetConstIterators(ObserverMap<ObserverType, ObserverDataType>* obmap) {
37 return obmap->const_iterators_;
38 }
39 };
40
41 namespace {
42
43 class TestObserver {
44 public:
45 int observe_;
46
47 TestObserver() : observe_(0) {}
48 void Observe() { observe_++; }
49 int GetObserve() const { return observe_; }
50 };
51
52 struct TestObserverData {
53 TestObserverData() : data(0) {}
54
55 size_t data;
56 };
57
58 TEST_F(ObserverMapTest, Types) {
59 ::testing::StaticAssertTypeEq<
60 ObserverMap<TestObserver, TestObserverData>::const_iterator::value_type,
61 std::pair<TestObserver* const, TestObserverData*>>();
62 }
63
64 TEST_F(ObserverMapTest, MapInitiallyEmpty) {
65 ObserverMap<TestObserver, TestObserverData> obmap;
66 EXPECT_EMPTY(obmap);
67 }
68
69 TEST_F(ObserverMapTest, SingleObserver) {
70 size_t data_value1 = __LINE__;
71 size_t data_value2 = __LINE__;
72 ObserverMap<TestObserver, TestObserverData> obmap;
73 TestObserver obs1;
74
75 // Observer not added yet
76 EXPECT_FALSE(obmap.HasObserver(&obs1));
77 EXPECT_EQ(obmap[&obs1], nullptr);
78
79 // Add the observer
80 obmap.AddObserver(&obs1);
81 EXPECT_TRUE(obmap.HasObserver(&obs1));
82 EXPECT_TRUE(obmap.HasObservers());
83 EXPECT_EQ(obmap[&obs1]->data, 0U);
84
85 // Normal iterator
86 for (auto it = obmap.begin(); it != obmap.end(); it++) {
87 EXPECT_EQ(GetIterators(&obmap), 1U);
88 EXPECT_EQ(GetConstIterators(&obmap), 0U);
89 EXPECT_EQ(&obs1, it->first);
90 it->second->data = data_value1;
91 }
92 EXPECT_EQ(GetIterators(&obmap), 0U);
93 EXPECT_EQ(obmap[&obs1]->data, data_value1);
94 // const iterator
95 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
96 EXPECT_EQ(GetIterators(&obmap), 0U);
97 EXPECT_EQ(GetConstIterators(&obmap), 1U);
98 EXPECT_EQ(&obs1, it->first);
99 EXPECT_EQ(it->second->data, data_value1);
100 }
101 EXPECT_EQ(GetConstIterators(&obmap), 0U);
102 // Nested iterators
103 for (auto it = obmap.begin(); it != obmap.end(); it++) {
104 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
105 EXPECT_EQ(GetIterators(&obmap), 2U);
106 EXPECT_EQ(GetConstIterators(&obmap), 0U);
107 EXPECT_EQ(&obs1, it->first);
108 it->second->data = data_value2;
109 }
110 EXPECT_EQ(GetIterators(&obmap), 1U);
111 }
112 EXPECT_EQ(GetIterators(&obmap), 0U);
113 EXPECT_EQ(obmap[&obs1]->data, data_value2);
114 // Nested const iterator
115 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
116 for (auto jt = obmap.cbegin(); jt != obmap.cend(); jt++) {
117 EXPECT_EQ(GetIterators(&obmap), 0U);
118 EXPECT_EQ(GetConstIterators(&obmap), 2U);
119 EXPECT_EQ(&obs1, jt->first);
120 EXPECT_EQ(jt->second->data, data_value2);
121 }
122 EXPECT_EQ(GetConstIterators(&obmap), 1U);
123 }
124 EXPECT_EQ(GetConstIterators(&obmap), 0U);
125
126 // Remove the observer
127 obmap.RemoveObserver(&obs1);
128 EXPECT_EMPTY(obmap);
129 }
130
131 TEST_F(ObserverMapTest, TwoObservers) {
132 size_t data_value1 = __LINE__;
133 size_t data_value2 = __LINE__;
134 size_t data_value3 = __LINE__;
135 ObserverMap<TestObserver, TestObserverData> obmap;
136 TestObserver obs1;
137 TestObserver obs2;
138
139 obmap.AddObserver(&obs1);
140 EXPECT_TRUE(obmap.HasObserver(&obs1));
141 obmap.AddObserver(&obs2);
142 EXPECT_TRUE(obmap.HasObserver(&obs2));
143
144 EXPECT_TRUE(obmap.HasObservers());
145 // Normal iterator
146 for (auto it = obmap.begin(); it != obmap.end(); it++) {
147 EXPECT_EQ(GetIterators(&obmap), 1U);
148 EXPECT_EQ(GetConstIterators(&obmap), 0U);
149 EXPECT_EQ(it->second->data, 0U);
150 it->second->data = data_value1;
151 }
152 EXPECT_EQ(GetIterators(&obmap), 0U);
153 // const iterator
154 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
155 EXPECT_EQ(GetIterators(&obmap), 0U);
156 EXPECT_EQ(GetConstIterators(&obmap), 1U);
157 EXPECT_EQ(it->second->data, data_value1);
158 }
159 EXPECT_EQ(GetConstIterators(&obmap), 0U);
160 // operator[]
161 EXPECT_EQ(obmap[&obs1]->data, data_value1);
162 EXPECT_EQ(obmap[&obs2]->data, data_value1);
163
164 // Nested iterators
165 for (auto it = obmap.begin(); it != obmap.end(); it++) {
166 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
167 EXPECT_EQ(GetIterators(&obmap), 2U);
168 EXPECT_EQ(GetConstIterators(&obmap), 0U);
169 it->second->data = data_value2;
170 }
171 EXPECT_EQ(GetIterators(&obmap), 1U);
172 }
173 EXPECT_EQ(GetIterators(&obmap), 0U);
174 // Nested const iterator
175 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
176 for (auto jt = obmap.cbegin(); jt != obmap.cend(); jt++) {
177 EXPECT_EQ(GetIterators(&obmap), 0U);
178 EXPECT_EQ(GetConstIterators(&obmap), 2U);
179 EXPECT_EQ(jt->second->data, data_value2);
180 }
181 EXPECT_EQ(GetConstIterators(&obmap), 1U);
182 }
183 EXPECT_EQ(GetConstIterators(&obmap), 0U);
184
185 // Remove a single observer
186 obmap.RemoveObserver(&obs2);
187
188 // Repeat the above
189 EXPECT_TRUE(obmap.HasObservers());
190 // Normal iterator
191 for (auto it = obmap.begin(); it != obmap.end(); it++) {
192 EXPECT_EQ(it->second->data, data_value2);
193 it->second->data = data_value3;
194 }
195 // const iterator
196 for (auto it = obmap.begin(); it != obmap.end(); it++) {
197 EXPECT_EQ(it->second->data, data_value3);
198 }
199 // operator[]
200 EXPECT_EQ(obmap[&obs1]->data, data_value3);
201 EXPECT_EQ(obmap[&obs2], nullptr);
202
203 // Remove the other observer
204 obmap.RemoveObserver(&obs1);
205 EXPECT_EMPTY(obmap);
206 }
207
208 TEST_F(ObserverMapTest, AddWhileIterating) {
209 size_t data_value1 = __LINE__;
210 ObserverMap<TestObserver, TestObserverData> obmap;
211 TestObserver obs1;
212 TestObserver obs2;
213 TestObserver obs3;
214 obmap.AddObserver(&obs1);
215 obmap.AddObserver(&obs3);
216
217 obmap[&obs1]->data = data_value1;
218 obmap[&obs3]->data = data_value1;
219
220 int i = 1;
221 for (auto it = obmap.begin(); it != obmap.end(); it++, i++) {
222 // Calling add twice while iterating should be safe
223 obmap.AddObserver(&obs2);
224 // Should be able to access the data right after adding.
225 EXPECT_TRUE(obmap.HasObserver(&obs2));
226 obmap[&obs2]->data = i;
227 }
228 EXPECT_TRUE(obmap.HasObservers());
229
230 EXPECT_EQ(obmap[&obs1]->data, data_value1);
231 EXPECT_EQ(obmap[&obs2]->data, 2U);
232 EXPECT_EQ(obmap[&obs3]->data, data_value1);
233 }
234
235 TEST_F(ObserverMapTest, RemoveOneWhileIterating) {
236 size_t data_value1 = __LINE__;
237 ObserverMap<TestObserver, TestObserverData> obmap;
238 TestObserver obs1;
239 TestObserver obs2;
240 TestObserver obs3;
241 obmap.AddObserver(&obs1);
242 obmap.AddObserver(&obs2);
243 obmap.AddObserver(&obs3);
244
245 obmap[&obs1]->data = data_value1;
246 obmap[&obs2]->data = data_value1;
247 obmap[&obs3]->data = data_value1;
248
249 for (auto it = obmap.begin(); it != obmap.end(); it++) {
250 obmap.RemoveObserver(&obs2);
251 // Observer doesn't go away until the iteration is finished...
252 EXPECT_TRUE(obmap.HasObserver(&obs2));
253 }
254 EXPECT_FALSE(obmap.HasObserver(&obs2));
255 EXPECT_TRUE(obmap.HasObservers());
256
257 EXPECT_EQ(obmap[&obs1]->data, data_value1);
258 EXPECT_EQ(obmap[&obs2], nullptr);
259 EXPECT_EQ(obmap[&obs3]->data, data_value1);
260 }
261
262 TEST_F(ObserverMapTest, NestedRemoveOneWhileIterating) {
263 size_t data_value1 = __LINE__;
264 ObserverMap<TestObserver, TestObserverData> obmap;
265 TestObserver obs1;
266 TestObserver obs2;
267 TestObserver obs3;
268 obmap.AddObserver(&obs1);
269 obmap.AddObserver(&obs2);
270 obmap.AddObserver(&obs3);
271
272 obmap[&obs1]->data = data_value1;
273 obmap[&obs2]->data = data_value1;
274 obmap[&obs3]->data = data_value1;
275
276 for (auto it = obmap.begin(); it != obmap.end(); it++) {
277 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
278 obmap.RemoveObserver(&obs2);
279 }
280 }
281 EXPECT_TRUE(obmap.HasObservers());
282
283 EXPECT_EQ(obmap[&obs1]->data, data_value1);
284 EXPECT_EQ(obmap[&obs2], nullptr);
285 EXPECT_EQ(obmap[&obs3]->data, data_value1);
286 }
287
288 TEST_F(ObserverMapTest, RemoveAllWhileIterating) {
289 ObserverMap<TestObserver, TestObserverData> obmap;
290 TestObserver obs1;
291 TestObserver obs2;
292 TestObserver obs3;
293 obmap.AddObserver(&obs1);
294 obmap.AddObserver(&obs2);
295
296 for (auto it = obmap.begin(); it != obmap.end(); it++) {
297 obmap.RemoveObserver(it->first);
298 }
299 EXPECT_EMPTY(obmap);
300 }
301
302 TEST_F(ObserverMapTest, NestedRemoveAllWhileIterating) {
303 ObserverMap<TestObserver, TestObserverData> obmap;
304 TestObserver obs1;
305 TestObserver obs2;
306 TestObserver obs3;
307 obmap.AddObserver(&obs1);
308 obmap.AddObserver(&obs2);
309
310 for (auto it = obmap.begin(); it != obmap.end(); it++) {
311 for (auto jt = obmap.begin(); jt != obmap.end(); jt++) {
312 obmap.RemoveObserver(jt->first);
313 }
314 }
315 EXPECT_EMPTY(obmap);
316 }
317
318 TEST_F(ObserverMapTest, AttemptToRemoveWhileConstIterating) {
319 ObserverMap<TestObserver, TestObserverData> obmap;
320 TestObserver obs1;
321 TestObserver obs2;
322 obmap.AddObserver(&obs1);
323 obmap.AddObserver(&obs2);
324
325 EXPECT_DEATH({
326 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
327 obmap.RemoveObserver(const_cast<TestObserver*>(it->first));
328 }
329 }, "");
330
331 const ObserverMap<TestObserver, TestObserverData>* cobmap = &obmap;
332 EXPECT_DEATH({
333 for (auto it = cobmap->begin(); it != cobmap->end(); it++) {
334 obmap.RemoveObserver(const_cast<TestObserver*>(it->first));
335 }
336 }, "");
337 }
338
339 TEST_F(ObserverMapTest, AttemptToAddWhileConstIterating) {
340 ObserverMap<TestObserver, TestObserverData> obmap;
341 TestObserver obs1;
342 TestObserver obs2;
343 TestObserver obs3;
344 obmap.AddObserver(&obs1);
345 obmap.AddObserver(&obs2);
346
347 EXPECT_DEATH({
348 for (auto it = obmap.cbegin(); it != obmap.cend(); it++) {
349 obmap.AddObserver(&obs3);
350 }
351 }, "");
352
353 const ObserverMap<TestObserver, TestObserverData>* cobmap = &obmap;
354 EXPECT_DEATH({
355 for (auto it = cobmap->begin(); it != cobmap->end(); it++) {
356 obmap.AddObserver(&obs3);
357 }
358 }, "");
359 }
360
361 struct TestObserverOwner {
362 TestObserverOwner() : ob1(), ob2(), obmap() {}
363
364 TestObserver ob1;
365 TestObserver ob2;
366 ObserverMap<TestObserver, TestObserverData> obmap;
367
368 void Notify() {
369 for (auto it = obmap.begin(); it != obmap.end(); it++) {
370 it->first->Observe();
371 }
372 }
373
374 int LargestObserver() const {
375 int largest = 0;
376 for (auto it = obmap.begin(); it != obmap.end(); it++) {
377 largest = std::max(largest, it->first->GetObserve());
378 }
379 return largest;
380 }
381 size_t LargestData() const {
382 size_t largest1 = 0;
383 size_t largest2 = 0;
384 for (auto it = obmap.begin(); it != obmap.end(); it++) {
385 largest1 = std::max(largest1, it->second->data);
386 largest2 = std::max(largest2, obmap[it->first]->data);
387 }
388 DCHECK_EQ(largest1, largest2);
389 return largest1;
390 }
391 };
392
393 TEST_F(ObserverMapTest, ObserverOwner) {
394 TestObserverOwner owner;
395
396 owner.Notify();
397 EXPECT_EQ(owner.LargestObserver(), 0);
398 EXPECT_EQ(owner.LargestData(), 0U);
399
400 owner.obmap.AddObserver(&owner.ob1);
401 owner.Notify();
402 EXPECT_EQ(owner.LargestObserver(), 1);
403 EXPECT_EQ(owner.LargestData(), 0U);
404
405 owner.obmap[&owner.ob1]->data = 2;
406 EXPECT_EQ(owner.LargestObserver(), 1);
407 EXPECT_EQ(owner.LargestData(), 2U);
408
409 owner.obmap.AddObserver(&owner.ob2);
410 EXPECT_EQ(owner.LargestObserver(), 1);
411 EXPECT_EQ(owner.LargestData(), 2U);
412 owner.Notify();
413 owner.Notify();
414 EXPECT_EQ(owner.LargestObserver(), 3);
415 EXPECT_EQ(owner.LargestData(), 2U);
416
417 owner.obmap[&owner.ob2]->data = 5;
418 EXPECT_EQ(owner.LargestObserver(), 3);
419 EXPECT_EQ(owner.LargestData(), 5U);
420
421 owner.obmap.RemoveObserver(&owner.ob1);
422 EXPECT_EQ(owner.LargestObserver(), 2);
423 EXPECT_EQ(owner.LargestData(), 5U);
424 }
425
426 } // namespace
427 } // namespace cc
OLDNEW
« cc/base/observer_map.h ('K') | « cc/base/observer_map.h ('k') | cc/cc.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698