Merge lp:~elopio/autopilot/fix1257055-slow_drag into lp:~elopio/autopilot/fix1266601-Pointer-pressed-move

Proposed by Leo Arias
Status: Superseded
Proposed branch: lp:~elopio/autopilot/fix1257055-slow_drag
Merge into: lp:~elopio/autopilot/fix1266601-Pointer-pressed-move
Diff against target: 295 lines (+212/-16) (has conflicts)
3 files modified
autopilot/input/_X11.py (+2/-2)
autopilot/input/_uinput.py (+22/-12)
autopilot/tests/unit/test_input.py (+188/-2)
Text conflict in autopilot/tests/unit/test_input.py
To merge this branch: bzr merge lp:~elopio/autopilot/fix1257055-slow_drag
Reviewer Review Type Date Requested Status
Leo Arias Pending
Review via email: mp+202203@code.launchpad.net

This proposal has been superseded by a proposal from 2014-01-19.

Commit message

Added the drags with rate.

To post a comment you must log in.
421. By Leo Arias

Updated the copyright years.

422. By Leo Arias

Added the rate to the Pointer drag.

423. By Leo Arias

Renamed MockTouch to MockUinputTouch.

424. By Leo Arias

Merged with trunk.

425. By Leo Arias

Added python-evdev as a build-dep.

426. By Leo Arias

Merged with prerequisite branch.

427. By Leo Arias

Fixed the imports.

428. By Leo Arias

Added comments for the rate parameter.

429. By Leo Arias

Updated the tests.

430. By Leo Arias

Removed unused import.

431. By Leo Arias

Removed extra line.

432. By Leo Arias

s/should/must

433. By Leo Arias

Added a test with time_between_events.

434. By Leo Arias

We can't use the real Mouse, so switch to touch backend for now.

435. By Leo Arias

Updated the fake.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'autopilot/input/_X11.py'
--- autopilot/input/_X11.py 2013-11-07 05:53:36 +0000
+++ autopilot/input/_X11.py 2014-01-19 00:39:05 +0000
@@ -455,7 +455,7 @@
455 x, y = coord["root_x"], coord["root_y"]455 x, y = coord["root_x"], coord["root_y"]
456 return x, y456 return x, y
457457
458 def drag(self, x1, y1, x2, y2):458 def drag(self, x1, y1, x2, y2, rate=10):
459 """Performs a press, move and release.459 """Performs a press, move and release.
460460
461 This is to keep a common API between Mouse and Finger as long as461 This is to keep a common API between Mouse and Finger as long as
@@ -464,7 +464,7 @@
464 """464 """
465 self.move(x1, y1)465 self.move(x1, y1)
466 self.press()466 self.press()
467 self.move(x2, y2)467 self.move(x2, y2, rate=rate)
468 self.release()468 self.release()
469469
470 @classmethod470 @classmethod
471471
=== modified file 'autopilot/input/_uinput.py'
--- autopilot/input/_uinput.py 2013-11-07 05:53:36 +0000
+++ autopilot/input/_uinput.py 2014-01-19 00:39:05 +0000
@@ -361,23 +361,33 @@
361 raise RuntimeError("Attempting to move without finger being down.")361 raise RuntimeError("Attempting to move without finger being down.")
362 self._finger_move(x, y)362 self._finger_move(x, y)
363363
364 def drag(self, x1, y1, x2, y2):364 def drag(self, x1, y1, x2, y2, rate=10):
365 """Perform a drag gesture from (x1,y1) to (x2,y2)"""365 """Perform a drag gesture from (x1,y1) to (x2,y2)"""
366 logger.debug("Dragging from %d,%d to %d,%d", x1, y1, x2, y2)366 logger.debug("Dragging from %d,%d to %d,%d", x1, y1, x2, y2)
367 self._finger_down(x1, y1)367 self._finger_down(x1, y1)
368368
369 # Let's drag in 100 steps for now...369 current_x, current_y = x1, y1
370 dx = 1.0 * (x2 - x1) / 100370 while current_x != x2 or current_y != y2:
371 dy = 1.0 * (y2 - y1) / 100371 dx = abs(x2 - current_x)
372 cur_x = x1 + dx372 dy = abs(y2 - current_y)
373 cur_y = y1 + dy373
374 for i in range(0, 100):374 intx = float(dx) / max(dx, dy)
375 self._finger_move(int(cur_x), int(cur_y))375 inty = float(dy) / max(dx, dy)
376
377 step_x = min(rate * intx, dx)
378 step_y = min(rate * inty, dy)
379
380 if x2 < current_x:
381 step_x *= -1
382 if y2 < current_y:
383 step_y *= -1
384
385 current_x += step_x
386 current_y += step_y
387 self._finger_move(current_x, current_y)
388
376 sleep(0.002)389 sleep(0.002)
377 cur_x += dx390
378 cur_y += dy
379 # Make sure we actually end up at target
380 self._finger_move(x2, y2)
381 self._finger_up()391 self._finger_up()
382392
383 def _finger_down(self, x, y):393 def _finger_down(self, x, y):
384394
=== modified file 'autopilot/tests/unit/test_input.py'
--- autopilot/tests/unit/test_input.py 2014-01-07 00:21:08 +0000
+++ autopilot/tests/unit/test_input.py 2014-01-19 00:39:05 +0000
@@ -1,7 +1,7 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#2#
3# Autopilot Functional Test Tool3# Autopilot Functional Test Tool
4# Copyright (C) 2013 Canonical4# Copyright (C) 2013, 2014 Canonical
5#5#
6# This program is free software: you can redistribute it and/or modify6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by7# it under the terms of the GNU General Public License as published by
@@ -17,12 +17,18 @@
17# along with this program. If not, see <http://www.gnu.org/licenses/>.17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18#18#
1919
20from mock import patch20import testscenarios
21
22from mock import call, Mock, patch
21from testtools import TestCase23from testtools import TestCase
22from testtools.matchers import raises24from testtools.matchers import raises
2325
26<<<<<<< TREE
24from autopilot import input27from autopilot import input
25from autopilot.input import _uinput28from autopilot.input import _uinput
29=======
30from autopilot.input import _uinput, _X11
31>>>>>>> MERGE-SOURCE
26from autopilot.input._common import get_center_point32from autopilot.input._common import get_center_point
2733
2834
@@ -153,6 +159,7 @@
153159
154 self.assertEqual(123, x)160 self.assertEqual(123, x)
155 self.assertEqual(345, y)161 self.assertEqual(345, y)
162<<<<<<< TREE
156163
157164
158class PointerWithTouchBackendTestCase(TestCase):165class PointerWithTouchBackendTestCase(TestCase):
@@ -182,3 +189,182 @@
182 self.pointer.move(1, 1)189 self.pointer.move(1, 1)
183190
184 self.assertFalse(mock_move.called)191 self.assertFalse(mock_move.called)
192=======
193
194
195class PartialMock(object):
196 """Mock some of the methods of an object, and record their calls."""
197
198 def __init__(self, real_object, *args):
199 super(PartialMock, self).__init__()
200 self._mock_manager = Mock()
201 self._real_object = real_object
202 self.patched_attributes = args
203
204 def __getattr__(self, name):
205 """Forward all the calls to the real object."""
206 return self._real_object.__getattribute__(name)
207
208 @property
209 def mock_calls(self):
210 """Return the calls recorded for the mocked attributes."""
211 return self._mock_manager.mock_calls
212
213 def __enter__(self):
214 self._start_patchers()
215 return self
216
217 def _start_patchers(self):
218 self._patchers = []
219 for attribute in self.patched_attributes:
220 patcher = patch.object(self._real_object, attribute)
221 self._patchers.append(patcher)
222
223 self._mock_manager.attach_mock(patcher.start(), attribute)
224
225 def __exit__(self, exc_type, exc_val, exc_tb):
226 self._stop_patchers()
227
228 def _stop_patchers(self):
229 for patcher in self._patchers:
230 patcher.stop()
231
232
233class MockX11Mouse(PartialMock):
234 """Mock for the X11 Mouse Touch.
235
236 It records the calls to press, release and move, but doesn't perform them.
237
238 """
239
240 def __init__(self):
241 super(MockX11Mouse, self).__init__(
242 _X11.Mouse(), 'press', 'release', 'move')
243
244 def get_move_call_args_list(self):
245 return self._mock_manager.move.call_args_list
246
247
248class X11MouseTestCase(TestCase):
249
250 def test_drag_should_call_move_with_rate(self):
251 expected_first_move_call = call(0, 0)
252 expected_second_move_call = call(100, 100, rate=1)
253 with MockX11Mouse() as mock_mouse:
254 mock_mouse.drag(0, 0, 100, 100, rate=1)
255
256 self.assertEqual(
257 [expected_first_move_call, expected_second_move_call],
258 mock_mouse.get_move_call_args_list())
259
260 def test_drag_with_default_rate(self):
261 expected_first_move_call = call(0, 0)
262 expected_second_move_call = call(100, 100, rate=10)
263 with MockX11Mouse() as mock_mouse:
264 mock_mouse.drag(0, 0, 100, 100)
265
266 self.assertEqual(
267 [expected_first_move_call, expected_second_move_call],
268 mock_mouse.get_move_call_args_list())
269
270
271class MockTouch(PartialMock):
272 """Mock for the uinput Touch.
273
274 It records the calls to _finger_down, _finger_up and _finger_move, but
275 doesn't perform them.
276
277 """
278
279 def __init__(self):
280 super(MockTouch, self).__init__(
281 _uinput.Touch(), '_finger_down', '_finger_up', '_finger_move')
282
283 def get_finger_move_call_args_list(self):
284 return self._mock_manager._finger_move.call_args_list
285
286
287class UinputTouchTestCase(TestCase):
288
289 def test_drag_finger_actions(self):
290 expected_finger_calls = [
291 call._finger_down(0, 0),
292 call._finger_move(10, 10),
293 call._finger_up()
294 ]
295 with MockTouch() as mock_touch:
296 mock_touch.drag(0, 0, 10, 10)
297 self.assertEqual(mock_touch.mock_calls, expected_finger_calls)
298
299 def test_drag_should_call_move_with_rate(self):
300 expected_move_calls = [call(5, 5), call(10, 10), call(15, 15)]
301 with MockTouch() as mock_touch:
302 mock_touch.drag(0, 0, 15, 15, rate=5)
303
304 self.assertEqual(
305 expected_move_calls, mock_touch.get_finger_move_call_args_list())
306
307 def test_drag_with_default_rate(self):
308 expected_move_calls = [call(10, 10), call(20, 20)]
309 with MockTouch() as mock_touch:
310 mock_touch.drag(0, 0, 20, 20)
311
312 self.assertEqual(
313 expected_move_calls, mock_touch.get_finger_move_call_args_list())
314
315 def test_drag_to_same_place_should_not_move(self):
316 expected_finger_calls = [
317 call._finger_down(0, 0),
318 call._finger_up()
319 ]
320 with MockTouch() as mock_touch:
321 mock_touch.drag(0, 0, 0, 0)
322 self.assertEqual(mock_touch.mock_calls, expected_finger_calls)
323
324
325class DragUinputTouchTestCase(testscenarios.TestWithScenarios, TestCase):
326
327 scenarios = [
328 ('drag to top', dict(
329 start_x=50, start_y=50, stop_x=50, stop_y=30,
330 expected_moves=[call(50, 40), call(50, 30)])),
331 ('drag to bottom', dict(
332 start_x=50, start_y=50, stop_x=50, stop_y=70,
333 expected_moves=[call(50, 60), call(50, 70)])),
334 ('drag to left', dict(
335 start_x=50, start_y=50, stop_x=30, stop_y=50,
336 expected_moves=[call(40, 50), call(30, 50)])),
337 ('drag to right', dict(
338 start_x=50, start_y=50, stop_x=70, stop_y=50,
339 expected_moves=[call(60, 50), call(70, 50)])),
340
341 ('drag to top-left', dict(
342 start_x=50, start_y=50, stop_x=30, stop_y=30,
343 expected_moves=[call(40, 40), call(30, 30)])),
344 ('drag to top-right', dict(
345 start_x=50, start_y=50, stop_x=70, stop_y=30,
346 expected_moves=[call(60, 40), call(70, 30)])),
347 ('drag to bottom-left', dict(
348 start_x=50, start_y=50, stop_x=30, stop_y=70,
349 expected_moves=[call(40, 60), call(30, 70)])),
350 ('drag to bottom-right', dict(
351 start_x=50, start_y=50, stop_x=70, stop_y=70,
352 expected_moves=[call(60, 60), call(70, 70)])),
353
354 ('drag less than rate', dict(
355 start_x=50, start_y=50, stop_x=55, stop_y=55,
356 expected_moves=[call(55, 55)])),
357
358 ('drag with last move less than rate', dict(
359 start_x=50, start_y=50, stop_x=65, stop_y=65,
360 expected_moves=[call(60, 60), call(65, 65)])),
361 ]
362
363 def test_drag_moves(self):
364 with MockTouch() as mock_touch:
365 mock_touch.drag(
366 self.start_x, self.start_y, self.stop_x, self.stop_y)
367
368 self.assertEqual(
369 self.expected_moves, mock_touch.get_finger_move_call_args_list())
370>>>>>>> MERGE-SOURCE

Subscribers

People subscribed via source and target branches

to all changes: