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

Side by Side Diff: ui/events/platform/platform_event_source_unittest.cc

Issue 203483004: events: Introduce PlatformEventDispatcher and PlatformEventSource. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tests Created 6 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "ui/events/platform/platform_event_source.h"
6
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/events/platform/platform_event_dispatcher.h"
14 #include "ui/events/platform/platform_event_observer.h"
15 #include "ui/events/platform/scoped_event_dispatcher.h"
16
17 namespace ui {
18
19 namespace {
20
21 scoped_ptr<PlatformEvent> CreatePlatformEvent() {
22 scoped_ptr<PlatformEvent> event(new PlatformEvent());
23 memset(event.get(), 0, sizeof(PlatformEvent));
24 return event.Pass();
25 }
26
27 template <typename T>
28 void DestroyScopedPtr(scoped_ptr<T> object) {}
29
30 } // namespace
31
32 class TestPlatformEventSource : public PlatformEventSource {
33 public:
34 TestPlatformEventSource() {}
35 virtual ~TestPlatformEventSource() {}
36
37 uint32_t Dispatch(const PlatformEvent& event) { return DispatchEvent(event); }
38
39 private:
40 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventSource);
41 };
42
43 class TestPlatformEventDispatcher : public PlatformEventDispatcher {
44 public:
45 TestPlatformEventDispatcher(int id, std::vector<int>* list)
46 : id_(id), list_(list), post_dispatch_action_(POST_DISPATCH_NONE) {
47 PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
48 }
49 virtual ~TestPlatformEventDispatcher() {
50 PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
51 }
52
53 void set_post_dispatch_action(uint32_t action) {
54 post_dispatch_action_ = action;
55 }
56
57 protected:
58 // PlatformEventDispatcher:
59 virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE {
60 return true;
61 }
62
63 virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
64 list_->push_back(id_);
65 return post_dispatch_action_;
66 }
67
68 private:
69 int id_;
70 std::vector<int>* list_;
71 uint32_t post_dispatch_action_;
72
73 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventDispatcher);
74 };
75
76 class TestPlatformEventObserver : public PlatformEventObserver {
77 public:
78 TestPlatformEventObserver(int id, std::vector<int>* list)
79 : id_(id), list_(list), consume_event_(false) {
80 PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
81 }
82 virtual ~TestPlatformEventObserver() {
83 PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
84 }
85
86 void set_consume_event(bool consume) { consume_event_ = consume; }
87
88 protected:
89 // PlatformEventObserver:
90 virtual bool WillProcessEvent(const PlatformEvent& event) OVERRIDE {
91 list_->push_back(id_);
92 return consume_event_;
93 }
94
95 virtual void DidProcessEvent(const PlatformEvent& event) OVERRIDE {}
96
97 private:
98 int id_;
99 std::vector<int>* list_;
100 bool consume_event_;
101
102 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventObserver);
103 };
104
105 class PlatformEventTest : public testing::Test {
106 public:
107 PlatformEventTest() {}
108 virtual ~PlatformEventTest() {}
109
110 TestPlatformEventSource* source() { return source_.get(); }
111
112 protected:
113 // testing::Test:
114 virtual void SetUp() OVERRIDE {
115 source_.reset(new TestPlatformEventSource());
116 }
117
118 private:
119 scoped_ptr<TestPlatformEventSource> source_;
120
121 DISALLOW_COPY_AND_ASSIGN(PlatformEventTest);
122 };
123
124 // Tests that a dispatcher receives an event.
125 TEST_F(PlatformEventTest, DispatcherBasic) {
126 std::vector<int> list_dispatcher;
127 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
128 source()->Dispatch(*event);
129 EXPECT_EQ(0u, list_dispatcher.size());
130 {
131 TestPlatformEventDispatcher dispatcher(1, &list_dispatcher);
132
133 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
134 source()->Dispatch(*event);
135 ASSERT_EQ(1u, list_dispatcher.size());
136 EXPECT_EQ(1, list_dispatcher[0]);
137 }
138
139 list_dispatcher.clear();
140 event = CreatePlatformEvent();
141 source()->Dispatch(*event);
142 EXPECT_EQ(0u, list_dispatcher.size());
143 }
144
145 // Tests that dispatchers receive events in the correct order.
146 TEST_F(PlatformEventTest, DispatcherOrder) {
147 std::vector<int> list_dispatcher;
148 int sequence[] = {21, 3, 6, 45};
149 ScopedVector<TestPlatformEventDispatcher> dispatchers;
150 for (size_t i = 0; i < arraysize(sequence); ++i) {
151 dispatchers.push_back(
152 new TestPlatformEventDispatcher(sequence[i], &list_dispatcher));
153 }
154 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
155 source()->Dispatch(*event);
156 ASSERT_EQ(arraysize(sequence), list_dispatcher.size());
157 EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)),
158 list_dispatcher);
159 }
160
161 // Tests that if a dispatcher consumes the event, the subsequent dispatchers do
162 // not receive the event.
163 TEST_F(PlatformEventTest, DispatcherConsumesEventToStopDispatch) {
164 std::vector<int> list_dispatcher;
165 TestPlatformEventDispatcher first(12, &list_dispatcher);
166 TestPlatformEventDispatcher second(23, &list_dispatcher);
167
168 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
169 source()->Dispatch(*event);
170 ASSERT_EQ(2u, list_dispatcher.size());
171 EXPECT_EQ(12, list_dispatcher[0]);
172 EXPECT_EQ(23, list_dispatcher[1]);
173 list_dispatcher.clear();
174
175 first.set_post_dispatch_action(POST_DISPATCH_STOP_PROPAGATION);
176 event = CreatePlatformEvent();
177 source()->Dispatch(*event);
178 ASSERT_EQ(1u, list_dispatcher.size());
179 EXPECT_EQ(12, list_dispatcher[0]);
180 }
181
182 // Tests that observers receive events.
183 TEST_F(PlatformEventTest, ObserverBasic) {
184 std::vector<int> list_observer;
185 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
186 source()->Dispatch(*event);
187 EXPECT_EQ(0u, list_observer.size());
188 {
189 TestPlatformEventObserver observer(31, &list_observer);
190
191 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
192 source()->Dispatch(*event);
193 ASSERT_EQ(1u, list_observer.size());
194 EXPECT_EQ(31, list_observer[0]);
195 }
196
197 list_observer.clear();
198 event = CreatePlatformEvent();
199 source()->Dispatch(*event);
200 EXPECT_EQ(0u, list_observer.size());
201 }
202
203 // Tests that observers receive events in the correct order.
204 TEST_F(PlatformEventTest, ObserverOrder) {
205 std::vector<int> list_observer;
206 const int sequence[] = {21, 3, 6, 45};
207 ScopedVector<TestPlatformEventObserver> observers;
208 for (size_t i = 0; i < arraysize(sequence); ++i) {
209 observers.push_back(
210 new TestPlatformEventObserver(sequence[i], &list_observer));
211 }
212 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
213 source()->Dispatch(*event);
214 ASSERT_EQ(arraysize(sequence), list_observer.size());
215 EXPECT_EQ(std::vector<int>(sequence, sequence + arraysize(sequence)),
216 list_observer);
217 }
218
219 // Tests that observers and dispatchers receive events in the correct order.
220 TEST_F(PlatformEventTest, DispatcherAndObserverOrder) {
221 std::vector<int> list;
222 TestPlatformEventDispatcher first_d(12, &list);
223 TestPlatformEventObserver first_o(10, &list);
224 TestPlatformEventDispatcher second_d(23, &list);
225 TestPlatformEventObserver second_o(20, &list);
226 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
227 source()->Dispatch(*event);
228 const int expected[] = {10, 20, 12, 23};
229 EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list);
230 }
231
232 // Tests that an observer can consume an event and stop its dispatch.
233 TEST_F(PlatformEventTest, ObserverConsumesEventToStopDispatch) {
234 std::vector<int> list;
235 TestPlatformEventDispatcher first_d(12, &list);
236 TestPlatformEventObserver first_o(10, &list);
237 TestPlatformEventDispatcher second_d(23, &list);
238 TestPlatformEventObserver second_o(20, &list);
239 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
240 source()->Dispatch(*event);
241 const int expected[] = {10, 20, 12, 23};
242 EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list);
243
244 list.clear();
245 first_o.set_consume_event(true);
246 event = CreatePlatformEvent();
247 source()->Dispatch(*event);
248 ASSERT_EQ(1u, list.size());
249 EXPECT_EQ(10, list[0]);
250 }
251
252 // Tests that an overridden dispatcher receives events before the default
253 // dispatchers.
254 TEST_F(PlatformEventTest, OverriddenDispatcherBasic) {
255 std::vector<int> list;
256 TestPlatformEventDispatcher dispatcher(10, &list);
257 TestPlatformEventObserver observer(15, &list);
258 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
259 source()->Dispatch(*event);
260 ASSERT_EQ(2u, list.size());
261 EXPECT_EQ(15, list[0]);
262 EXPECT_EQ(10, list[1]);
263 list.clear();
264
265 TestPlatformEventDispatcher overriding_dispatcher(20, &list);
266 source()->RemovePlatformEventDispatcher(&overriding_dispatcher);
267 scoped_ptr<ScopedEventDispatcher> handle =
268 source()->OverrideDispatcher(&overriding_dispatcher);
269 source()->Dispatch(*event);
270 ASSERT_EQ(2u, list.size());
271 EXPECT_EQ(15, list[0]);
272 EXPECT_EQ(20, list[1]);
273 }
274
275 // Tests that an overridden dispatcher can request that the default dispatchers
276 // can dispatch the events.
277 TEST_F(PlatformEventTest, OverriddenDispatcherInvokeDefaultDispatcher) {
278 std::vector<int> list;
279 TestPlatformEventDispatcher dispatcher(10, &list);
280 TestPlatformEventObserver observer(15, &list);
281 TestPlatformEventDispatcher overriding_dispatcher(20, &list);
282 source()->RemovePlatformEventDispatcher(&overriding_dispatcher);
283 scoped_ptr<ScopedEventDispatcher> handle =
284 source()->OverrideDispatcher(&overriding_dispatcher);
285 overriding_dispatcher.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT);
286
287 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
288 source()->Dispatch(*event);
289 // First the observer, then the overriding dispatcher, then the default
290 // dispatcher.
291 ASSERT_EQ(3u, list.size());
292 EXPECT_EQ(15, list[0]);
293 EXPECT_EQ(20, list[1]);
294 EXPECT_EQ(10, list[2]);
295 list.clear();
296
297 // Install a second overriding dispatcher.
298 TestPlatformEventDispatcher second_overriding(50, &list);
299 source()->RemovePlatformEventDispatcher(&second_overriding);
300 scoped_ptr<ScopedEventDispatcher> second_override_handle =
301 source()->OverrideDispatcher(&second_overriding);
302 source()->Dispatch(*event);
303 ASSERT_EQ(2u, list.size());
304 EXPECT_EQ(15, list[0]);
305 EXPECT_EQ(50, list[1]);
306 list.clear();
307
308 second_overriding.set_post_dispatch_action(POST_DISPATCH_PERFORM_DEFAULT);
309 source()->Dispatch(*event);
310 // First the observer, then the second overriding dispatcher, then the default
311 // dispatcher.
312 ASSERT_EQ(3u, list.size());
313 EXPECT_EQ(15, list[0]);
314 EXPECT_EQ(50, list[1]);
315 EXPECT_EQ(10, list[2]);
316 }
317
318 // Provides mechanism for running tests from inside an active message-loop.
319 class PlatformEventTestWithMessageLoop : public PlatformEventTest {
320 public:
321 PlatformEventTestWithMessageLoop() {}
322 virtual ~PlatformEventTestWithMessageLoop() {}
323
324 void Run() {
325 message_loop_.PostTask(
326 FROM_HERE,
327 base::Bind(&PlatformEventTestWithMessageLoop::RunTest,
328 base::Unretained(this)));
329 message_loop_.Run();
330 }
331
332 protected:
333 void RunTest() {
334 RunTestImpl();
335 message_loop_.Quit();
336 }
337
338 virtual void RunTestImpl() = 0;
339
340 private:
341 base::MessageLoopForUI message_loop_;
342
343 DISALLOW_COPY_AND_ASSIGN(PlatformEventTestWithMessageLoop);
344 };
345
346 #define RUN_TEST_IN_MESSAGE_LOOP(name) \
347 TEST_F(name, Run) { Run(); }
348
349 // Tests that a ScopedEventDispatcher restores the previous dispatcher when
350 // destroyed.
351 class ScopedDispatcherRestoresAfterDestroy
352 : public PlatformEventTestWithMessageLoop {
353 public:
354 // PlatformEventTestWithMessageLoop:
355 virtual void RunTestImpl() OVERRIDE {
356 std::vector<int> list;
357 TestPlatformEventDispatcher dispatcher(10, &list);
358 TestPlatformEventObserver observer(15, &list);
359
360 TestPlatformEventDispatcher first_overriding(20, &list);
361 source()->RemovePlatformEventDispatcher(&first_overriding);
362 scoped_ptr<ScopedEventDispatcher> first_override_handle =
363 source()->OverrideDispatcher(&first_overriding);
364
365 // Install a second overriding dispatcher.
366 TestPlatformEventDispatcher second_overriding(50, &list);
367 source()->RemovePlatformEventDispatcher(&second_overriding);
368 scoped_ptr<ScopedEventDispatcher> second_override_handle =
369 source()->OverrideDispatcher(&second_overriding);
370
371 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
372 source()->Dispatch(*event);
373 ASSERT_EQ(2u, list.size());
374 EXPECT_EQ(15, list[0]);
375 EXPECT_EQ(50, list[1]);
376 list.clear();
377
378 second_override_handle.reset();
379 source()->Dispatch(*event);
380 ASSERT_EQ(2u, list.size());
381 EXPECT_EQ(15, list[0]);
382 EXPECT_EQ(20, list[1]);
383 }
384 };
385
386 RUN_TEST_IN_MESSAGE_LOOP(ScopedDispatcherRestoresAfterDestroy)
387
388 // This dispatcher destroys the handle to the ScopedEventDispatcher when
389 // dispatching an event.
390 class DestroyScopedHandleDispatcher : public TestPlatformEventDispatcher {
391 public:
392 DestroyScopedHandleDispatcher(int id, std::vector<int>* list)
393 : TestPlatformEventDispatcher(id, list) {}
394 virtual ~DestroyScopedHandleDispatcher() {}
395
396 void SetScopedHandle(scoped_ptr<ScopedEventDispatcher> handler) {
397 handler_ = handler.Pass();
398 }
399
400 private:
401 // PlatformEventDispatcher:
402 virtual bool CanDispatchEvent(const PlatformEvent& event) OVERRIDE {
403 return true;
404 }
405
406 virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
407 handler_.reset();
408 return TestPlatformEventDispatcher::DispatchEvent(event);
409 }
410
411 scoped_ptr<ScopedEventDispatcher> handler_;
412
413 DISALLOW_COPY_AND_ASSIGN(DestroyScopedHandleDispatcher);
414 };
415
416 // Tests that resetting an overridden dispatcher causes the nested message-loop
417 // to terminate.
418 class DestroyedNestedOverriddenDispatcherQuitsNestedLoop
419 : public PlatformEventTestWithMessageLoop {
420 public:
421 void NestedTask(std::vector<int>* list) {
422 // Dispatch an event. This will cause the ScopedEventDispatcher to be
423 // destroyed, which causes the nested loop to terminate.
424 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
425 source()->Dispatch(*event);
426 ASSERT_EQ(2u, list->size());
427 EXPECT_EQ(15, (*list)[0]);
428 EXPECT_EQ(20, (*list)[1]);
429 list->clear();
430 }
431
432 // PlatformEventTestWithMessageLoop:
433 virtual void RunTestImpl() OVERRIDE {
434 std::vector<int> list;
435 TestPlatformEventDispatcher dispatcher(10, &list);
436 TestPlatformEventObserver observer(15, &list);
437
438 DestroyScopedHandleDispatcher overriding(20, &list);
439 source()->RemovePlatformEventDispatcher(&overriding);
440 scoped_ptr<ScopedEventDispatcher> override_handle =
441 source()->OverrideDispatcher(&overriding);
442
443 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
444 source()->Dispatch(*event);
445 ASSERT_EQ(2u, list.size());
446 EXPECT_EQ(15, list[0]);
447 EXPECT_EQ(20, list[1]);
448 list.clear();
449
450 overriding.SetScopedHandle(override_handle.Pass());
451 base::RunLoop run_loop;
452 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
453 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
454 loop->PostTask(
455 FROM_HERE,
456 base::Bind(
457 &DestroyedNestedOverriddenDispatcherQuitsNestedLoop::NestedTask,
458 base::Unretained(this),
459 base::Unretained(&list)));
460 run_loop.Run();
461
462 // Dispatching the event should now reach the default dispatcher.
463 source()->Dispatch(*event);
464 ASSERT_EQ(2u, list.size());
465 EXPECT_EQ(15, list[0]);
466 EXPECT_EQ(10, list[1]);
467 }
468 };
469
470 RUN_TEST_IN_MESSAGE_LOOP(DestroyedNestedOverriddenDispatcherQuitsNestedLoop)
471
472 // Tests that resetting an overridden dispatcher, and installing another
473 // overridden dispatcher before the nested message-loop completely unwinds
474 // function correctly.
475 class ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration
476 : public PlatformEventTestWithMessageLoop {
477 public:
478 void NestedTask(scoped_ptr<ScopedEventDispatcher> dispatch_handle,
479 std::vector<int>* list) {
480 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
481 source()->Dispatch(*event);
482 ASSERT_EQ(2u, list->size());
483 EXPECT_EQ(15, (*list)[0]);
484 EXPECT_EQ(20, (*list)[1]);
485 list->clear();
486
487 dispatch_handle.reset();
488 source()->Dispatch(*event);
489 ASSERT_EQ(2u, list->size());
490 EXPECT_EQ(15, (*list)[0]);
491 EXPECT_EQ(10, (*list)[1]);
492 list->clear();
493
494 // Install another override-dispatcher.
495 DestroyScopedHandleDispatcher second_overriding(70, list);
496 source()->RemovePlatformEventDispatcher(&second_overriding);
497 scoped_ptr<ScopedEventDispatcher> second_override_handle =
498 source()->OverrideDispatcher(&second_overriding);
499
500 source()->Dispatch(*event);
501 ASSERT_EQ(2u, list->size());
502 EXPECT_EQ(15, (*list)[0]);
503 EXPECT_EQ(70, (*list)[1]);
504 list->clear();
505
506 second_overriding.SetScopedHandle(second_override_handle.Pass());
507 base::RunLoop run_loop;
508 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
509 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
510 loop->PostTask(
511 FROM_HERE,
512 base::Bind(base::IgnoreResult(&TestPlatformEventSource::Dispatch),
513 base::Unretained(source()),
514 *event));
515 run_loop.Run();
516 list->clear();
517 }
518
519 // PlatformEventTestWithMessageLoop:
520 virtual void RunTestImpl() OVERRIDE {
521 std::vector<int> list;
522 TestPlatformEventDispatcher dispatcher(10, &list);
523 TestPlatformEventObserver observer(15, &list);
524
525 TestPlatformEventDispatcher overriding(20, &list);
526 source()->RemovePlatformEventDispatcher(&overriding);
527 scoped_ptr<ScopedEventDispatcher> override_handle =
528 source()->OverrideDispatcher(&overriding);
529
530 scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
531 source()->Dispatch(*event);
532 ASSERT_EQ(2u, list.size());
533 EXPECT_EQ(15, list[0]);
534 EXPECT_EQ(20, list[1]);
535 list.clear();
536
537 // Start a nested message-loop, and destroy |override_handle| in the nested
538 // loop. That should terminate the nested loop, restore the previous
539 // dispatchers, and return control to this function.
540 base::RunLoop run_loop;
541 base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
542 base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
543 loop->PostTask(
544 FROM_HERE,
545 base::Bind(
546 &ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration::
547 NestedTask,
548 base::Unretained(this),
549 base::Passed(&override_handle),
550 base::Unretained(&list)));
551 run_loop.Run();
552
553 // Dispatching the event should now reach the default dispatcher.
554 source()->Dispatch(*event);
555 ASSERT_EQ(2u, list.size());
556 EXPECT_EQ(15, list[0]);
557 EXPECT_EQ(10, list[1]);
558 }
559 };
560
561 RUN_TEST_IN_MESSAGE_LOOP(
562 ConsecutiveOverriddenDispatcherInTheSameMessageLoopIteration)
563
564 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698