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

Side by Side 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: Address review comments. 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
OLDNEW
(Empty)
1 // Copyright (c) 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/event_rewriter.h"
6
7 #include <list>
8 #include <map>
9 #include <set>
10 #include <utility>
11
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/events/test/test_event_processor.h"
14
15 namespace ui {
16
17 namespace {
18
19 // To test the handling of |EventRewriter|s through |EventSource|,
20 // we rewrite and test event types.
21 class TestEvent : public Event {
22 public:
23 explicit TestEvent(EventType type)
24 : Event(type, base::TimeDelta(), 0), unique_id_(next_unique_id_++) {}
25 ~TestEvent() {}
26 int unique_id() const { return unique_id_; }
27
28 private:
29 static int next_unique_id_;
30 int unique_id_;
31 };
32
33 int TestEvent::next_unique_id_ = 0;
34
35 // TestEventRewriteProcessor is set up with a sequence of event types,
36 // and fails if the events received via OnEventFromSource() do not match
37 // this sequence. These expected event types are consumed on receipt.
38 class TestEventRewriteProcessor : public test::TestEventProcessor {
39 public:
40 TestEventRewriteProcessor() {}
41 virtual ~TestEventRewriteProcessor() { CheckAllReceived(); }
42
43 void AddExpectedEvent(EventType type) { expected_events_.push_back(type); }
44 // Test that all expected events have been received.
45 void CheckAllReceived() { EXPECT_TRUE(expected_events_.empty()); }
46
47 // EventProcessor:
48 virtual EventDispatchDetails OnEventFromSource(Event* event) OVERRIDE {
49 EXPECT_FALSE(expected_events_.empty());
50 EXPECT_EQ(expected_events_.front(), event->type());
51 expected_events_.pop_front();
52 return EventDispatchDetails();
53 }
54
55 private:
56 std::list<EventType> expected_events_;
57 DISALLOW_COPY_AND_ASSIGN(TestEventRewriteProcessor);
58 };
59
60 // Trivial EventSource that does nothing but send events.
61 class TestEventRewriteSource : public EventSource {
62 public:
63 explicit TestEventRewriteSource(EventProcessor* processor)
64 : processor_(processor) {}
65 virtual EventProcessor* GetEventProcessor() OVERRIDE { return processor_; }
66 void Send(EventType type) {
67 scoped_ptr<Event> event(new TestEvent(type));
68 (void)SendEventToProcessor(event.get());
69 }
70
71 private:
72 EventProcessor* processor_;
73 };
74
75 // This EventRewriter always returns the same status, and if rewriting, the
76 // same event type; it is used to test simple rewriting, and rewriter addition,
77 // removal, and sequencing. Consequently EVENT_REWRITE_DISPATCH_ANOTHER is not
78 // supported here (calls to NextDispatchEvent() would continue indefinitely).
79 class TestConstantEventRewriter : public EventRewriter {
80 public:
81 TestConstantEventRewriter(EventRewriteStatus status, EventType type)
82 : status_(status), type_(type) {
83 CHECK_NE(EVENT_REWRITE_DISPATCH_ANOTHER, status);
84 }
85
86 virtual EventRewriteStatus RewriteEvent(
87 const Event& event, scoped_ptr<Event>& rewritten_event) OVERRIDE {
88 if (status_ == EVENT_REWRITE_REWRITTEN) {
89 rewritten_event.reset(new TestEvent(type_));
90 }
91 return status_;
92 }
93 virtual EventRewriteStatus NextDispatchEvent(
94 const Event& last_event, scoped_ptr<Event>& new_event) OVERRIDE {
95 NOTREACHED();
96 return status_;
97 }
98
99 private:
100 EventRewriteStatus status_;
101 EventType type_;
102 };
103
104 // This EventRewriter runs a simple state machine; it is used to test
105 // EVENT_REWRITE_DISPATCH_ANOTHER.
106 class TestStateMachineEventRewriter : public EventRewriter {
107 public:
108 TestStateMachineEventRewriter() : last_rewritten_event_(0), state_(0) {}
109 void AddRule(int from_state, EventType from_type, int to_state,
110 EventType to_type, EventRewriteStatus to_status) {
111 RewriteResult r = {to_state, to_type, to_status};
112 rules_.insert(std::pair<RewriteCase, RewriteResult>(
113 RewriteCase(from_state, from_type), r));
114 }
115 virtual EventRewriteStatus RewriteEvent(
116 const Event& event, scoped_ptr<Event>& rewritten_event) OVERRIDE {
117 RewriteRules::iterator find =
118 rules_.find(RewriteCase(state_, event.type()));
119 if (find == rules_.end()) {
120 return EVENT_REWRITE_CONTINUE;
121 }
122 if ((find->second.status == EVENT_REWRITE_REWRITTEN) ||
123 (find->second.status == EVENT_REWRITE_DISPATCH_ANOTHER)) {
124 last_rewritten_event_ = new TestEvent(find->second.type);
125 rewritten_event.reset(last_rewritten_event_);
126 } else {
127 last_rewritten_event_ = 0;
128 }
129 state_ = find->second.state;
130 return find->second.status;
131 }
132 virtual EventRewriteStatus NextDispatchEvent(
133 const Event& last_event, scoped_ptr<Event>& new_event) OVERRIDE {
134 EXPECT_TRUE(last_rewritten_event_);
135 const TestEvent* arg_last = static_cast<const TestEvent*>(&last_event);
136 EXPECT_EQ(last_rewritten_event_->unique_id(), arg_last->unique_id());
137 const TestEvent* arg_new = static_cast<const TestEvent*>(new_event.get());
138 EXPECT_FALSE(new_event && arg_last->unique_id() == arg_new->unique_id());
139 return RewriteEvent(last_event, new_event);
140 }
141
142 private:
143 typedef std::pair<int, EventType> RewriteCase;
144 struct RewriteResult {
145 int state;
146 EventType type;
147 EventRewriteStatus status;
148 };
149 typedef std::map<RewriteCase, RewriteResult> RewriteRules;
150 RewriteRules rules_;
151 TestEvent* last_rewritten_event_;
152 int state_;
153 };
154
155 } // namespace
156
157 TEST(EventRewriterTest, EventRewriting) {
158 // TestEventRewriter r0 always rewrites events to ET_CANCEL_MODE;
159 // it is placed at the beginning of the chain and later removed,
160 // to verify that rewriter removal works.
161 TestConstantEventRewriter r0(EVENT_REWRITE_REWRITTEN, ET_CANCEL_MODE);
162
163 // TestEventRewriter r1 always returns EVENT_REWRITE_CONTINUE;
164 // it is placed at the beginning of the chain to verify that a
165 // later rewriter sees the events.
166 TestConstantEventRewriter r1(EVENT_REWRITE_CONTINUE, ET_UNKNOWN);
167
168 // TestEventRewriter r2 has a state machine, primarily to test
169 // |EVENT_REWRITE_DISPATCH_ANOTHER|.
170 TestStateMachineEventRewriter r2;
171
172 // TestEventRewriter r3 always rewrites events to ET_CANCEL_MODE;
173 // it is placed at the end of the chain to verify that previously
174 // rewritten events are not passed further down the chain.
175 TestConstantEventRewriter r3(EVENT_REWRITE_REWRITTEN, ET_CANCEL_MODE);
176
177 TestEventRewriteProcessor p;
178 TestEventRewriteSource s(&p);
179 s.AddEventRewriter(&r0);
180 s.AddEventRewriter(&r1);
181 s.AddEventRewriter(&r2);
182
183 // These events should be rewritten by r0 to ET_CANCEL_MODE.
184 p.AddExpectedEvent(ET_CANCEL_MODE);
185 s.Send(ET_MOUSE_DRAGGED);
186 p.AddExpectedEvent(ET_CANCEL_MODE);
187 s.Send(ET_MOUSE_PRESSED);
188 p.CheckAllReceived();
189
190 // Remove r0, and verify that it's gone and that events make it through.
191 s.AddEventRewriter(&r3);
192 s.RemoveEventRewriter(&r0);
193 r2.AddRule(0, ET_SCROLL_FLING_START, 0, ET_SCROLL_FLING_CANCEL,
194 EVENT_REWRITE_REWRITTEN);
195 p.AddExpectedEvent(ET_SCROLL_FLING_CANCEL);
196 s.Send(ET_SCROLL_FLING_START);
197 p.CheckAllReceived();
198 s.RemoveEventRewriter(&r3);
199
200 // Verify EVENT_REWRITE_DISPATCH_ANOTHER using a state machine
201 // (that happens to be analogous to sticky keys).
202 r2.AddRule(0, ET_KEY_PRESSED,
203 1, ET_KEY_PRESSED, EVENT_REWRITE_CONTINUE);
204 r2.AddRule(1, ET_MOUSE_PRESSED,
205 0, ET_MOUSE_PRESSED, EVENT_REWRITE_CONTINUE);
206 r2.AddRule(1, ET_KEY_RELEASED,
207 2, ET_KEY_RELEASED, EVENT_REWRITE_DISCARD);
208 r2.AddRule(2, ET_MOUSE_RELEASED,
209 3, ET_MOUSE_RELEASED, EVENT_REWRITE_DISPATCH_ANOTHER);
210 r2.AddRule(3, ET_MOUSE_RELEASED,
211 0, ET_KEY_RELEASED, EVENT_REWRITE_REWRITTEN);
212 p.AddExpectedEvent(ET_KEY_PRESSED);
213 s.Send(ET_KEY_PRESSED);
214 s.Send(ET_KEY_RELEASED);
215 p.AddExpectedEvent(ET_MOUSE_PRESSED);
216 s.Send(ET_MOUSE_PRESSED);
217
218 // Removing rewriters r1 and r3 shouldn't affect r2.
219 s.RemoveEventRewriter(&r1);
220 s.RemoveEventRewriter(&r3);
221
222 // Continue with the state-based rewriting.
223 p.AddExpectedEvent(ET_MOUSE_RELEASED);
224 p.AddExpectedEvent(ET_KEY_RELEASED);
225 s.Send(ET_MOUSE_RELEASED);
226 p.CheckAllReceived();
227 }
228
229 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698