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

Side by Side Diff: ui/touch_selection/touch_selection_controller_aura_unittest.cc

Issue 1046783002: wip: Aura-specific implementation of unified touch selection: touch_selection (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moving the responsibility for showing the menu into the client. Created 5 years, 8 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 2015 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/touch_selection/touch_selection_controller_aura.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/aura/test/aura_test_base.h"
9 #include "ui/aura/window.h"
10 #include "ui/events/test/event_generator.h"
11 #include "ui/touch_selection/touch_handle_drawable_aura.h"
12 #include "ui/touch_selection/touch_selection_controller_aura_test_api.h"
13 #include "ui/touch_selection/touch_selection_menu_runner.h"
14
15 namespace ui {
16 namespace {
17
18 // A mock implementation for |TouchSelectionMenuRunner| used in tests.
19 class TestTouchSelectionMenuRunner : public TouchSelectionMenuRunner {
20 public:
21 TestTouchSelectionMenuRunner() {}
22 ~TestTouchSelectionMenuRunner() override {}
23
24 bool is_running() const { return is_running_; }
25
26 private:
27 // TouchSelectionMenuRunner:
28 void RunMenu(TouchSelectionMenuClient* client,
29 const gfx::Rect& anchor_rect,
30 const gfx::Size& handle_image_size,
31 aura::Window* context) override {
32 is_running_ = true;
33 }
34
35 void CloseMenu() override { is_running_ = false; }
36
37 bool IsRunning() const override { return is_running_; }
38
39 bool is_running_;
40
41 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionMenuRunner);
42 };
43
44 // Convenience to make constructing a |GestureEvent| simpler.
45 class GestureEventForTest : public GestureEvent {
46 public:
47 GestureEventForTest(EventType type, int x, int y)
48 : GestureEvent(x, y, 0, base::TimeDelta(), GestureEventDetails(type)) {}
49 };
50
51 // Convenience to make constructing a |TouchEvent| simpler.
52 class TouchEventForTest : public TouchEvent {
53 public:
54 TouchEventForTest(EventType type, gfx::Point location)
55 : TouchEvent(type, location, 0, base::TimeDelta()) {}
56 };
57
58 } // namespace
59
60 // A subclass of |TouchSelectionControllerAura| which adds some test
61 // functionality to it.
62 class TestTouchSelectionControllerAura : public TouchSelectionControllerAura {
63 public:
64 TestTouchSelectionControllerAura(TouchSelectionControllerAuraClient* client)
65 : TouchSelectionControllerAura(client),
66 test_api_(new TouchSelectionControllerAuraTestApi(this)),
67 last_drawable_(nullptr) {
68 test_api_->set_immediate_quick_menu(true);
69 }
70
71 ~TestTouchSelectionControllerAura() override {}
72
73 TouchHandleDrawable* last_drawable() const { return last_drawable_; }
74
75 TouchSelectionControllerAuraTestApi* test_api() { return test_api_.get(); }
76
77 protected:
78 // TouchSelectionControllerAura:
79 scoped_ptr<TouchHandleDrawable> CreateDrawable() override {
80 scoped_ptr<TouchHandleDrawable> drawable =
81 TouchSelectionControllerAura::CreateDrawable();
82 last_drawable_ = drawable.get();
83 return drawable;
84 }
85
86 private:
87 scoped_ptr<TouchSelectionControllerAuraTestApi> test_api_;
88 TouchHandleDrawable* last_drawable_;
89
90 DISALLOW_COPY_AND_ASSIGN(TestTouchSelectionControllerAura);
91 };
92
93 class TouchSelectionControllerAuraTest
94 : public aura::test::AuraTestBase,
95 public TouchSelectionControllerAuraClient {
96 public:
97 TouchSelectionControllerAuraTest() {}
98 ~TouchSelectionControllerAuraTest() override {}
99
100 protected:
101 bool ChangeSelection(const gfx::PointF& start_top,
102 const gfx::PointF& start_bottom,
103 const gfx::PointF& end_top,
104 const gfx::PointF& end_bottom) {
105 SelectionBound start_bound, end_bound;
106 start_bound.set_type(SelectionBound::LEFT);
107 end_bound.set_type(SelectionBound::RIGHT);
108 start_bound.SetEdge(start_top, start_bottom);
109 end_bound.SetEdge(end_top, end_bottom);
110 start_bound.set_visible(true);
111 end_bound.set_visible(true);
112 return controller_->OnSelectionBoundsUpdated(start_bound, end_bound);
113 }
114
115 bool ChangeInsertion(const gfx::Point& top, const gfx::Point& bottom) {
116 SelectionBound bound;
117 bound.set_type(SelectionBound::CENTER);
118 bound.SetEdge(top, bottom);
119 bound.set_visible(true);
120 return controller_->OnSelectionBoundsUpdated(bound, bound);
121 }
122
123 bool ClearSelection() {
124 return controller_->OnSelectionBoundsUpdated(SelectionBound(),
125 SelectionBound());
126 }
127
128 bool ClearInsertion() { return ClearSelection(); }
129
130 aura::Window* parent_window() const { return parent_window_.get(); }
131
132 TestTouchSelectionMenuRunner* menu_runner() const {
133 return menu_runner_.get();
134 }
135
136 TestTouchSelectionControllerAura* controller() const {
137 return controller_.get();
138 }
139
140 void OnEvent(Event* event) { controller_->OnEvent(event); }
141
142 private:
143 // aura::test::AuraTestBase:
144 void SetUp() override {
145 AuraTestBase::SetUp();
146
147 menu_runner_.reset(new TestTouchSelectionMenuRunner());
148
149 parent_window_.reset(CreateNormalWindow(0, root_window(), nullptr));
150 parent_window_->SetBounds(gfx::Rect(0, 0, 400, 400));
151
152 controller_.reset(new TestTouchSelectionControllerAura(this));
153 }
154
155 void TearDown() override {
156 controller_.reset();
157 parent_window_.reset();
158 menu_runner_.reset();
159
160 AuraTestBase::TearDown();
161 }
162
163 // TouchSelectionControllerAuraClient:
164 EventTarget* GetEventTarget() const override { return parent_window_.get(); }
165
166 void MoveCaret(const gfx::PointF& position) override {}
167
168 void MoveRangeSelectionExtent(const gfx::PointF& extent) override {}
169
170 void SelectBetweenCoordinates(const gfx::PointF& base,
171 const gfx::PointF& extent) override {}
172
173 aura::Window* GetParentWindow() const override {
174 return parent_window_.get();
175 }
176
177 gfx::Rect GetClientBounds() const override {
178 return parent_window_->bounds();
179 }
180
181 bool IsCommandIdEnabled(int command_id) const override { return true; }
182
183 void ExecuteCommand(int command_id, int event_flags) override {}
184
185 void OpenContextMenu(const gfx::PointF& point) override {}
186
187 scoped_ptr<aura::Window> parent_window_;
188 scoped_ptr<TestTouchSelectionControllerAura> controller_;
189 scoped_ptr<TestTouchSelectionMenuRunner> menu_runner_;
190
191 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerAuraTest);
192 };
193
194 // Tests if touch selection quick menu is shown when touch selection is
195 // activated and hidden when touch selection is deactivated.
196 TEST_F(TouchSelectionControllerAuraTest, QuickMenuShowHide) {
197 gfx::Point top(5, 5);
198 gfx::Point bottom(5, 15);
199
200 controller()->OnSelectionEditable(true);
201 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
202 OnEvent(&tap);
203 EXPECT_TRUE(ChangeInsertion(top, bottom));
204 EXPECT_TRUE(controller()->is_insertion_active());
205 EXPECT_FALSE(controller()->is_selection_active());
206 EXPECT_TRUE(menu_runner()->is_running());
207
208 EXPECT_TRUE(ClearInsertion());
209 EXPECT_FALSE(controller()->is_insertion_active());
210 EXPECT_FALSE(controller()->is_selection_active());
211 EXPECT_FALSE(menu_runner()->is_running());
212 }
213
214 // Tests if touch selection quick menu is hidden during a scroll.
215 TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnScroll) {
216 gfx::Point top(5, 5);
217 gfx::Point bottom(5, 15);
218
219 controller()->OnSelectionEditable(true);
220 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
221 OnEvent(&tap);
222 EXPECT_TRUE(ChangeInsertion(top, bottom));
223 EXPECT_TRUE(controller()->is_insertion_active());
224 EXPECT_FALSE(controller()->is_selection_active());
225 EXPECT_TRUE(menu_runner()->is_running());
226
227 GestureEventForTest scroll_begin(ET_GESTURE_SCROLL_BEGIN, top.x(), top.y());
228 OnEvent(&scroll_begin);
229 EXPECT_TRUE(controller()->is_insertion_active());
230 EXPECT_FALSE(controller()->is_selection_active());
231 EXPECT_FALSE(menu_runner()->is_running());
232
233 GestureEventForTest scroll_end(ET_GESTURE_SCROLL_END, top.x(), top.y());
234 OnEvent(&scroll_end);
235 EXPECT_TRUE(controller()->is_insertion_active());
236 EXPECT_FALSE(controller()->is_selection_active());
237 EXPECT_TRUE(menu_runner()->is_running());
238
239 EXPECT_TRUE(ClearInsertion());
240 EXPECT_FALSE(controller()->is_insertion_active());
241 EXPECT_FALSE(controller()->is_selection_active());
242 EXPECT_FALSE(menu_runner()->is_running());
243 }
244
245 // Tests if touch selection quick menu is hidden while a handle is being
246 // dragged.
247 TEST_F(TouchSelectionControllerAuraTest, QuickMenuHiddenOnHandleDrag) {
248 gfx::Point top(5, 5);
249 gfx::Point bottom(5, 15);
250
251 controller()->OnSelectionEditable(true);
252 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
253 OnEvent(&tap);
254 EXPECT_TRUE(ChangeInsertion(top, bottom));
255 EXPECT_TRUE(controller()->is_insertion_active());
256 EXPECT_FALSE(controller()->is_selection_active());
257 EXPECT_TRUE(menu_runner()->is_running());
258
259 gfx::RectF handle_bounds = controller()->last_drawable()->GetVisibleBounds();
260 gfx::Point drag_point = gfx::ToRoundedPoint(handle_bounds.CenterPoint());
261
262 TouchEventForTest touch_pressed(ET_TOUCH_PRESSED, drag_point);
263 OnEvent(&touch_pressed);
264 EXPECT_TRUE(controller()->is_insertion_active());
265 EXPECT_FALSE(controller()->is_selection_active());
266 EXPECT_FALSE(menu_runner()->is_running());
267
268 TouchEventForTest touch_released(ET_TOUCH_RELEASED, drag_point);
269 OnEvent(&touch_released);
270 EXPECT_TRUE(controller()->is_insertion_active());
271 EXPECT_FALSE(controller()->is_selection_active());
272 EXPECT_TRUE(menu_runner()->is_running());
273
274 EXPECT_TRUE(ClearInsertion());
275 EXPECT_FALSE(controller()->is_insertion_active());
276 EXPECT_FALSE(controller()->is_selection_active());
277 EXPECT_FALSE(menu_runner()->is_running());
278 }
279
280 // Tests if taps on selection in an editable text are handled properly.
281 TEST_F(TouchSelectionControllerAuraTest, TapOnEditableSelection) {
282 gfx::Point start_top(5, 5);
283 gfx::Point start_bottom(5, 15);
284 gfx::Point middle(15, 10);
285 gfx::Point end_top(25, 5);
286 gfx::Point end_bottom(25, 15);
287
288 controller()->OnSelectionEditable(true);
289 EXPECT_FALSE(ChangeSelection(start_top, start_bottom, end_top, end_bottom));
290 EXPECT_FALSE(controller()->is_insertion_active());
291 EXPECT_FALSE(controller()->is_selection_active());
292
293 // When touch selection is inactive, tapping on selection should consume the
294 // event and activate touch selection.
295 GestureEventForTest tap1(ET_GESTURE_TAP, middle.x(), middle.y());
296 OnEvent(&tap1);
297 EXPECT_TRUE(tap1.handled());
298 EXPECT_FALSE(controller()->is_insertion_active());
299 EXPECT_TRUE(controller()->is_selection_active());
300
301 // When touch selection is active, tapping on selection should leave the event
302 // unhandled, so that the event can be forwarded to the renderer.
303 GestureEventForTest tap2(ET_GESTURE_TAP, middle.x(), middle.y());
304 OnEvent(&tap2);
305 EXPECT_FALSE(tap2.handled());
306 EXPECT_FALSE(controller()->is_insertion_active());
307 EXPECT_TRUE(controller()->is_selection_active());
308
309 EXPECT_TRUE(ClearSelection());
310 EXPECT_FALSE(controller()->is_insertion_active());
311 EXPECT_FALSE(controller()->is_selection_active());
312 }
313
314 // Tests if taps on selection in a non-editable text are handled properly.
315 TEST_F(TouchSelectionControllerAuraTest, TapOnNonEditableSelection) {
316 gfx::Point start_top(5, 5);
317 gfx::Point start_bottom(5, 15);
318 gfx::Point middle(15, 10);
319 gfx::Point end_top(25, 5);
320 gfx::Point end_bottom(25, 15);
321
322 controller()->OnSelectionEditable(false);
323 EXPECT_FALSE(ChangeSelection(start_top, start_bottom, end_top, end_bottom));
324 EXPECT_FALSE(controller()->is_insertion_active());
325 EXPECT_FALSE(controller()->is_selection_active());
326
327 // When touch selection is inactive, tapping on selection should consume the
328 // event and activate touch selection.
329 GestureEventForTest tap1(ET_GESTURE_TAP, middle.x(), middle.y());
330 OnEvent(&tap1);
331 EXPECT_TRUE(tap1.handled());
332 EXPECT_FALSE(controller()->is_insertion_active());
333 EXPECT_TRUE(controller()->is_selection_active());
334
335 // When touch selection is active, tapping on selection should consume the
336 // event to prevent it from being forwarded to the renderer.
337 GestureEventForTest tap2(ET_GESTURE_TAP, middle.x(), middle.y());
338 OnEvent(&tap2);
339 EXPECT_TRUE(tap2.handled());
340 EXPECT_FALSE(controller()->is_insertion_active());
341 EXPECT_TRUE(controller()->is_selection_active());
342
343 EXPECT_TRUE(ClearSelection());
344 EXPECT_FALSE(controller()->is_insertion_active());
345 EXPECT_FALSE(controller()->is_selection_active());
346 }
347
348 // Tests if touch selection is deactivated on a key event.
349 TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnKeyEvent) {
350 gfx::Point top(5, 5);
351 gfx::Point bottom(5, 15);
352
353 RunAllPendingInMessageLoop();
354 controller()->OnSelectionEditable(true);
355 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
356 OnEvent(&tap);
357 EXPECT_TRUE(ChangeInsertion(top, bottom));
358 EXPECT_TRUE(controller()->is_insertion_active());
359 EXPECT_FALSE(controller()->is_selection_active());
360
361 test::EventGenerator generator(root_window());
362 generator.PressKey(VKEY_A, 0);
363 RunAllPendingInMessageLoop();
364 EXPECT_FALSE(controller()->is_insertion_active());
365 EXPECT_FALSE(controller()->is_selection_active());
366 }
367
368 // Tests if touch selection is deactivated on a mouse event.
369 TEST_F(TouchSelectionControllerAuraTest, DeactivatedOnMouseEvent) {
370 gfx::Point top(5, 5);
371 gfx::Point bottom(5, 15);
372
373 RunAllPendingInMessageLoop();
374 controller()->OnSelectionEditable(true);
375 GestureEventForTest tap(ET_GESTURE_TAP, top.x(), top.y());
376 OnEvent(&tap);
377 EXPECT_TRUE(ChangeInsertion(top, bottom));
378 EXPECT_TRUE(controller()->is_insertion_active());
379 EXPECT_FALSE(controller()->is_selection_active());
380
381 test::EventGenerator generator(root_window());
382 generator.set_current_location(top);
383 RunAllPendingInMessageLoop();
384 generator.MoveMouseTo(bottom);
385 RunAllPendingInMessageLoop();
386 EXPECT_FALSE(controller()->is_insertion_active());
387 EXPECT_FALSE(controller()->is_selection_active());
388 }
389
390 } // namespace ui
OLDNEW
« no previous file with comments | « ui/touch_selection/touch_selection_controller_aura_test_api.cc ('k') | ui/touch_selection/touch_selection_controller_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698