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

Unified Diff: ui/events/event_rewriter_unittest.cc

Issue 210203002: events: Introduce EventRewriter. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix missing 'virtual' 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/events/event_rewriter.h ('k') | ui/events/event_source.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/events/event_rewriter_unittest.cc
diff --git a/ui/events/event_rewriter_unittest.cc b/ui/events/event_rewriter_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c161ff058a4292fc64c0a88172b9e3b00c7ed38e
--- /dev/null
+++ b/ui/events/event_rewriter_unittest.cc
@@ -0,0 +1,231 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/event_rewriter.h"
+
+#include <list>
+#include <map>
+#include <set>
+#include <utility>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/test/test_event_processor.h"
+
+namespace ui {
+
+namespace {
+
+// To test the handling of |EventRewriter|s through |EventSource|,
+// we rewrite and test event types.
+class TestEvent : public Event {
+ public:
+ explicit TestEvent(EventType type)
+ : Event(type, base::TimeDelta(), 0), unique_id_(next_unique_id_++) {}
+ virtual ~TestEvent() {}
+ int unique_id() const { return unique_id_; }
+
+ private:
+ static int next_unique_id_;
+ int unique_id_;
+};
+
+int TestEvent::next_unique_id_ = 0;
+
+// TestEventRewriteProcessor is set up with a sequence of event types,
+// and fails if the events received via OnEventFromSource() do not match
+// this sequence. These expected event types are consumed on receipt.
+class TestEventRewriteProcessor : public test::TestEventProcessor {
+ public:
+ TestEventRewriteProcessor() {}
+ virtual ~TestEventRewriteProcessor() { CheckAllReceived(); }
+
+ void AddExpectedEvent(EventType type) { expected_events_.push_back(type); }
+ // Test that all expected events have been received.
+ void CheckAllReceived() { EXPECT_TRUE(expected_events_.empty()); }
+
+ // EventProcessor:
+ virtual EventDispatchDetails OnEventFromSource(Event* event) OVERRIDE {
+ EXPECT_FALSE(expected_events_.empty());
+ EXPECT_EQ(expected_events_.front(), event->type());
+ expected_events_.pop_front();
+ return EventDispatchDetails();
+ }
+
+ private:
+ std::list<EventType> expected_events_;
+ DISALLOW_COPY_AND_ASSIGN(TestEventRewriteProcessor);
+};
+
+// Trivial EventSource that does nothing but send events.
+class TestEventRewriteSource : public EventSource {
+ public:
+ explicit TestEventRewriteSource(EventProcessor* processor)
+ : processor_(processor) {}
+ virtual EventProcessor* GetEventProcessor() OVERRIDE { return processor_; }
+ void Send(EventType type) {
+ scoped_ptr<Event> event(new TestEvent(type));
+ (void)SendEventToProcessor(event.get());
+ }
+
+ private:
+ EventProcessor* processor_;
+};
+
+// This EventRewriter always returns the same status, and if rewriting, the
+// same event type; it is used to test simple rewriting, and rewriter addition,
+// removal, and sequencing. Consequently EVENT_REWRITE_DISPATCH_ANOTHER is not
+// supported here (calls to NextDispatchEvent() would continue indefinitely).
+class TestConstantEventRewriter : public EventRewriter {
+ public:
+ TestConstantEventRewriter(EventRewriteStatus status, EventType type)
+ : status_(status), type_(type) {
+ CHECK_NE(EVENT_REWRITE_DISPATCH_ANOTHER, status);
+ }
+
+ virtual EventRewriteStatus RewriteEvent(const Event& event,
+ scoped_ptr<Event>* rewritten_event)
+ OVERRIDE {
+ if (status_ == EVENT_REWRITE_REWRITTEN)
+ rewritten_event->reset(new TestEvent(type_));
+ return status_;
+ }
+ virtual EventRewriteStatus NextDispatchEvent(const Event& last_event,
+ scoped_ptr<Event>* new_event)
+ OVERRIDE {
+ NOTREACHED();
+ return status_;
+ }
+
+ private:
+ EventRewriteStatus status_;
+ EventType type_;
+};
+
+// This EventRewriter runs a simple state machine; it is used to test
+// EVENT_REWRITE_DISPATCH_ANOTHER.
+class TestStateMachineEventRewriter : public EventRewriter {
+ public:
+ TestStateMachineEventRewriter() : last_rewritten_event_(0), state_(0) {}
+ void AddRule(int from_state, EventType from_type,
+ int to_state, EventType to_type, EventRewriteStatus to_status) {
+ RewriteResult r = {to_state, to_type, to_status};
+ rules_.insert(std::pair<RewriteCase, RewriteResult>(
+ RewriteCase(from_state, from_type), r));
+ }
+ virtual EventRewriteStatus RewriteEvent(const Event& event,
+ scoped_ptr<Event>* rewritten_event)
+ OVERRIDE {
+ RewriteRules::iterator find =
+ rules_.find(RewriteCase(state_, event.type()));
+ if (find == rules_.end())
+ return EVENT_REWRITE_CONTINUE;
+ if ((find->second.status == EVENT_REWRITE_REWRITTEN) ||
+ (find->second.status == EVENT_REWRITE_DISPATCH_ANOTHER)) {
+ last_rewritten_event_ = new TestEvent(find->second.type);
+ rewritten_event->reset(last_rewritten_event_);
+ } else {
+ last_rewritten_event_ = 0;
+ }
+ state_ = find->second.state;
+ return find->second.status;
+ }
+ virtual EventRewriteStatus NextDispatchEvent(const Event& last_event,
+ scoped_ptr<Event>* new_event)
+ OVERRIDE {
+ EXPECT_TRUE(last_rewritten_event_);
+ const TestEvent* arg_last = static_cast<const TestEvent*>(&last_event);
+ EXPECT_EQ(last_rewritten_event_->unique_id(), arg_last->unique_id());
+ const TestEvent* arg_new = static_cast<const TestEvent*>(new_event->get());
+ EXPECT_FALSE(arg_new && arg_last->unique_id() == arg_new->unique_id());
+ return RewriteEvent(last_event, new_event);
+ }
+
+ private:
+ typedef std::pair<int, EventType> RewriteCase;
+ struct RewriteResult {
+ int state;
+ EventType type;
+ EventRewriteStatus status;
+ };
+ typedef std::map<RewriteCase, RewriteResult> RewriteRules;
+ RewriteRules rules_;
+ TestEvent* last_rewritten_event_;
+ int state_;
+};
+
+} // namespace
+
+TEST(EventRewriterTest, EventRewriting) {
+ // TestEventRewriter r0 always rewrites events to ET_CANCEL_MODE;
+ // it is placed at the beginning of the chain and later removed,
+ // to verify that rewriter removal works.
+ TestConstantEventRewriter r0(EVENT_REWRITE_REWRITTEN, ET_CANCEL_MODE);
+
+ // TestEventRewriter r1 always returns EVENT_REWRITE_CONTINUE;
+ // it is placed at the beginning of the chain to verify that a
+ // later rewriter sees the events.
+ TestConstantEventRewriter r1(EVENT_REWRITE_CONTINUE, ET_UNKNOWN);
+
+ // TestEventRewriter r2 has a state machine, primarily to test
+ // |EVENT_REWRITE_DISPATCH_ANOTHER|.
+ TestStateMachineEventRewriter r2;
+
+ // TestEventRewriter r3 always rewrites events to ET_CANCEL_MODE;
+ // it is placed at the end of the chain to verify that previously
+ // rewritten events are not passed further down the chain.
+ TestConstantEventRewriter r3(EVENT_REWRITE_REWRITTEN, ET_CANCEL_MODE);
+
+ TestEventRewriteProcessor p;
+ TestEventRewriteSource s(&p);
+ s.AddEventRewriter(&r0);
+ s.AddEventRewriter(&r1);
+ s.AddEventRewriter(&r2);
+
+ // These events should be rewritten by r0 to ET_CANCEL_MODE.
+ p.AddExpectedEvent(ET_CANCEL_MODE);
+ s.Send(ET_MOUSE_DRAGGED);
+ p.AddExpectedEvent(ET_CANCEL_MODE);
+ s.Send(ET_MOUSE_PRESSED);
+ p.CheckAllReceived();
+
+ // Remove r0, and verify that it's gone and that events make it through.
+ s.AddEventRewriter(&r3);
+ s.RemoveEventRewriter(&r0);
+ r2.AddRule(0, ET_SCROLL_FLING_START,
+ 0, ET_SCROLL_FLING_CANCEL, EVENT_REWRITE_REWRITTEN);
+ p.AddExpectedEvent(ET_SCROLL_FLING_CANCEL);
+ s.Send(ET_SCROLL_FLING_START);
+ p.CheckAllReceived();
+ s.RemoveEventRewriter(&r3);
+
+ // Verify EVENT_REWRITE_DISPATCH_ANOTHER using a state machine
+ // (that happens to be analogous to sticky keys).
+ r2.AddRule(0, ET_KEY_PRESSED,
+ 1, ET_KEY_PRESSED, EVENT_REWRITE_CONTINUE);
+ r2.AddRule(1, ET_MOUSE_PRESSED,
+ 0, ET_MOUSE_PRESSED, EVENT_REWRITE_CONTINUE);
+ r2.AddRule(1, ET_KEY_RELEASED,
+ 2, ET_KEY_RELEASED, EVENT_REWRITE_DISCARD);
+ r2.AddRule(2, ET_MOUSE_RELEASED,
+ 3, ET_MOUSE_RELEASED, EVENT_REWRITE_DISPATCH_ANOTHER);
+ r2.AddRule(3, ET_MOUSE_RELEASED,
+ 0, ET_KEY_RELEASED, EVENT_REWRITE_REWRITTEN);
+ p.AddExpectedEvent(ET_KEY_PRESSED);
+ s.Send(ET_KEY_PRESSED);
+ s.Send(ET_KEY_RELEASED);
+ p.AddExpectedEvent(ET_MOUSE_PRESSED);
+ s.Send(ET_MOUSE_PRESSED);
+
+ // Removing rewriters r1 and r3 shouldn't affect r2.
+ s.RemoveEventRewriter(&r1);
+ s.RemoveEventRewriter(&r3);
+
+ // Continue with the state-based rewriting.
+ p.AddExpectedEvent(ET_MOUSE_RELEASED);
+ p.AddExpectedEvent(ET_KEY_RELEASED);
+ s.Send(ET_MOUSE_RELEASED);
+ p.CheckAllReceived();
+}
+
+} // namespace ui
« no previous file with comments | « ui/events/event_rewriter.h ('k') | ui/events/event_source.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698