test_key_binding.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import pytest
  2. from prompt_toolkit.application import Application
  3. from prompt_toolkit.application.current import set_app
  4. from prompt_toolkit.input.defaults import create_pipe_input
  5. from prompt_toolkit.key_binding.key_bindings import KeyBindings
  6. from prompt_toolkit.key_binding.key_processor import KeyPress, KeyProcessor
  7. from prompt_toolkit.keys import Keys
  8. from prompt_toolkit.layout import Layout, Window
  9. from prompt_toolkit.output import DummyOutput
  10. class Handlers(object):
  11. def __init__(self):
  12. self.called = []
  13. def __getattr__(self, name):
  14. def func(event):
  15. self.called.append(name)
  16. return func
  17. def set_dummy_app():
  18. """
  19. Return a context manager that makes sure that this dummy application is
  20. active. This is important, because we need an `Application` with
  21. `is_done=False` flag, otherwise no keys will be processed.
  22. """
  23. app = Application(
  24. layout=Layout(Window()), output=DummyOutput(), input=create_pipe_input()
  25. )
  26. return set_app(app)
  27. @pytest.fixture
  28. def handlers():
  29. return Handlers()
  30. @pytest.fixture
  31. def bindings(handlers):
  32. bindings = KeyBindings()
  33. bindings.add(Keys.ControlX, Keys.ControlC)(handlers.controlx_controlc)
  34. bindings.add(Keys.ControlX)(handlers.control_x)
  35. bindings.add(Keys.ControlD)(handlers.control_d)
  36. bindings.add(Keys.ControlSquareClose, Keys.Any)(handlers.control_square_close_any)
  37. return bindings
  38. @pytest.fixture
  39. def processor(bindings):
  40. return KeyProcessor(bindings)
  41. def test_remove_bindings(handlers):
  42. with set_dummy_app():
  43. h = handlers.controlx_controlc
  44. h2 = handlers.controld
  45. # Test passing a handler to the remove() function.
  46. bindings = KeyBindings()
  47. bindings.add(Keys.ControlX, Keys.ControlC)(h)
  48. bindings.add(Keys.ControlD)(h2)
  49. assert len(bindings.bindings) == 2
  50. bindings.remove(h)
  51. assert len(bindings.bindings) == 1
  52. # Test passing a key sequence to the remove() function.
  53. bindings = KeyBindings()
  54. bindings.add(Keys.ControlX, Keys.ControlC)(h)
  55. bindings.add(Keys.ControlD)(h2)
  56. assert len(bindings.bindings) == 2
  57. bindings.remove(Keys.ControlX, Keys.ControlC)
  58. assert len(bindings.bindings) == 1
  59. def test_feed_simple(processor, handlers):
  60. with set_dummy_app():
  61. processor.feed(KeyPress(Keys.ControlX, "\x18"))
  62. processor.feed(KeyPress(Keys.ControlC, "\x03"))
  63. processor.process_keys()
  64. assert handlers.called == ["controlx_controlc"]
  65. def test_feed_several(processor, handlers):
  66. with set_dummy_app():
  67. # First an unknown key first.
  68. processor.feed(KeyPress(Keys.ControlQ, ""))
  69. processor.process_keys()
  70. assert handlers.called == []
  71. # Followed by a know key sequence.
  72. processor.feed(KeyPress(Keys.ControlX, ""))
  73. processor.feed(KeyPress(Keys.ControlC, ""))
  74. processor.process_keys()
  75. assert handlers.called == ["controlx_controlc"]
  76. # Followed by another unknown sequence.
  77. processor.feed(KeyPress(Keys.ControlR, ""))
  78. processor.feed(KeyPress(Keys.ControlS, ""))
  79. # Followed again by a know key sequence.
  80. processor.feed(KeyPress(Keys.ControlD, ""))
  81. processor.process_keys()
  82. assert handlers.called == ["controlx_controlc", "control_d"]
  83. def test_control_square_closed_any(processor, handlers):
  84. with set_dummy_app():
  85. processor.feed(KeyPress(Keys.ControlSquareClose, ""))
  86. processor.feed(KeyPress("C", "C"))
  87. processor.process_keys()
  88. assert handlers.called == ["control_square_close_any"]
  89. def test_common_prefix(processor, handlers):
  90. with set_dummy_app():
  91. # Sending Control_X should not yet do anything, because there is
  92. # another sequence starting with that as well.
  93. processor.feed(KeyPress(Keys.ControlX, ""))
  94. processor.process_keys()
  95. assert handlers.called == []
  96. # When another key is pressed, we know that we did not meant the longer
  97. # "ControlX ControlC" sequence and the callbacks are called.
  98. processor.feed(KeyPress(Keys.ControlD, ""))
  99. processor.process_keys()
  100. assert handlers.called == ["control_x", "control_d"]
  101. def test_previous_key_sequence(processor):
  102. """
  103. test whether we receive the correct previous_key_sequence.
  104. """
  105. with set_dummy_app():
  106. events = []
  107. def handler(event):
  108. events.append(event)
  109. # Build registry.
  110. registry = KeyBindings()
  111. registry.add("a", "a")(handler)
  112. registry.add("b", "b")(handler)
  113. processor = KeyProcessor(registry)
  114. # Create processor and feed keys.
  115. processor.feed(KeyPress("a", "a"))
  116. processor.feed(KeyPress("a", "a"))
  117. processor.feed(KeyPress("b", "b"))
  118. processor.feed(KeyPress("b", "b"))
  119. processor.process_keys()
  120. # Test.
  121. assert len(events) == 2
  122. assert len(events[0].key_sequence) == 2
  123. assert events[0].key_sequence[0].key == "a"
  124. assert events[0].key_sequence[0].data == "a"
  125. assert events[0].key_sequence[1].key == "a"
  126. assert events[0].key_sequence[1].data == "a"
  127. assert events[0].previous_key_sequence == []
  128. assert len(events[1].key_sequence) == 2
  129. assert events[1].key_sequence[0].key == "b"
  130. assert events[1].key_sequence[0].data == "b"
  131. assert events[1].key_sequence[1].key == "b"
  132. assert events[1].key_sequence[1].data == "b"
  133. assert len(events[1].previous_key_sequence) == 2
  134. assert events[1].previous_key_sequence[0].key == "a"
  135. assert events[1].previous_key_sequence[0].data == "a"
  136. assert events[1].previous_key_sequence[1].key == "a"
  137. assert events[1].previous_key_sequence[1].data == "a"