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

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: 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 change and test event type.
21
22 // TestEventRewriteProcessor is set up with a sequence of event types,
23 // and fails if the events received via OnEventFromSource() do not match
24 // this sequence. These expected event types are consumed on receipt.
25 class TestEventRewriteProcessor : public test::TestEventProcessor {
26 public:
27 ~TestEventRewriteProcessor() { CheckAllReceived(); }
sadrul 2014/03/24 21:15:38 virtual
28
29 // EventProcessor:
30 virtual EventDispatchDetails OnEventFromSource(Event* event) OVERRIDE {
sadrul 2014/03/24 21:15:38 Overrides typically go at the end of the block. So
31 EXPECT_FALSE(expected_events_.empty());
32 EXPECT_EQ(expected_events_.front(), event->type());
33 expected_events_.pop_front();
34 return EventDispatchDetails();
35 }
36
37 void AddExpectedEvent(EventType type) { expected_events_.push_back(type); }
38 // Test that all expected events have been received.
39 void CheckAllReceived() { EXPECT_TRUE(expected_events_.empty()); }
40
41 private:
42 std::list<EventType> expected_events_;
sadrul 2014/03/24 21:15:38 DISALLOW_COPY_AND_ASSIGN
43 };
44
45 // Allocates events, testing that none are leaked.
46 class TestEventFactory {
47 public:
48 TestEventFactory() {}
49 ~TestEventFactory() { EXPECT_TRUE(events_.empty()); }
50
51 Event* New(EventType type) {
sadrul 2014/03/24 21:15:38 This should return a scoped_ptr<>
52 Event* event = new TestEvent(*this, type);
53 EXPECT_TRUE(event);
54 events_.insert(event);
55 return event;
56 }
57 void Check(Event* event) { EXPECT_NE(events_.end(), events_.find(event)); }
58 void Delete(Event* event) {
59 EventList::iterator find = events_.find(event);
60 EXPECT_NE(events_.end(), find);
61 events_.erase(find);
62 }
63
64 private:
65 class TestEvent : public Event {
66 public:
67 TestEvent(TestEventFactory& factory, EventType type)
68 : Event(type, base::TimeDelta(), 0), factory_(factory) {}
69 ~TestEvent() { factory_.Delete(this); }
70
71 private:
72 TestEventFactory& factory_;
73 };
74 typedef std::set<Event*> EventList;
75 EventList events_;
76 DISALLOW_COPY_AND_ASSIGN(TestEventFactory);
77 };
78
79 // Trivial EventSource that does nothing but send events.
80 class TestEventRewriteSource : public EventSource {
81 public:
82 explicit TestEventRewriteSource(EventProcessor* processor)
83 : processor_(processor) {}
84 virtual EventProcessor* GetEventProcessor() OVERRIDE { return processor_; }
85 void Send(EventType type) {
86 scoped_ptr<Event> event(event_factory_.New(type));
87 (void)SendEventToProcessor(event.get());
sadrul 2014/03/24 21:15:38 You don't need to Delete the event in the event-fa
88 }
89
90 private:
91 TestEventFactory event_factory_;
92 EventProcessor* processor_;
93 };
94
95 // This EventRewriter always returns the same status; it is used to test
96 // simple rewriting, and rewriter addition, removal, and sequencing.
97 // EVENT_REWRITE_DISPATCH_ANOTHER is not supported here.
98 class TestConstantEventRewriter : public EventRewriter {
99 public:
100 TestConstantEventRewriter(EventRewriteStatus status, EventType type)
101 : status_(status), type_(type) {
102 EXPECT_NE(EVENT_REWRITE_DISPATCH_ANOTHER, status);
sadrul 2014/03/24 21:15:38 CHECK instead
103 }
104
105 virtual EventRewriteStatus RewriteEvent(const Event& event,
106 Event** rewritten_event) OVERRIDE {
107 EXPECT_TRUE(rewritten_event);
108 if (status_ == EVENT_REWRITE_REWRITTEN) {
109 *rewritten_event = event_factory_.New(type_);
110 }
111 return status_;
112 }
113 virtual EventRewriteStatus NextDispatchEvent(const Event& last_event,
114 Event** new_event) OVERRIDE {
115 EXPECT_TRUE(false);
sadrul 2014/03/24 21:15:38 Replace this with a NOTREACHED instead
116 return status_;
117 }
118
119 private:
120 EventRewriteStatus status_;
121 EventType type_;
122 TestEventFactory event_factory_;
123 };
124
125 // This EventRewriter runs a simple state machine; it is used to test
126 // EVENT_REWRITE_DISPATCH_ANOTHER.
127 class TestStateMachineEventRewriter : public EventRewriter {
128 public:
129 TestStateMachineEventRewriter() : state_(0), last_rewritten_event_(0) {}
130 void AddRule(int from_state, EventType from_type,
131 int to_state, EventType to_type, EventRewriteStatus to_status) {
132 RewriteResult r = {to_state, to_type, to_status};
133 rules_.insert(std::pair<RewriteCase, RewriteResult>(
134 RewriteCase(from_state, from_type), r));
135 }
136 virtual EventRewriteStatus RewriteEvent(const Event& event,
137 Event** rewritten_event) OVERRIDE {
138 EXPECT_TRUE(rewritten_event);
139 RewriteRules::iterator find =
140 rules_.find(RewriteCase(state_, event.type()));
141 if (find == rules_.end()) {
142 return EVENT_REWRITE_CONTINUE;
143 }
144 if ((find->second.status == EVENT_REWRITE_REWRITTEN) ||
145 (find->second.status == EVENT_REWRITE_DISPATCH_ANOTHER)) {
146 last_rewritten_event_ = event_factory_.New(find->second.type);
147 *rewritten_event = last_rewritten_event_;
148 }
149 state_ = find->second.state;
150 return find->second.status;
151 }
152 virtual EventRewriteStatus NextDispatchEvent(const Event& last_event,
153 Event** new_event) OVERRIDE {
154 EXPECT_TRUE(last_rewritten_event_);
155 EXPECT_EQ(last_rewritten_event_->type(), last_event.type());
156 event_factory_.Check(last_rewritten_event_);
sadrul 2014/03/24 21:15:38 We should add a unique-identifer for each TestEven
kpschoedel 2014/03/25 18:12:01 Is it really necessary to pass back last_event? If
sadrul 2014/03/25 18:24:35 I am thinking the rewriter will need to maintain l
157 last_rewritten_event_ = 0;
158 return RewriteEvent(last_event, new_event);
159 }
160
161 private:
162 typedef std::pair<int, EventType> RewriteCase;
163 struct RewriteResult {
164 int state;
165 EventType type;
166 EventRewriteStatus status;
167 };
168 typedef std::map<RewriteCase, RewriteResult> RewriteRules;
169
170 int state_;
171 RewriteRules rules_;
172 TestEventFactory event_factory_;
173 Event* last_rewritten_event_;
174 };
175
176 } // namespace
177
178 TEST(EventRewriterTest, EventRewriting) {
179 // TestEventRewriter r0 always rewrites events to ET_CANCEL_MODE;
180 // it is placed at the beginning of the chain and later removed,
181 // to verify that rewriter removal works.
182 TestConstantEventRewriter r0(EVENT_REWRITE_REWRITTEN, ET_CANCEL_MODE);
183
184 // TestEventRewriter r1 always returns EVENT_REWRITE_CONTINUE;
185 // it is placed at the beginning of the chain to verify that a
186 // later rewriter sees the events.
187 TestConstantEventRewriter r1(EVENT_REWRITE_CONTINUE, ET_UNKNOWN);
188
189 // TestEventRewriter r2 has a state machine, primarily to test
190 // |EVENT_REWRITE_DISPATCH_ANOTHER|.
191 TestStateMachineEventRewriter r2;
192
193 // TestEventRewriter r3 always rewrites events to ET_CANCEL_MODE;
194 // it is placed at the end of the chain to verify that previously
195 // rewritten events are not passed further down the chain.
196 TestConstantEventRewriter r3(EVENT_REWRITE_REWRITTEN, ET_CANCEL_MODE);
197
198 TestEventRewriteProcessor p;
199 TestEventRewriteSource s(&p);
200 s.AddEventRewriter(&r0);
201 s.AddEventRewriter(&r1);
202 s.AddEventRewriter(&r2);
203
204 // These events should be rewritten by r0 to ET_CANCEL_MODE.
205 p.AddExpectedEvent(ET_CANCEL_MODE);
206 s.Send(ET_MOUSE_DRAGGED);
207 p.AddExpectedEvent(ET_CANCEL_MODE);
208 s.Send(ET_MOUSE_PRESSED);
209 p.CheckAllReceived();
210
211 // Remove r0, and verify that it's gone and that events make it through.
212 s.AddEventRewriter(&r3);
213 s.RemoveEventRewriter(&r0);
214 r2.AddRule(0, ET_SCROLL_FLING_START,
215 0, ET_SCROLL_FLING_CANCEL, EVENT_REWRITE_REWRITTEN);
216 p.AddExpectedEvent(ET_SCROLL_FLING_CANCEL);
217 s.Send(ET_SCROLL_FLING_START);
218 p.CheckAllReceived();
219 s.RemoveEventRewriter(&r3);
220
221 // Verify EVENT_REWRITE_DISPATCH_ANOTHER using a state machine
222 // (that happens to be analogous to sticky keys).
223 r2.AddRule(0, ET_KEY_PRESSED,
224 1, ET_KEY_PRESSED, EVENT_REWRITE_CONTINUE);
225 r2.AddRule(1, ET_MOUSE_PRESSED,
226 0, ET_MOUSE_PRESSED, EVENT_REWRITE_CONTINUE);
227 r2.AddRule(1, ET_KEY_RELEASED,
228 2, ET_KEY_RELEASED, EVENT_REWRITE_DISCARD);
229 r2.AddRule(2, ET_MOUSE_RELEASED,
230 3, ET_MOUSE_RELEASED,
231 EVENT_REWRITE_DISPATCH_ANOTHER);
232 r2.AddRule(3, ET_MOUSE_RELEASED, 0,
233 ET_KEY_RELEASED, EVENT_REWRITE_REWRITTEN);
234 p.AddExpectedEvent(ET_KEY_PRESSED);
235 s.Send(ET_KEY_PRESSED);
236 s.Send(ET_KEY_RELEASED);
237 p.AddExpectedEvent(ET_MOUSE_PRESSED);
238 s.Send(ET_MOUSE_PRESSED);
239
240 // Removing rewriters r1 and r3 shouldn't affect r2.
241 s.RemoveEventRewriter(&r1);
242 s.RemoveEventRewriter(&r3);
243
244 // Continue with the state-based rewriting.
245 p.AddExpectedEvent(ET_MOUSE_RELEASED);
246 p.AddExpectedEvent(ET_KEY_RELEASED);
247 s.Send(ET_MOUSE_RELEASED);
248 p.CheckAllReceived();
249 }
250
251 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698