from __future__ import unicode_literals
from prompt_toolkit.key_binding.input_processor import InputProcessor, KeyPress
from prompt_toolkit.key_binding.registry import Registry
from prompt_toolkit.keys import Keys
import pytest
class Handlers(object):
def __init__(self):
self.called = []
def __getattr__(self, name):
def func(event):
self.called.append(name)
return func
@pytest.fixture
def handlers():
return Handlers()
@pytest.fixture
def registry(handlers):
registry = Registry()
registry.add_binding(
Keys.ControlX, Keys.ControlC)(handlers.controlx_controlc)
registry.add_binding(Keys.ControlX)(handlers.control_x)
registry.add_binding(Keys.ControlD)(handlers.control_d)
registry.add_binding(
Keys.ControlSquareClose, Keys.Any)(handlers.control_square_close_any)
return registry
@pytest.fixture
def processor(registry):
return InputProcessor(registry, lambda: None)
def test_feed_simple(processor, handlers):
processor.feed(KeyPress(Keys.ControlX, '\x18'))
processor.feed(KeyPress(Keys.ControlC, '\x03'))
processor.process_keys()
assert handlers.called == ['controlx_controlc']
def test_feed_several(processor, handlers):
# First an unknown key first.
processor.feed(KeyPress(Keys.ControlQ, ''))
processor.process_keys()
assert handlers.called == []
# Followed by a know key sequence.
processor.feed(KeyPress(Keys.ControlX, ''))
processor.feed(KeyPress(Keys.ControlC, ''))
processor.process_keys()
assert handlers.called == ['controlx_controlc']
# Followed by another unknown sequence.
processor.feed(KeyPress(Keys.ControlR, ''))
processor.feed(KeyPress(Keys.ControlS, ''))
# Followed again by a know key sequence.
processor.feed(KeyPress(Keys.ControlD, ''))
processor.process_keys()
assert handlers.called == ['controlx_controlc', 'control_d']
def test_control_square_closed_any(processor, handlers):
processor.feed(KeyPress(Keys.ControlSquareClose, ''))
processor.feed(KeyPress('C', 'C'))
processor.process_keys()
assert handlers.called == ['control_square_close_any']
def test_common_prefix(processor, handlers):
# Sending Control_X should not yet do anything, because there is
# another sequence starting with that as well.
processor.feed(KeyPress(Keys.ControlX, ''))
processor.process_keys()
assert handlers.called == []
# When another key is pressed, we know that we did not meant the longer
# "ControlX ControlC" sequence and the callbacks are called.
processor.feed(KeyPress(Keys.ControlD, ''))
processor.process_keys()
assert handlers.called == ['control_x', 'control_d']
def test_previous_key_sequence(processor, handlers):
"""
test whether we receive the correct previous_key_sequence.
"""
events = []
def handler(event):
events.append(event)
# Build registry.
registry = Registry()
registry.add_binding('a', 'a')(handler)
registry.add_binding('b', 'b')(handler)
processor = InputProcessor(registry, lambda: None)
# Create processor and feed keys.
processor.feed(KeyPress('a', 'a'))
processor.feed(KeyPress('a', 'a'))
processor.feed(KeyPress('b', 'b'))
processor.feed(KeyPress('b', 'b'))
processor.process_keys()
# Test.
assert len(events) == 2
assert len(events[0].key_sequence) == 2
assert events[0].key_sequence[0].key == 'a'
assert events[0].key_sequence[0].data == 'a'
assert events[0].key_sequence[1].key == 'a'
assert events[0].key_sequence[1].data == 'a'
assert events[0].previous_key_sequence == []
assert len(events[1].key_sequence) == 2
assert events[1].key_sequence[0].key == 'b'
assert events[1].key_sequence[0].data == 'b'
assert events[1].key_sequence[1].key == 'b'
assert events[1].key_sequence[1].data == 'b'
assert len(events[1].previous_key_sequence) == 2
assert events[1].previous_key_sequence[0].key == 'a'
assert events[1].previous_key_sequence[0].data == 'a'
assert events[1].previous_key_sequence[1].key == 'a'
assert events[1].previous_key_sequence[1].data == 'a'