Home | History | Annotate | Download | only in events
      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.
      4 
      5 #include "ui/events/event_dispatcher.h"
      6 
      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"
     13 
     14 namespace ui {
     15 
     16 namespace {
     17 
     18 class TestTarget : public EventTarget {
     19  public:
     20   TestTarget() : parent_(NULL), valid_(true) {}
     21   virtual ~TestTarget() {}
     22 
     23   void set_parent(TestTarget* parent) { parent_ = parent; }
     24 
     25   bool valid() const { return valid_; }
     26   void set_valid(bool valid) { valid_ = valid; }
     27 
     28   void AddHandlerId(int id) {
     29     handler_list_.push_back(id);
     30   }
     31 
     32   const std::vector<int>& handler_list() const { return handler_list_; }
     33 
     34   void Reset() {
     35     handler_list_.clear();
     36     valid_ = true;
     37   }
     38 
     39  private:
     40   // Overridden from EventTarget:
     41   virtual bool CanAcceptEvent(const ui::Event& event) OVERRIDE {
     42     return true;
     43   }
     44 
     45   virtual EventTarget* GetParentTarget() OVERRIDE {
     46     return parent_;
     47   }
     48 
     49   virtual scoped_ptr<EventTargetIterator> GetChildIterator() const OVERRIDE {
     50     return scoped_ptr<EventTargetIterator>();
     51   }
     52 
     53   virtual EventTargeter* GetEventTargeter() OVERRIDE {
     54     return NULL;
     55   }
     56 
     57   TestTarget* parent_;
     58   std::vector<int> handler_list_;
     59   bool valid_;
     60 
     61   DISALLOW_COPY_AND_ASSIGN(TestTarget);
     62 };
     63 
     64 class TestEventHandler : public EventHandler {
     65  public:
     66   TestEventHandler(int id)
     67       : id_(id),
     68         event_result_(ER_UNHANDLED),
     69         expect_pre_target_(false),
     70         expect_post_target_(false),
     71         received_pre_target_(false) {
     72   }
     73 
     74   virtual ~TestEventHandler() {}
     75 
     76   virtual void ReceivedEvent(Event* event) {
     77     static_cast<TestTarget*>(event->target())->AddHandlerId(id_);
     78     if (event->phase() == ui::EP_POSTTARGET) {
     79       EXPECT_TRUE(expect_post_target_);
     80       if (expect_pre_target_)
     81         EXPECT_TRUE(received_pre_target_);
     82     } else if (event->phase() == ui::EP_PRETARGET) {
     83       EXPECT_TRUE(expect_pre_target_);
     84       received_pre_target_ = true;
     85     } else {
     86       NOTREACHED();
     87     }
     88   }
     89 
     90   void set_event_result(EventResult result) { event_result_ = result; }
     91 
     92   void set_expect_pre_target(bool expect) { expect_pre_target_ = expect; }
     93   void set_expect_post_target(bool expect) { expect_post_target_ = expect; }
     94 
     95  private:
     96   // Overridden from EventHandler:
     97   virtual void OnEvent(Event* event) OVERRIDE {
     98     ui::EventHandler::OnEvent(event);
     99     ReceivedEvent(event);
    100     SetStatusOnEvent(event);
    101   }
    102 
    103   void SetStatusOnEvent(Event* event) {
    104     if (event_result_ & ui::ER_CONSUMED)
    105       event->StopPropagation();
    106     if (event_result_ & ui::ER_HANDLED)
    107       event->SetHandled();
    108   }
    109 
    110   int id_;
    111   EventResult event_result_;
    112   bool expect_pre_target_;
    113   bool expect_post_target_;
    114   bool received_pre_target_;
    115 
    116   DISALLOW_COPY_AND_ASSIGN(TestEventHandler);
    117 };
    118 
    119 class NonCancelableEvent : public Event {
    120  public:
    121   NonCancelableEvent()
    122       : Event(ui::ET_CANCEL_MODE, ui::EventTimeForNow(), 0) {
    123     set_cancelable(false);
    124   }
    125 
    126   virtual ~NonCancelableEvent() {}
    127 
    128  private:
    129   DISALLOW_COPY_AND_ASSIGN(NonCancelableEvent);
    130 };
    131 
    132 // Destroys the dispatcher-delegate when it receives any event.
    133 class EventHandlerDestroyDispatcherDelegate : public TestEventHandler {
    134  public:
    135   EventHandlerDestroyDispatcherDelegate(EventDispatcherDelegate* delegate,
    136                                         int id)
    137       : TestEventHandler(id),
    138         dispatcher_delegate_(delegate) {
    139   }
    140 
    141   virtual ~EventHandlerDestroyDispatcherDelegate() {}
    142 
    143  private:
    144   virtual void ReceivedEvent(Event* event) OVERRIDE {
    145     TestEventHandler::ReceivedEvent(event);
    146     delete dispatcher_delegate_;
    147   }
    148 
    149   EventDispatcherDelegate* dispatcher_delegate_;
    150 
    151   DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyDispatcherDelegate);
    152 };
    153 
    154 // Invalidates the target when it receives any event.
    155 class InvalidateTargetEventHandler : public TestEventHandler {
    156  public:
    157   explicit InvalidateTargetEventHandler(int id) : TestEventHandler(id) {}
    158   virtual ~InvalidateTargetEventHandler() {}
    159 
    160  private:
    161   virtual void ReceivedEvent(Event* event) OVERRIDE {
    162    TestEventHandler::ReceivedEvent(event);
    163    TestTarget* target = static_cast<TestTarget*>(event->target());
    164    target->set_valid(false);
    165   }
    166 
    167   DISALLOW_COPY_AND_ASSIGN(InvalidateTargetEventHandler);
    168 };
    169 
    170 // Destroys a second event handler when this handler gets an event.
    171 // Optionally also destroys the dispatcher.
    172 class EventHandlerDestroyer : public TestEventHandler {
    173  public:
    174   EventHandlerDestroyer(int id, EventHandler* destroy)
    175       : TestEventHandler(id),
    176         to_destroy_(destroy),
    177         dispatcher_delegate_(NULL) {
    178   }
    179 
    180   virtual ~EventHandlerDestroyer() {
    181     CHECK(!to_destroy_);
    182   }
    183 
    184   void set_dispatcher_delegate(EventDispatcherDelegate* dispatcher_delegate) {
    185     dispatcher_delegate_ = dispatcher_delegate;
    186   }
    187 
    188  private:
    189   virtual void ReceivedEvent(Event* event) OVERRIDE {
    190     TestEventHandler::ReceivedEvent(event);
    191     delete to_destroy_;
    192     to_destroy_ = NULL;
    193 
    194     if (dispatcher_delegate_) {
    195       delete dispatcher_delegate_;
    196       dispatcher_delegate_ = NULL;
    197     }
    198   }
    199 
    200   EventHandler* to_destroy_;
    201   EventDispatcherDelegate* dispatcher_delegate_;
    202 
    203   DISALLOW_COPY_AND_ASSIGN(EventHandlerDestroyer);
    204 };
    205 
    206 class TestEventDispatcher : public EventDispatcherDelegate {
    207  public:
    208   TestEventDispatcher() {}
    209 
    210   virtual ~TestEventDispatcher() {}
    211 
    212   EventDispatchDetails ProcessEvent(EventTarget* target, Event* event) {
    213     return DispatchEvent(target, event);
    214   }
    215 
    216  private:
    217   // Overridden from EventDispatcherDelegate:
    218   virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE {
    219     TestTarget* test_target = static_cast<TestTarget*>(target);
    220     return test_target->valid();
    221   }
    222 
    223   DISALLOW_COPY_AND_ASSIGN(TestEventDispatcher);
    224 };
    225 
    226 }  // namespace
    227 
    228 TEST(EventDispatcherTest, EventDispatchOrder) {
    229   TestEventDispatcher dispatcher;
    230   TestTarget parent, child;
    231   TestEventHandler h1(1), h2(2), h3(3), h4(4);
    232   TestEventHandler h5(5), h6(6), h7(7), h8(8);
    233 
    234   child.set_parent(&parent);
    235 
    236   parent.AddPreTargetHandler(&h1);
    237   parent.AddPreTargetHandler(&h2);
    238 
    239   child.AddPreTargetHandler(&h3);
    240   child.AddPreTargetHandler(&h4);
    241 
    242   h1.set_expect_pre_target(true);
    243   h2.set_expect_pre_target(true);
    244   h3.set_expect_pre_target(true);
    245   h4.set_expect_pre_target(true);
    246 
    247   child.AddPostTargetHandler(&h5);
    248   child.AddPostTargetHandler(&h6);
    249 
    250   parent.AddPostTargetHandler(&h7);
    251   parent.AddPostTargetHandler(&h8);
    252 
    253   h5.set_expect_post_target(true);
    254   h6.set_expect_post_target(true);
    255   h7.set_expect_post_target(true);
    256   h8.set_expect_post_target(true);
    257 
    258   MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4),
    259                    gfx::Point(3, 4), 0, 0);
    260   Event::DispatcherApi event_mod(&mouse);
    261   dispatcher.ProcessEvent(&child, &mouse);
    262   EXPECT_FALSE(mouse.stopped_propagation());
    263   EXPECT_FALSE(mouse.handled());
    264 
    265   {
    266     int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    267     EXPECT_EQ(
    268         std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
    269         child.handler_list());
    270   }
    271 
    272   child.Reset();
    273   event_mod.set_phase(EP_PREDISPATCH);
    274   event_mod.set_result(ER_UNHANDLED);
    275 
    276   h1.set_event_result(ER_HANDLED);
    277   dispatcher.ProcessEvent(&child, &mouse);
    278   EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
    279   EXPECT_FALSE(mouse.stopped_propagation());
    280   EXPECT_TRUE(mouse.handled());
    281   {
    282     // |h1| marks the event as handled. So only the pre-target handlers should
    283     // receive the event.
    284     int expected[] = { 1, 2, 3, 4 };
    285     EXPECT_EQ(
    286         std::vector<int>(expected, expected + sizeof(expected) / sizeof(int)),
    287         child.handler_list());
    288   }
    289 
    290   child.Reset();
    291   event_mod.set_phase(EP_PREDISPATCH);
    292   event_mod.set_result(ER_UNHANDLED);
    293 
    294   int nexpected[] = { 1, 2, 3, 4, 5 };
    295   h1.set_event_result(ER_UNHANDLED);
    296   h5.set_event_result(ER_CONSUMED);
    297   dispatcher.ProcessEvent(&child, &mouse);
    298   EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
    299   EXPECT_TRUE(mouse.stopped_propagation());
    300   EXPECT_TRUE(mouse.handled());
    301   EXPECT_EQ(
    302       std::vector<int>(nexpected, nexpected + sizeof(nexpected) / sizeof(int)),
    303       child.handler_list());
    304 
    305   child.Reset();
    306   event_mod.set_phase(EP_PREDISPATCH);
    307   event_mod.set_result(ER_UNHANDLED);
    308 
    309   int exp[] = { 1 };
    310   h1.set_event_result(ER_CONSUMED);
    311   dispatcher.ProcessEvent(&child, &mouse);
    312   EXPECT_EQ(EP_POSTDISPATCH, mouse.phase());
    313   EXPECT_TRUE(mouse.stopped_propagation());
    314   EXPECT_TRUE(mouse.handled());
    315   EXPECT_EQ(
    316       std::vector<int>(exp, exp + sizeof(exp) / sizeof(int)),
    317       child.handler_list());
    318 }
    319 
    320 // Tests that the event-phases are correct.
    321 TEST(EventDispatcherTest, EventDispatchPhase) {
    322   TestEventDispatcher dispatcher;
    323   TestTarget target;
    324 
    325   TestEventHandler handler(11);
    326 
    327   target.AddPreTargetHandler(&handler);
    328   target.AddPostTargetHandler(&handler);
    329   handler.set_expect_pre_target(true);
    330   handler.set_expect_post_target(true);
    331 
    332   MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4),
    333                    gfx::Point(3, 4), 0, 0);
    334   Event::DispatcherApi event_mod(&mouse);
    335   dispatcher.ProcessEvent(&target, &mouse);
    336   EXPECT_EQ(ER_UNHANDLED, mouse.result());
    337 
    338   int handlers[] = { 11, 11 };
    339   EXPECT_EQ(
    340       std::vector<int>(handlers, handlers + sizeof(handlers) / sizeof(int)),
    341       target.handler_list());
    342 }
    343 
    344 // Tests that if the dispatcher is destroyed in the middle of pre or post-target
    345 // dispatching events, it doesn't cause a crash.
    346 TEST(EventDispatcherTest, EventDispatcherDestroyedDuringDispatch) {
    347   // Test for pre-target first.
    348   {
    349     TestEventDispatcher* dispatcher = new TestEventDispatcher();
    350     TestTarget target;
    351     EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
    352     TestEventHandler h1(1), h2(2);
    353 
    354     target.AddPreTargetHandler(&h1);
    355     target.AddPreTargetHandler(&handler);
    356     target.AddPreTargetHandler(&h2);
    357 
    358     h1.set_expect_pre_target(true);
    359     handler.set_expect_pre_target(true);
    360     // |h2| should not receive any events at all since |handler| will have
    361     // destroyed the dispatcher.
    362     h2.set_expect_pre_target(false);
    363 
    364     MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4),
    365                      gfx::Point(3, 4), 0, 0);
    366     EventDispatchDetails details = dispatcher->ProcessEvent(&target, &mouse);
    367     EXPECT_TRUE(details.dispatcher_destroyed);
    368     EXPECT_EQ(ER_CONSUMED, mouse.result());
    369     EXPECT_EQ(2U, target.handler_list().size());
    370     EXPECT_EQ(1, target.handler_list()[0]);
    371     EXPECT_EQ(5, target.handler_list()[1]);
    372   }
    373 
    374   // Test for non-cancelable event.
    375   {
    376     TestEventDispatcher* dispatcher = new TestEventDispatcher();
    377     TestTarget target;
    378     EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
    379     TestEventHandler h1(1), h2(2);
    380 
    381     target.AddPreTargetHandler(&h1);
    382     target.AddPreTargetHandler(&handler);
    383     target.AddPreTargetHandler(&h2);
    384 
    385     h1.set_expect_pre_target(true);
    386     handler.set_expect_pre_target(true);
    387     // |h2| should not receive any events at all since |handler| will have
    388     // destroyed the dispatcher.
    389     h2.set_expect_pre_target(false);
    390 
    391     NonCancelableEvent event;
    392     EventDispatchDetails details = dispatcher->ProcessEvent(&target, &event);
    393     EXPECT_TRUE(details.dispatcher_destroyed);
    394     EXPECT_EQ(2U, target.handler_list().size());
    395     EXPECT_EQ(1, target.handler_list()[0]);
    396     EXPECT_EQ(5, target.handler_list()[1]);
    397   }
    398 
    399   // Now test for post-target.
    400   {
    401     TestEventDispatcher* dispatcher = new TestEventDispatcher();
    402     TestTarget target;
    403     EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
    404     TestEventHandler h1(1), h2(2);
    405 
    406     target.AddPostTargetHandler(&h1);
    407     target.AddPostTargetHandler(&handler);
    408     target.AddPostTargetHandler(&h2);
    409 
    410     h1.set_expect_post_target(true);
    411     handler.set_expect_post_target(true);
    412     // |h2| should not receive any events at all since |handler| will have
    413     // destroyed the dispatcher.
    414     h2.set_expect_post_target(false);
    415 
    416     MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4),
    417                      gfx::Point(3, 4), 0, 0);
    418     EventDispatchDetails details = dispatcher->ProcessEvent(&target, &mouse);
    419     EXPECT_TRUE(details.dispatcher_destroyed);
    420     EXPECT_EQ(ER_CONSUMED, mouse.result());
    421     EXPECT_EQ(2U, target.handler_list().size());
    422     EXPECT_EQ(1, target.handler_list()[0]);
    423     EXPECT_EQ(5, target.handler_list()[1]);
    424   }
    425 
    426   // Test for non-cancelable event.
    427   {
    428     TestEventDispatcher* dispatcher = new TestEventDispatcher();
    429     TestTarget target;
    430     EventHandlerDestroyDispatcherDelegate handler(dispatcher, 5);
    431     TestEventHandler h1(1), h2(2);
    432 
    433     target.AddPostTargetHandler(&h1);
    434     target.AddPostTargetHandler(&handler);
    435     target.AddPostTargetHandler(&h2);
    436 
    437     h1.set_expect_post_target(true);
    438     handler.set_expect_post_target(true);
    439     // |h2| should not receive any events at all since |handler| will have
    440     // destroyed the dispatcher.
    441     h2.set_expect_post_target(false);
    442 
    443     NonCancelableEvent event;
    444     EventDispatchDetails details = dispatcher->ProcessEvent(&target, &event);
    445     EXPECT_TRUE(details.dispatcher_destroyed);
    446     EXPECT_EQ(2U, target.handler_list().size());
    447     EXPECT_EQ(1, target.handler_list()[0]);
    448     EXPECT_EQ(5, target.handler_list()[1]);
    449   }
    450 }
    451 
    452 // Tests that a target becoming invalid in the middle of pre- or post-target
    453 // event processing aborts processing.
    454 TEST(EventDispatcherTest, EventDispatcherInvalidateTarget) {
    455   TestEventDispatcher dispatcher;
    456   TestTarget target;
    457   TestEventHandler h1(1);
    458   InvalidateTargetEventHandler invalidate_handler(2);
    459   TestEventHandler h3(3);
    460 
    461   target.AddPreTargetHandler(&h1);
    462   target.AddPreTargetHandler(&invalidate_handler);
    463   target.AddPreTargetHandler(&h3);
    464 
    465   h1.set_expect_pre_target(true);
    466   invalidate_handler.set_expect_pre_target(true);
    467   // |h3| should not receive events as the target will be invalidated.
    468   h3.set_expect_pre_target(false);
    469 
    470   MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0,
    471                    0);
    472   EventDispatchDetails details = dispatcher.ProcessEvent(&target, &mouse);
    473   EXPECT_FALSE(details.dispatcher_destroyed);
    474   EXPECT_TRUE(details.target_destroyed);
    475   EXPECT_FALSE(target.valid());
    476   EXPECT_TRUE(mouse.stopped_propagation());
    477   EXPECT_EQ(2U, target.handler_list().size());
    478   EXPECT_EQ(1, target.handler_list()[0]);
    479   EXPECT_EQ(2, target.handler_list()[1]);
    480 
    481   // Test for non-cancelable event.
    482   target.Reset();
    483   NonCancelableEvent event;
    484   details = dispatcher.ProcessEvent(&target, &event);
    485   EXPECT_FALSE(details.dispatcher_destroyed);
    486   EXPECT_TRUE(details.target_destroyed);
    487   EXPECT_FALSE(target.valid());
    488   EXPECT_EQ(2U, target.handler_list().size());
    489   EXPECT_EQ(1, target.handler_list()[0]);
    490   EXPECT_EQ(2, target.handler_list()[1]);
    491 }
    492 
    493 // Tests that if an event-handler gets destroyed during event-dispatch, it does
    494 // not cause a crash.
    495 TEST(EventDispatcherTest, EventHandlerDestroyedDuringDispatch) {
    496   {
    497     TestEventDispatcher dispatcher;
    498     TestTarget target;
    499     TestEventHandler h1(1);
    500     TestEventHandler* h3 = new TestEventHandler(3);
    501     EventHandlerDestroyer handle_destroyer(2, h3);
    502 
    503     target.AddPreTargetHandler(&h1);
    504     target.AddPreTargetHandler(&handle_destroyer);
    505     target.AddPreTargetHandler(h3);
    506 
    507     h1.set_expect_pre_target(true);
    508     handle_destroyer.set_expect_pre_target(true);
    509     // |h3| should not receive events since |handle_destroyer| will have
    510     // destroyed it.
    511     h3->set_expect_pre_target(false);
    512 
    513     MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0,
    514                      0);
    515     EventDispatchDetails details = dispatcher.ProcessEvent(&target, &mouse);
    516     EXPECT_FALSE(details.dispatcher_destroyed);
    517     EXPECT_FALSE(details.target_destroyed);
    518     EXPECT_FALSE(mouse.stopped_propagation());
    519     EXPECT_EQ(2U, target.handler_list().size());
    520     EXPECT_EQ(1, target.handler_list()[0]);
    521     EXPECT_EQ(2, target.handler_list()[1]);
    522   }
    523 
    524   // Test for non-cancelable events.
    525   {
    526     TestEventDispatcher dispatcher;
    527     TestTarget target;
    528     TestEventHandler h1(1);
    529     TestEventHandler* h3 = new TestEventHandler(3);
    530     EventHandlerDestroyer handle_destroyer(2, h3);
    531 
    532     target.AddPreTargetHandler(&h1);
    533     target.AddPreTargetHandler(&handle_destroyer);
    534     target.AddPreTargetHandler(h3);
    535 
    536     h1.set_expect_pre_target(true);
    537     handle_destroyer.set_expect_pre_target(true);
    538     h3->set_expect_pre_target(false);
    539 
    540     NonCancelableEvent event;
    541     EventDispatchDetails details = dispatcher.ProcessEvent(&target, &event);
    542     EXPECT_FALSE(details.dispatcher_destroyed);
    543     EXPECT_FALSE(details.target_destroyed);
    544     EXPECT_EQ(2U, target.handler_list().size());
    545     EXPECT_EQ(1, target.handler_list()[0]);
    546     EXPECT_EQ(2, target.handler_list()[1]);
    547   }
    548 }
    549 
    550 // Tests that things work correctly if an event-handler destroys both the
    551 // dispatcher and a handler.
    552 TEST(EventDispatcherTest, EventHandlerAndDispatcherDestroyedDuringDispatch) {
    553   {
    554     TestEventDispatcher* dispatcher = new TestEventDispatcher();
    555     TestTarget target;
    556     TestEventHandler h1(1);
    557     TestEventHandler* h3 = new TestEventHandler(3);
    558     EventHandlerDestroyer destroyer(2, h3);
    559 
    560     target.AddPreTargetHandler(&h1);
    561     target.AddPreTargetHandler(&destroyer);
    562     target.AddPreTargetHandler(h3);
    563 
    564     h1.set_expect_pre_target(true);
    565     destroyer.set_expect_pre_target(true);
    566     destroyer.set_dispatcher_delegate(dispatcher);
    567     // |h3| should not receive events since |destroyer| will have destroyed
    568     // it.
    569     h3->set_expect_pre_target(false);
    570 
    571     MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(3, 4), gfx::Point(3, 4), 0,
    572                      0);
    573     EventDispatchDetails details = dispatcher->ProcessEvent(&target, &mouse);
    574     EXPECT_TRUE(details.dispatcher_destroyed);
    575     EXPECT_TRUE(mouse.stopped_propagation());
    576     EXPECT_EQ(2U, target.handler_list().size());
    577     EXPECT_EQ(1, target.handler_list()[0]);
    578     EXPECT_EQ(2, target.handler_list()[1]);
    579   }
    580 
    581   // Test for non-cancelable events.
    582   {
    583     TestEventDispatcher* dispatcher = new TestEventDispatcher();
    584     TestTarget target;
    585     TestEventHandler h1(1);
    586     TestEventHandler* h3 = new TestEventHandler(3);
    587     EventHandlerDestroyer destroyer(2, h3);
    588 
    589     target.AddPreTargetHandler(&h1);
    590     target.AddPreTargetHandler(&destroyer);
    591     target.AddPreTargetHandler(h3);
    592 
    593     h1.set_expect_pre_target(true);
    594     destroyer.set_expect_pre_target(true);
    595     destroyer.set_dispatcher_delegate(dispatcher);
    596     // |h3| should not receive events since |destroyer| will have destroyed
    597     // it.
    598     h3->set_expect_pre_target(false);
    599 
    600     NonCancelableEvent event;
    601     EventDispatchDetails details = dispatcher->ProcessEvent(&target, &event);
    602     EXPECT_TRUE(details.dispatcher_destroyed);
    603     EXPECT_EQ(2U, target.handler_list().size());
    604     EXPECT_EQ(1, target.handler_list()[0]);
    605     EXPECT_EQ(2, target.handler_list()[1]);
    606   }
    607 }
    608 
    609 }  // namespace ui
    610