Drive: Add BatchableRequest subclass.
[chromium-blink-merge.git] / ui / events / event_dispatcher_unittest.cc
blob0bae34e81918f4597ff3a63a9590931479fba88a
1 // Copyright (c) 2012 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.
5 #include "ui/events/event_dispatcher.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/events/event.h"
9 #include "ui/events/event_dispatcher.h"
10 #include "ui/events/event_target.h"
11 #include "ui/events/event_target_iterator.h"
12 #include "ui/events/event_utils.h"
14 namespace ui {
16 namespace {
18 class TestTarget : public EventTarget {
19 public:
20 TestTarget() : parent_(NULL), valid_(true) {}
21 ~TestTarget() override {}
23 void set_parent(TestTarget* parent) { parent_ = parent; }
25 bool valid() const { return valid_; }
26 void set_valid(bool valid) { valid_ = valid; }
28 void AddHandlerId(int id) {
29 handler_list_.push_back(id);
32 const std::vector<int>& handler_list() const { return handler_list_; }
34 void Reset() {
35 handler_list_.clear();
36 valid_ = true;
39 private:
40 // Overridden from EventTarget:
41 bool CanAcceptEvent(const ui::Event& event) override { return true; }
43 EventTarget* GetParentTarget() override { return parent_; }
45 scoped_ptr<EventTargetIterator> GetChildIterator() const override {
46 return nullptr;
49 EventTargeter* GetEventTargeter() override { return NULL; }
51 TestTarget* parent_;
52 std::vector<int> handler_list_;
53 bool valid_;
55 DISALLOW_COPY_AND_ASSIGN(TestTarget);
58 class TestEventHandler : public EventHandler {
59 public:
60 TestEventHandler(int id)
61 : id_(id),
62 event_result_(ER_UNHANDLED),
63 expect_pre_target_(false),
64 expect_post_target_(false),
65 received_pre_target_(false) {
68 ~TestEventHandler() override {}
70 virtual void ReceivedEvent(Event* event) {
71 static_cast<TestTarget*>(event->target())->AddHandlerId(id_);
72 if (event->phase() == ui::EP_POSTTARGET) {
73 EXPECT_TRUE(expect_post_target_);
74 if (expect_pre_target_)
75 EXPECT_TRUE(received_pre_target_);
76 } else if (event->phase() == ui::EP_PRETARGET) {
77 EXPECT_TRUE(expect_pre_target_);
78 received_pre_target_ = true;
79 } else {
80 NOTREACHED();
84 void set_event_result(EventResult result) { event_result_ = result; }
86 void set_expect_pre_target(bool expect) { expect_pre_target_ = expect; }
87 void set_expect_post_target(bool expect) { expect_post_target_ = expect; }
89 private:
90 // Overridden from EventHandler:
91 void OnEvent(Event* event) override {
92 ui::EventHandler::OnEvent(event);
93 ReceivedEvent(event);
94 SetStatusOnEvent(event);
97 void SetStatusOnEvent(Event* event) {
98 if (event_result_ & ui::ER_CONSUMED)
99 event->StopPropagation();
100 if (event_result_ & ui::ER_HANDLED)
101 event->SetHandled();
104 int id_;
105 EventResult event_result_;
106 bool expect_pre_target_;
107 bool expect_post_target_;
108 bool received_pre_target_;
110 DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
113 class NonCancelableEvent : public Event {
114 public:
115 NonCancelableEvent()
116 : Event(ui::ET_CANCEL_MODE, ui::EventTimeForNow(), 0) {
117 set_cancelable(false);
120 ~NonCancelableEvent() override {}
122 private:
123 DISALLOW_COPY_AND_ASSIGN(NonCancelableEvent);
126 // Destroys the dispatcher-delegate when it receives any event.
127 class EventHandlerDestroyDispatcherDelegate : public TestEventHandler {
128 public:
129 EventHandlerDestroyDispatcherDelegate(EventDispatcherDelegate* delegate,
130 int id)
131 : TestEventHandler(id),
132 dispatcher_delegate_(delegate) {
135 ~EventHandlerDestroyDispatcherDelegate() override {}
137 private:
138 void ReceivedEvent(Event* event) override {
139 TestEventHandler::ReceivedEvent(event);
140 delete dispatcher_delegate_;
143 EventDispatcherDelegate* dispatcher_delegate_;
145 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyDispatcherDelegate);
148 // Invalidates the target when it receives any event.
149 class InvalidateTargetEventHandler : public TestEventHandler {
150 public:
151 explicit InvalidateTargetEventHandler(int id) : TestEventHandler(id) {}
152 ~InvalidateTargetEventHandler() override {}
154 private:
155 void ReceivedEvent(Event* event) override {
156 TestEventHandler::ReceivedEvent(event);
157 TestTarget* target = static_cast<TestTarget*>(event->target());
158 target->set_valid(false);
161 DISALLOW_COPY_AND_ASSIGN(InvalidateTargetEventHandler);
164 // Destroys a second event handler when this handler gets an event.
165 // Optionally also destroys the dispatcher.
166 class EventHandlerDestroyer : public TestEventHandler {
167 public:
168 EventHandlerDestroyer(int id, EventHandler* destroy)
169 : TestEventHandler(id),
170 to_destroy_(destroy),
171 dispatcher_delegate_(NULL) {
174 ~EventHandlerDestroyer() override { CHECK(!to_destroy_); }
176 void set_dispatcher_delegate(EventDispatcherDelegate* dispatcher_delegate) {
177 dispatcher_delegate_ = dispatcher_delegate;
180 private:
181 void ReceivedEvent(Event* event) override {
182 TestEventHandler::ReceivedEvent(event);
183 delete to_destroy_;
184 to_destroy_ = NULL;
186 if (dispatcher_delegate_) {
187 delete dispatcher_delegate_;
188 dispatcher_delegate_ = NULL;
192 EventHandler* to_destroy_;
193 EventDispatcherDelegate* dispatcher_delegate_;
195 DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyer);
198 class TestEventDispatcher : public EventDispatcherDelegate {
199 public:
200 TestEventDispatcher() {}
202 ~TestEventDispatcher() override {}
204 EventDispatchDetails ProcessEvent(EventTarget* target, Event* event) {
205 return DispatchEvent(target, event);
208 private:
209 // Overridden from EventDispatcherDelegate:
210 bool CanDispatchToTarget(EventTarget* target) override {
211 TestTarget* test_target = static_cast<TestTarget*>(target);
212 return test_target->valid();
215 DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher);
218 } // namespace
220 TEST(EventDispatcherTest, EventDispatchOrder) {
221 TestEventDispatcher dispatcher;
222 TestTarget parent, child;
223 TestEventHandler h1(1), h2(2), h3(3), h4(4);
224 TestEventHandler h5(5), h6(6), h7(7), h8(8);
226 child.set_parent(&parent);
228 parent.AddPreTargetHandler(&h1);
229 parent.AddPreTargetHandler(&h2);
231 child.AddPreTargetHandler(&h3);
232 child.AddPreTargetHandler(&h4);
234 h1.set_expect_pre_target(true);
235 h2.set_expect_pre_target(true);
236 h3.set_expect_pre_target(true);
237 h4.set_expect_pre_target(true);
239 child.AddPostTargetHandler(&h5);
240 child.AddPostTargetHandler(&h6);
242 parent.AddPostTargetHandler(&h7);
243 parent.AddPostTargetHandler(&h8);
245 h5.set_expect_post_target(true);
246 h6.set_expect_post_target(true);
247 h7.set_expect_post_target(true);
248 h8.set_expect_post_target(true);
250 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4),
251 ui::EventTimeForNow(), 0, 0);
252 Event::DispatcherApi event_mod(&mouse);
253 dispatcher.ProcessEvent(&child, &mouse);
254 EXPECT_FALSE(mouse.stopped_propagation());
255 EXPECT_FALSE(mouse.handled());
258 int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
259 EXPECT_EQ(
260 std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
261 child.handler_list());
264 child.Reset();
265 event_mod.set_phase(EP_PREDISPATCH);
266 event_mod.set_result(ER_UNHANDLED);
268 h1.set_event_result(ER_HANDLED);
269 dispatcher.ProcessEvent(&child, &mouse);
270 EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
271 EXPECT_FALSE(mouse.stopped_propagation());
272 EXPECT_TRUE(mouse.handled());
274 // |h1| marks the event as handled. So only the pre-target handlers should
275 // receive the event.
276 int expected[] = { 1, 2, 3, 4 };
277 EXPECT_EQ(
278 std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
279 child.handler_list());
282 child.Reset();
283 event_mod.set_phase(EP_PREDISPATCH);
284 event_mod.set_result(ER_UNHANDLED);
286 int nexpected[] = { 1, 2, 3, 4, 5 };
287 h1.set_event_result(ER_UNHANDLED);
288 h5.set_event_result(ER_CONSUMED);
289 dispatcher.ProcessEvent(&child, &mouse);
290 EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
291 EXPECT_TRUE(mouse.stopped_propagation());
292 EXPECT_TRUE(mouse.handled());
293 EXPECT_EQ(
294 std::vector<int>(nexpected, nexpected + sizeof(nexpected) / sizeof(int)),
295 child.handler_list());
297 child.Reset();
298 event_mod.set_phase(EP_PREDISPATCH);
299 event_mod.set_result(ER_UNHANDLED);
301 int exp[] = { 1 };
302 h1.set_event_result(ER_CONSUMED);
303 dispatcher.ProcessEvent(&child, &mouse);
304 EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
305 EXPECT_TRUE(mouse.stopped_propagation());
306 EXPECT_TRUE(mouse.handled());
307 EXPECT_EQ(
308 std::vector<int>(exp, exp + sizeof(exp) / sizeof(int)),
309 child.handler_list());
312 // Tests that the event-phases are correct.
313 TEST(EventDispatcherTest, EventDispatchPhase) {
314 TestEventDispatcher dispatcher;
315 TestTarget target;
317 TestEventHandler handler(11);
319 target.AddPreTargetHandler(&handler);
320 target.AddPostTargetHandler(&handler);
321 handler.set_expect_pre_target(true);
322 handler.set_expect_post_target(true);
324 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4),
325 ui::EventTimeForNow(), 0, 0);
326 Event::DispatcherApi event_mod(&mouse);
327 dispatcher.ProcessEvent(&target, &mouse);
328 EXPECT_EQ(ER_UNHANDLED, mouse.result());
330 int handlers[] = { 11, 11 };
331 EXPECT_EQ(
332 std::vector<int>(handlers, handlers + sizeof(handlers) / sizeof(int)),
333 target.handler_list());
336 // Tests that if the dispatcher is destroyed in the middle of pre or post-target
337 // dispatching events, it doesn't cause a crash.
338 TEST(EventDispatcherTest, EventDispatcherDestroyedDuringDispatch) {
339 // Test for pre-target first.
341 TestEventDispatcher* dispatcher = new TestEventDispatcher();
342 TestTarget target;
343 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
344 TestEventHandler h1(1), h2(2);
346 target.AddPreTargetHandler(&h1);
347 target.AddPreTargetHandler(&handler);
348 target.AddPreTargetHandler(&h2);
350 h1.set_expect_pre_target(true);
351 handler.set_expect_pre_target(true);
352 // |h2| should not receive any events at all since |handler| will have
353 // destroyed the dispatcher.
354 h2.set_expect_pre_target(false);
356 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4),
357 ui::EventTimeForNow(), 0, 0);
358 EventDispatchDetails details = dispatcher->ProcessEvent(&target, &mouse);
359 EXPECT_TRUE(details.dispatcher_destroyed);
360 EXPECT_EQ(ER_CONSUMED, mouse.result());
361 EXPECT_EQ(2U, target.handler_list().size());
362 EXPECT_EQ(1, target.handler_list()[0]);
363 EXPECT_EQ(5, target.handler_list()[1]);
366 // Test for non-cancelable event.
368 TestEventDispatcher* dispatcher = new TestEventDispatcher();
369 TestTarget target;
370 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
371 TestEventHandler h1(1), h2(2);
373 target.AddPreTargetHandler(&h1);
374 target.AddPreTargetHandler(&handler);
375 target.AddPreTargetHandler(&h2);
377 h1.set_expect_pre_target(true);
378 handler.set_expect_pre_target(true);
379 // |h2| should not receive any events at all since |handler| will have
380 // destroyed the dispatcher.
381 h2.set_expect_pre_target(false);
383 NonCancelableEvent event;
384 EventDispatchDetails details = dispatcher->ProcessEvent(&target, &event);
385 EXPECT_TRUE(details.dispatcher_destroyed);
386 EXPECT_EQ(2U, target.handler_list().size());
387 EXPECT_EQ(1, target.handler_list()[0]);
388 EXPECT_EQ(5, target.handler_list()[1]);
391 // Now test for post-target.
393 TestEventDispatcher* dispatcher = new TestEventDispatcher();
394 TestTarget target;
395 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
396 TestEventHandler h1(1), h2(2);
398 target.AddPostTargetHandler(&h1);
399 target.AddPostTargetHandler(&handler);
400 target.AddPostTargetHandler(&h2);
402 h1.set_expect_post_target(true);
403 handler.set_expect_post_target(true);
404 // |h2| should not receive any events at all since |handler| will have
405 // destroyed the dispatcher.
406 h2.set_expect_post_target(false);
408 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4),
409 ui::EventTimeForNow(), 0, 0);
410 EventDispatchDetails details = dispatcher->ProcessEvent(&target, &mouse);
411 EXPECT_TRUE(details.dispatcher_destroyed);
412 EXPECT_EQ(ER_CONSUMED, mouse.result());
413 EXPECT_EQ(2U, target.handler_list().size());
414 EXPECT_EQ(1, target.handler_list()[0]);
415 EXPECT_EQ(5, target.handler_list()[1]);
418 // Test for non-cancelable event.
420 TestEventDispatcher* dispatcher = new TestEventDispatcher();
421 TestTarget target;
422 EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
423 TestEventHandler h1(1), h2(2);
425 target.AddPostTargetHandler(&h1);
426 target.AddPostTargetHandler(&handler);
427 target.AddPostTargetHandler(&h2);
429 h1.set_expect_post_target(true);
430 handler.set_expect_post_target(true);
431 // |h2| should not receive any events at all since |handler| will have
432 // destroyed the dispatcher.
433 h2.set_expect_post_target(false);
435 NonCancelableEvent event;
436 EventDispatchDetails details = dispatcher->ProcessEvent(&target, &event);
437 EXPECT_TRUE(details.dispatcher_destroyed);
438 EXPECT_EQ(2U, target.handler_list().size());
439 EXPECT_EQ(1, target.handler_list()[0]);
440 EXPECT_EQ(5, target.handler_list()[1]);
444 // Tests that a target becoming invalid in the middle of pre- or post-target
445 // event processing aborts processing.
446 TEST(EventDispatcherTest, EventDispatcherInvalidateTarget) {
447 TestEventDispatcher dispatcher;
448 TestTarget target;
449 TestEventHandler h1(1);
450 InvalidateTargetEventHandler invalidate_handler(2);
451 TestEventHandler h3(3);
453 target.AddPreTargetHandler(&h1);
454 target.AddPreTargetHandler(&invalidate_handler);
455 target.AddPreTargetHandler(&h3);
457 h1.set_expect_pre_target(true);
458 invalidate_handler.set_expect_pre_target(true);
459 // |h3| should not receive events as the target will be invalidated.
460 h3.set_expect_pre_target(false);
462 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4),
463 ui::EventTimeForNow(), 0, 0);
464 EventDispatchDetails details = dispatcher.ProcessEvent(&target, &mouse);
465 EXPECT_FALSE(details.dispatcher_destroyed);
466 EXPECT_TRUE(details.target_destroyed);
467 EXPECT_FALSE(target.valid());
468 EXPECT_TRUE(mouse.stopped_propagation());
469 EXPECT_EQ(2U, target.handler_list().size());
470 EXPECT_EQ(1, target.handler_list()[0]);
471 EXPECT_EQ(2, target.handler_list()[1]);
473 // Test for non-cancelable event.
474 target.Reset();
475 NonCancelableEvent event;
476 details = dispatcher.ProcessEvent(&target, &event);
477 EXPECT_FALSE(details.dispatcher_destroyed);
478 EXPECT_TRUE(details.target_destroyed);
479 EXPECT_FALSE(target.valid());
480 EXPECT_EQ(2U, target.handler_list().size());
481 EXPECT_EQ(1, target.handler_list()[0]);
482 EXPECT_EQ(2, target.handler_list()[1]);
485 // Tests that if an event-handler gets destroyed during event-dispatch, it does
486 // not cause a crash.
487 TEST(EventDispatcherTest, EventHandlerDestroyedDuringDispatch) {
489 TestEventDispatcher dispatcher;
490 TestTarget target;
491 TestEventHandler h1(1);
492 TestEventHandler* h3 = new TestEventHandler(3);
493 EventHandlerDestroyer handle_destroyer(2, h3);
495 target.AddPreTargetHandler(&h1);
496 target.AddPreTargetHandler(&handle_destroyer);
497 target.AddPreTargetHandler(h3);
499 h1.set_expect_pre_target(true);
500 handle_destroyer.set_expect_pre_target(true);
501 // |h3| should not receive events since |handle_destroyer| will have
502 // destroyed it.
503 h3->set_expect_pre_target(false);
505 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4),
506 ui::EventTimeForNow(), 0, 0);
507 EventDispatchDetails details = dispatcher.ProcessEvent(&target, &mouse);
508 EXPECT_FALSE(details.dispatcher_destroyed);
509 EXPECT_FALSE(details.target_destroyed);
510 EXPECT_FALSE(mouse.stopped_propagation());
511 EXPECT_EQ(2U, target.handler_list().size());
512 EXPECT_EQ(1, target.handler_list()[0]);
513 EXPECT_EQ(2, target.handler_list()[1]);
516 // Test for non-cancelable events.
518 TestEventDispatcher dispatcher;
519 TestTarget target;
520 TestEventHandler h1(1);
521 TestEventHandler* h3 = new TestEventHandler(3);
522 EventHandlerDestroyer handle_destroyer(2, h3);
524 target.AddPreTargetHandler(&h1);
525 target.AddPreTargetHandler(&handle_destroyer);
526 target.AddPreTargetHandler(h3);
528 h1.set_expect_pre_target(true);
529 handle_destroyer.set_expect_pre_target(true);
530 h3->set_expect_pre_target(false);
532 NonCancelableEvent event;
533 EventDispatchDetails details = dispatcher.ProcessEvent(&target, &event);
534 EXPECT_FALSE(details.dispatcher_destroyed);
535 EXPECT_FALSE(details.target_destroyed);
536 EXPECT_EQ(2U, target.handler_list().size());
537 EXPECT_EQ(1, target.handler_list()[0]);
538 EXPECT_EQ(2, target.handler_list()[1]);
542 // Tests that things work correctly if an event-handler destroys both the
543 // dispatcher and a handler.
544 TEST(EventDispatcherTest, EventHandlerAndDispatcherDestroyedDuringDispatch) {
546 TestEventDispatcher* dispatcher = new TestEventDispatcher();
547 TestTarget target;
548 TestEventHandler h1(1);
549 TestEventHandler* h3 = new TestEventHandler(3);
550 EventHandlerDestroyer destroyer(2, h3);
552 target.AddPreTargetHandler(&h1);
553 target.AddPreTargetHandler(&destroyer);
554 target.AddPreTargetHandler(h3);
556 h1.set_expect_pre_target(true);
557 destroyer.set_expect_pre_target(true);
558 destroyer.set_dispatcher_delegate(dispatcher);
559 // |h3| should not receive events since |destroyer| will have destroyed
560 // it.
561 h3->set_expect_pre_target(false);
563 MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4),
564 ui::EventTimeForNow(), 0, 0);
565 EventDispatchDetails details = dispatcher->ProcessEvent(&target, &mouse);
566 EXPECT_TRUE(details.dispatcher_destroyed);
567 EXPECT_TRUE(mouse.stopped_propagation());
568 EXPECT_EQ(2U, target.handler_list().size());
569 EXPECT_EQ(1, target.handler_list()[0]);
570 EXPECT_EQ(2, target.handler_list()[1]);
573 // Test for non-cancelable events.
575 TestEventDispatcher* dispatcher = new TestEventDispatcher();
576 TestTarget target;
577 TestEventHandler h1(1);
578 TestEventHandler* h3 = new TestEventHandler(3);
579 EventHandlerDestroyer destroyer(2, h3);
581 target.AddPreTargetHandler(&h1);
582 target.AddPreTargetHandler(&destroyer);
583 target.AddPreTargetHandler(h3);
585 h1.set_expect_pre_target(true);
586 destroyer.set_expect_pre_target(true);
587 destroyer.set_dispatcher_delegate(dispatcher);
588 // |h3| should not receive events since |destroyer| will have destroyed
589 // it.
590 h3->set_expect_pre_target(false);
592 NonCancelableEvent event;
593 EventDispatchDetails details = dispatcher->ProcessEvent(&target, &event);
594 EXPECT_TRUE(details.dispatcher_destroyed);
595 EXPECT_EQ(2U, target.handler_list().size());
596 EXPECT_EQ(1, target.handler_list()[0]);
597 EXPECT_EQ(2, target.handler_list()[1]);
601 } // namespace ui