Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / events / platform / platform_event_source_unittest.cc
index 56aef35..fa5e9ef 100644 (file)
@@ -27,6 +27,20 @@ scoped_ptr<PlatformEvent> CreatePlatformEvent() {
 template <typename T>
 void DestroyScopedPtr(scoped_ptr<T> object) {}
 
+void RemoveDispatcher(PlatformEventDispatcher* dispatcher) {
+  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(dispatcher);
+}
+
+void RemoveDispatchers(PlatformEventDispatcher* first,
+                       PlatformEventDispatcher* second) {
+  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(first);
+  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(second);
+}
+
+void AddDispatcher(PlatformEventDispatcher* dispatcher) {
+  PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(dispatcher);
+}
+
 }  // namespace
 
 class TestPlatformEventSource : public PlatformEventSource {
@@ -87,20 +101,17 @@ class TestPlatformEventDispatcher : public PlatformEventDispatcher {
 class TestPlatformEventObserver : public PlatformEventObserver {
  public:
   TestPlatformEventObserver(int id, std::vector<int>* list)
-      : id_(id), list_(list), consume_event_(false) {
+      : id_(id), list_(list) {
     PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
   }
   virtual ~TestPlatformEventObserver() {
     PlatformEventSource::GetInstance()->RemovePlatformEventObserver(this);
   }
 
-  void set_consume_event(bool consume) { consume_event_ = consume; }
-
  protected:
   // PlatformEventObserver:
-  virtual EventStatus WillProcessEvent(const PlatformEvent& event) OVERRIDE {
+  virtual void WillProcessEvent(const PlatformEvent& event) OVERRIDE {
     list_->push_back(id_);
-    return consume_event_ ? EVENT_STATUS_HANDLED : EVENT_STATUS_CONTINUE;
   }
 
   virtual void DidProcessEvent(const PlatformEvent& event) OVERRIDE {}
@@ -108,7 +119,6 @@ class TestPlatformEventObserver : public PlatformEventObserver {
  private:
   int id_;
   std::vector<int>* list_;
-  bool consume_event_;
 
   DISALLOW_COPY_AND_ASSIGN(TestPlatformEventObserver);
 };
@@ -240,26 +250,6 @@ TEST_F(PlatformEventTest, DispatcherAndObserverOrder) {
   EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list);
 }
 
-// Tests that an observer can consume an event and stop its dispatch.
-TEST_F(PlatformEventTest, ObserverConsumesEventToStopDispatch) {
-  std::vector<int> list;
-  TestPlatformEventDispatcher first_d(12, &list);
-  TestPlatformEventObserver first_o(10, &list);
-  TestPlatformEventDispatcher second_d(23, &list);
-  TestPlatformEventObserver second_o(20, &list);
-  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
-  source()->Dispatch(*event);
-  const int expected[] = {10, 20, 12, 23};
-  EXPECT_EQ(std::vector<int>(expected, expected + arraysize(expected)), list);
-
-  list.clear();
-  first_o.set_consume_event(true);
-  event = CreatePlatformEvent();
-  source()->Dispatch(*event);
-  ASSERT_EQ(1u, list.size());
-  EXPECT_EQ(10, list[0]);
-}
-
 // Tests that an overridden dispatcher receives events before the default
 // dispatchers.
 TEST_F(PlatformEventTest, OverriddenDispatcherBasic) {
@@ -326,6 +316,170 @@ TEST_F(PlatformEventTest, OverriddenDispatcherInvokeDefaultDispatcher) {
   EXPECT_EQ(10, list[2]);
 }
 
+// Runs a callback during an event dispatch.
+class RunCallbackDuringDispatch : public TestPlatformEventDispatcher {
+ public:
+  RunCallbackDuringDispatch(int id, std::vector<int>* list)
+      : TestPlatformEventDispatcher(id, list) {}
+  virtual ~RunCallbackDuringDispatch() {}
+
+  void set_callback(const base::Closure& callback) {
+    callback_ = callback;
+  }
+
+ protected:
+  // PlatformEventDispatcher:
+  virtual uint32_t DispatchEvent(const PlatformEvent& event) OVERRIDE {
+    if (!callback_.is_null())
+      callback_.Run();
+    return TestPlatformEventDispatcher::DispatchEvent(event);
+  }
+
+ private:
+  base::Closure callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(RunCallbackDuringDispatch);
+};
+
+// Test that if a dispatcher removes another dispatcher that is later in the
+// dispatcher list during dispatching an event, then event dispatching still
+// continues correctly.
+TEST_F(PlatformEventTest, DispatcherRemovesNextDispatcherDuringDispatch) {
+  std::vector<int> list;
+  TestPlatformEventDispatcher first(10, &list);
+  RunCallbackDuringDispatch second(15, &list);
+  TestPlatformEventDispatcher third(20, &list);
+  TestPlatformEventDispatcher fourth(30, &list);
+
+  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&third)));
+
+  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
+  source()->Dispatch(*event);
+  // |second| removes |third| from the dispatcher list during dispatch. So the
+  // event should only reach |first|, |second|, and |fourth|.
+  ASSERT_EQ(3u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(15, list[1]);
+  EXPECT_EQ(30, list[2]);
+}
+
+// Tests that if a dispatcher removes itself from the dispatcher list during
+// dispatching an event, then event dispatching continues correctly.
+TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatch) {
+  std::vector<int> list;
+  TestPlatformEventDispatcher first(10, &list);
+  RunCallbackDuringDispatch second(15, &list);
+  TestPlatformEventDispatcher third(20, &list);
+
+  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&second)));
+
+  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
+  source()->Dispatch(*event);
+  // |second| removes itself from the dispatcher list during dispatch. So the
+  // event should reach all three dispatchers in the list.
+  ASSERT_EQ(3u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(15, list[1]);
+  EXPECT_EQ(20, list[2]);
+}
+
+// Tests that if a dispatcher removes itself from the dispatcher list during
+// dispatching an event, and this dispatcher is last in the dispatcher-list,
+// then event dispatching ends correctly.
+TEST_F(PlatformEventTest, DispatcherRemovesSelfDuringDispatchLast) {
+  std::vector<int> list;
+  TestPlatformEventDispatcher first(10, &list);
+  RunCallbackDuringDispatch second(15, &list);
+
+  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&second)));
+
+  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
+  source()->Dispatch(*event);
+  // |second| removes itself during dispatch. So both dispatchers will have
+  // received the event.
+  ASSERT_EQ(2u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(15, list[1]);
+}
+
+// Tests that if a dispatcher removes a single dispatcher that comes before it
+// in the dispatcher list, then dispatch continues correctly.
+TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatcherDuringDispatch) {
+  std::vector<int> list;
+  TestPlatformEventDispatcher first(10, &list);
+  RunCallbackDuringDispatch second(15, &list);
+  TestPlatformEventDispatcher third(20, &list);
+
+  second.set_callback(base::Bind(&RemoveDispatcher, base::Unretained(&first)));
+
+  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
+  source()->Dispatch(*event);
+  // |second| removes |first| from the dispatcher list during dispatch. The
+  // event should reach all three dispatchers.
+  ASSERT_EQ(3u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(15, list[1]);
+  EXPECT_EQ(20, list[2]);
+}
+
+// Tests that if a dispatcher removes multiple dispatchers that comes before it
+// in the dispatcher list, then dispatch continues correctly.
+TEST_F(PlatformEventTest, DispatcherRemovesPrevDispatchersDuringDispatch) {
+  std::vector<int> list;
+  TestPlatformEventDispatcher first(10, &list);
+  TestPlatformEventDispatcher second(12, &list);
+  RunCallbackDuringDispatch third(15, &list);
+  TestPlatformEventDispatcher fourth(20, &list);
+
+  third.set_callback(base::Bind(&RemoveDispatchers,
+                                base::Unretained(&first),
+                                base::Unretained(&second)));
+
+  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
+  source()->Dispatch(*event);
+  // |third| removes |first| and |second| from the dispatcher list during
+  // dispatch. The event should reach all three dispatchers.
+  ASSERT_EQ(4u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(12, list[1]);
+  EXPECT_EQ(15, list[2]);
+  EXPECT_EQ(20, list[3]);
+}
+
+// Tests that adding a dispatcher during dispatching an event receives that
+// event.
+TEST_F(PlatformEventTest, DispatcherAddedDuringDispatchReceivesEvent) {
+  std::vector<int> list;
+  TestPlatformEventDispatcher first(10, &list);
+  RunCallbackDuringDispatch second(15, &list);
+  TestPlatformEventDispatcher third(20, &list);
+  TestPlatformEventDispatcher fourth(30, &list);
+  RemoveDispatchers(&third, &fourth);
+
+  scoped_ptr<PlatformEvent> event(CreatePlatformEvent());
+  source()->Dispatch(*event);
+  ASSERT_EQ(2u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(15, list[1]);
+
+  second.set_callback(base::Bind(&AddDispatcher, base::Unretained(&third)));
+  list.clear();
+  source()->Dispatch(*event);
+  ASSERT_EQ(3u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(15, list[1]);
+  EXPECT_EQ(20, list[2]);
+
+  second.set_callback(base::Bind(&AddDispatcher, base::Unretained(&fourth)));
+  list.clear();
+  source()->Dispatch(*event);
+  ASSERT_EQ(4u, list.size());
+  EXPECT_EQ(10, list[0]);
+  EXPECT_EQ(15, list[1]);
+  EXPECT_EQ(20, list[2]);
+  EXPECT_EQ(30, list[3]);
+}
+
 // Provides mechanism for running tests from inside an active message-loop.
 class PlatformEventTestWithMessageLoop : public PlatformEventTest {
  public: