_mouse_tests.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. # -*- coding: utf-8 -*-
  2. import unittest
  3. import time
  4. from ._mouse_event import MoveEvent, ButtonEvent, WheelEvent, LEFT, RIGHT, MIDDLE, X, X2, UP, DOWN, DOUBLE
  5. from keyboard import mouse
  6. class FakeOsMouse(object):
  7. def __init__(self):
  8. self.append = None
  9. self.position = (0, 0)
  10. self.queue = None
  11. self.init = lambda: None
  12. def listen(self, queue):
  13. self.listening = True
  14. self.queue = queue
  15. def press(self, button):
  16. self.append((DOWN, button))
  17. def release(self, button):
  18. self.append((UP, button))
  19. def get_position(self):
  20. return self.position
  21. def move_to(self, x, y):
  22. self.append(('move', (x, y)))
  23. self.position = (x, y)
  24. def wheel(self, delta):
  25. self.append(('wheel', delta))
  26. def move_relative(self, x, y):
  27. self.position = (self.position[0] + x, self.position[1] + y)
  28. class TestMouse(unittest.TestCase):
  29. @staticmethod
  30. def setUpClass():
  31. mouse._os_mouse= FakeOsMouse()
  32. mouse._listener.start_if_necessary()
  33. assert mouse._os_mouse.listening
  34. def setUp(self):
  35. self.events = []
  36. mouse._pressed_events.clear()
  37. mouse._os_mouse.append = self.events.append
  38. def tearDown(self):
  39. mouse.unhook_all()
  40. # Make sure there's no spill over between tests.
  41. self.wait_for_events_queue()
  42. def wait_for_events_queue(self):
  43. mouse._listener.queue.join()
  44. def flush_events(self):
  45. self.wait_for_events_queue()
  46. events = list(self.events)
  47. # Ugly, but requried to work in Python2. Python3 has list.clear
  48. del self.events[:]
  49. return events
  50. def press(self, button=LEFT):
  51. mouse._os_mouse.queue.put(ButtonEvent(DOWN, button, time.time()))
  52. self.wait_for_events_queue()
  53. def release(self, button=LEFT):
  54. mouse._os_mouse.queue.put(ButtonEvent(UP, button, time.time()))
  55. self.wait_for_events_queue()
  56. def double_click(self, button=LEFT):
  57. mouse._os_mouse.queue.put(ButtonEvent(DOUBLE, button, time.time()))
  58. self.wait_for_events_queue()
  59. def click(self, button=LEFT):
  60. self.press(button)
  61. self.release(button)
  62. def wheel(self, delta=1):
  63. mouse._os_mouse.queue.put(WheelEvent(delta, time.time()))
  64. self.wait_for_events_queue()
  65. def move(self, x=0, y=0):
  66. mouse._os_mouse.queue.put(MoveEvent(x, y, time.time()))
  67. self.wait_for_events_queue()
  68. def test_hook(self):
  69. events = []
  70. self.press()
  71. mouse.hook(events.append)
  72. self.press()
  73. mouse.unhook(events.append)
  74. self.press()
  75. self.assertEqual(len(events), 1)
  76. def test_is_pressed(self):
  77. self.assertFalse(mouse.is_pressed())
  78. self.press()
  79. self.assertTrue(mouse.is_pressed())
  80. self.release()
  81. self.press(X2)
  82. self.assertFalse(mouse.is_pressed())
  83. self.assertTrue(mouse.is_pressed(X2))
  84. self.press(X2)
  85. self.assertTrue(mouse.is_pressed(X2))
  86. self.release(X2)
  87. self.release(X2)
  88. self.assertFalse(mouse.is_pressed(X2))
  89. def test_buttons(self):
  90. mouse.press()
  91. self.assertEqual(self.flush_events(), [(DOWN, LEFT)])
  92. mouse.release()
  93. self.assertEqual(self.flush_events(), [(UP, LEFT)])
  94. mouse.click()
  95. self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT)])
  96. mouse.double_click()
  97. self.assertEqual(self.flush_events(), [(DOWN, LEFT), (UP, LEFT), (DOWN, LEFT), (UP, LEFT)])
  98. mouse.right_click()
  99. self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)])
  100. mouse.click(RIGHT)
  101. self.assertEqual(self.flush_events(), [(DOWN, RIGHT), (UP, RIGHT)])
  102. mouse.press(X2)
  103. self.assertEqual(self.flush_events(), [(DOWN, X2)])
  104. def test_position(self):
  105. self.assertEqual(mouse.get_position(), mouse._os_mouse.get_position())
  106. def test_move(self):
  107. mouse.move(0, 0)
  108. self.assertEqual(mouse._os_mouse.get_position(), (0, 0))
  109. mouse.move(100, 500)
  110. self.assertEqual(mouse._os_mouse.get_position(), (100, 500))
  111. mouse.move(1, 2, False)
  112. self.assertEqual(mouse._os_mouse.get_position(), (101, 502))
  113. mouse.move(0, 0)
  114. mouse.move(100, 499, True, duration=0.01)
  115. self.assertEqual(mouse._os_mouse.get_position(), (100, 499))
  116. mouse.move(100, 1, False, duration=0.01)
  117. self.assertEqual(mouse._os_mouse.get_position(), (200, 500))
  118. mouse.move(0, 0, False, duration=0.01)
  119. self.assertEqual(mouse._os_mouse.get_position(), (200, 500))
  120. def triggers(self, fn, events, **kwargs):
  121. self.triggered = False
  122. def callback():
  123. self.triggered = True
  124. handler = fn(callback, **kwargs)
  125. for event_type, arg in events:
  126. if event_type == DOWN:
  127. self.press(arg)
  128. elif event_type == UP:
  129. self.release(arg)
  130. elif event_type == DOUBLE:
  131. self.double_click(arg)
  132. elif event_type == 'WHEEL':
  133. self.wheel()
  134. mouse._listener.remove_handler(handler)
  135. return self.triggered
  136. def test_on_button(self):
  137. self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)]))
  138. self.assertTrue(self.triggers(mouse.on_button, [(DOWN, RIGHT)]))
  139. self.assertTrue(self.triggers(mouse.on_button, [(DOWN, X)]))
  140. self.assertFalse(self.triggers(mouse.on_button, [('WHEEL', '')]))
  141. self.assertFalse(self.triggers(mouse.on_button, [(DOWN, X)], buttons=MIDDLE))
  142. self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE))
  143. self.assertTrue(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE))
  144. self.assertFalse(self.triggers(mouse.on_button, [(DOWN, MIDDLE)], buttons=MIDDLE, types=UP))
  145. self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=MIDDLE, types=UP))
  146. self.assertTrue(self.triggers(mouse.on_button, [(UP, MIDDLE)], buttons=[MIDDLE, LEFT], types=[UP, DOWN]))
  147. self.assertTrue(self.triggers(mouse.on_button, [(DOWN, LEFT)], buttons=[MIDDLE, LEFT], types=[UP, DOWN]))
  148. self.assertFalse(self.triggers(mouse.on_button, [(UP, X)], buttons=[MIDDLE, LEFT], types=[UP, DOWN]))
  149. def test_ons(self):
  150. self.assertTrue(self.triggers(mouse.on_click, [(UP, LEFT)]))
  151. self.assertFalse(self.triggers(mouse.on_click, [(UP, RIGHT)]))
  152. self.assertFalse(self.triggers(mouse.on_click, [(DOWN, LEFT)]))
  153. self.assertFalse(self.triggers(mouse.on_click, [(DOWN, RIGHT)]))
  154. self.assertTrue(self.triggers(mouse.on_double_click, [(DOUBLE, LEFT)]))
  155. self.assertFalse(self.triggers(mouse.on_double_click, [(DOUBLE, RIGHT)]))
  156. self.assertFalse(self.triggers(mouse.on_double_click, [(DOWN, RIGHT)]))
  157. self.assertTrue(self.triggers(mouse.on_right_click, [(UP, RIGHT)]))
  158. self.assertTrue(self.triggers(mouse.on_middle_click, [(UP, MIDDLE)]))
  159. def test_wait(self):
  160. # If this fails it blocks. Unfortunately, but I see no other way of testing.
  161. from threading import Thread, Lock
  162. lock = Lock()
  163. lock.acquire()
  164. def t():
  165. mouse.wait()
  166. lock.release()
  167. Thread(target=t).start()
  168. self.press()
  169. lock.acquire()
  170. def test_record_play(self):
  171. from threading import Thread, Lock
  172. lock = Lock()
  173. lock.acquire()
  174. def t():
  175. self.recorded = mouse.record(RIGHT)
  176. lock.release()
  177. Thread(target=t).start()
  178. self.click()
  179. self.wheel(5)
  180. self.move(100, 50)
  181. self.press(RIGHT)
  182. lock.acquire()
  183. self.assertEqual(len(self.recorded), 5)
  184. self.assertEqual(self.recorded[0]._replace(time=None), ButtonEvent(DOWN, LEFT, None))
  185. self.assertEqual(self.recorded[1]._replace(time=None), ButtonEvent(UP, LEFT, None))
  186. self.assertEqual(self.recorded[2]._replace(time=None), WheelEvent(5, None))
  187. self.assertEqual(self.recorded[3]._replace(time=None), MoveEvent(100, 50, None))
  188. self.assertEqual(self.recorded[4]._replace(time=None), ButtonEvent(DOWN, RIGHT, None))
  189. mouse.play(self.recorded, speed_factor=0)
  190. events = self.flush_events()
  191. self.assertEqual(len(events), 5)
  192. self.assertEqual(events[0], (DOWN, LEFT))
  193. self.assertEqual(events[1], (UP, LEFT))
  194. self.assertEqual(events[2], ('wheel', 5))
  195. self.assertEqual(events[3], ('move', (100, 50)))
  196. self.assertEqual(events[4], (DOWN, RIGHT))
  197. mouse.play(self.recorded)
  198. events = self.flush_events()
  199. self.assertEqual(len(events), 5)
  200. self.assertEqual(events[0], (DOWN, LEFT))
  201. self.assertEqual(events[1], (UP, LEFT))
  202. self.assertEqual(events[2], ('wheel', 5))
  203. self.assertEqual(events[3], ('move', (100, 50)))
  204. self.assertEqual(events[4], (DOWN, RIGHT))
  205. mouse.play(self.recorded, include_clicks=False)
  206. events = self.flush_events()
  207. self.assertEqual(len(events), 2)
  208. self.assertEqual(events[0], ('wheel', 5))
  209. self.assertEqual(events[1], ('move', (100, 50)))
  210. mouse.play(self.recorded, include_moves=False)
  211. events = self.flush_events()
  212. self.assertEqual(len(events), 4)
  213. self.assertEqual(events[0], (DOWN, LEFT))
  214. self.assertEqual(events[1], (UP, LEFT))
  215. self.assertEqual(events[2], ('wheel', 5))
  216. self.assertEqual(events[3], (DOWN, RIGHT))
  217. mouse.play(self.recorded, include_wheel=False)
  218. events = self.flush_events()
  219. self.assertEqual(len(events), 4)
  220. self.assertEqual(events[0], (DOWN, LEFT))
  221. self.assertEqual(events[1], (UP, LEFT))
  222. self.assertEqual(events[2], ('move', (100, 50)))
  223. self.assertEqual(events[3], (DOWN, RIGHT))
  224. if __name__ == '__main__':
  225. unittest.main()