diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py index 23d705dcc..df40ecfc2 100644 --- a/tests/helpers/fixtures.py +++ b/tests/helpers/fixtures.py @@ -226,33 +226,11 @@ def default_config(): @pytest.fixture -def key_config_stub(stubs): +def key_config_stub(config_stub, monkeypatch): """Fixture which provides a fake key config object.""" - # FIXME:conf - # class KeyConfigStub: - # - # """Stub for the key-config object.""" - # - # def __init__(self): - # self.bindings = {} - # - # def get_bindings_for(self, section): - # return self.bindings.get(section) - # - # def set_bindings_for(self, section, bindings): - # self.bindings[section] = bindings - # - # def get_reverse_bindings_for(self, section): - # """Get a dict of commands to a list of bindings for the section.""" - # cmd_to_keys = collections.defaultdict(list) - # for key, cmd in self.bindings[section].items(): - # # put special bindings last - # if utils.is_special_key(key): - # cmd_to_keys[cmd].append(key) - # else: - # cmd_to_keys[cmd].insert(0, key) - # return cmd_to_keys - return None + keyconf = config.KeyConfig(config_stub) + monkeypatch.setattr(config, 'key_instance', keyconf) + return keyconf @pytest.fixture diff --git a/tests/unit/keyinput/conftest.py b/tests/unit/keyinput/conftest.py index 59bad5c61..18bac33bb 100644 --- a/tests/unit/keyinput/conftest.py +++ b/tests/unit/keyinput/conftest.py @@ -23,25 +23,23 @@ from unittest import mock import pytest +import qutebrowser.app # to run decorators from qutebrowser.utils import objreg -BINDINGS = {'test': {'': 'ctrla', - 'a': 'a', - 'ba': 'ba', - 'ax': 'ax', - 'ccc': 'ccc', - '0': '0'}, - 'test2': {'foo': 'bar', '': 'ctrlx'}, - 'normal': {'a': 'a', 'ba': 'ba'}} +BINDINGS = {'prompt': {'': 'message-info ctrla', + 'a': 'message-info a', + 'ba': 'message-info ba', + 'ax': 'message-info ax', + 'ccc': 'message-info ccc', + '0': 'message-info 0'}, + 'command': {'foo': 'message-info bar', + '': 'message-info ctrlx'}, + 'normal': {'a': 'message-info a', 'ba': 'message-info ba'}} @pytest.fixture -def fake_keyconfig(): - """Create a mock of a KeyConfiguration and register it into objreg.""" - bindings = dict(BINDINGS) # so the bindings can be changed later - fake_keyconfig = mock.Mock(spec=['get_bindings_for']) - fake_keyconfig.get_bindings_for.side_effect = lambda s: bindings[s] - objreg.register('key-config', fake_keyconfig) - yield bindings - objreg.delete('key-config') +def keyinput_bindings(config_stub, key_config_stub): + """Register some test bindings.""" + config_stub.val.bindings.default = {} + config_stub.val.bindings.commands = dict(BINDINGS) diff --git a/tests/unit/keyinput/test_basekeyparser.py b/tests/unit/keyinput/test_basekeyparser.py index f8494ed2b..1df5e73c6 100644 --- a/tests/unit/keyinput/test_basekeyparser.py +++ b/tests/unit/keyinput/test_basekeyparser.py @@ -30,11 +30,8 @@ from qutebrowser.keyinput import basekeyparser from qutebrowser.utils import utils -CONFIG = {'input': {'timeout': 100}} - - @pytest.fixture -def keyparser(): +def keyparser(key_config_stub): """Fixture providing a BaseKeyParser supporting count/chains.""" kp = basekeyparser.BaseKeyParser( 0, supports_count=True, supports_chains=True) @@ -61,7 +58,8 @@ def handle_text(fake_keyevent_factory, keyparser): (False, True, False, True), (None, True, True, True), ]) -def test_supports_args(count, chains, count_expected, chains_expected): +def test_supports_args(config_stub, count, chains, count_expected, + chains_expected): kp = basekeyparser.BaseKeyParser( 0, supports_count=count, supports_chains=chains) assert kp._supports_count == count_expected @@ -93,64 +91,59 @@ class TestDebugLog: ('foo', True, (None, 'foo')), ('10foo', False, (None, '10foo')), ]) -def test_split_count(input_key, supports_count, expected): +def test_split_count(config_stub, input_key, supports_count, expected): kp = basekeyparser.BaseKeyParser(0, supports_count=supports_count) kp._keystring = input_key assert kp._split_count() == expected -@pytest.mark.usefixtures('fake_keyconfig') +@pytest.mark.usefixtures('keyinput_bindings') class TestReadConfig: def test_read_config_invalid(self, keyparser): """Test reading config without setting modename before.""" with pytest.raises(ValueError): - keyparser.read_config() + keyparser._read_config() def test_read_config_modename(self, keyparser): """Test reading config with _modename set.""" keyparser._modename = 'normal' - keyparser.read_config() + keyparser._read_config() assert 'a' in keyparser.bindings def test_read_config_valid(self, keyparser): """Test reading config.""" - keyparser.read_config('test') + keyparser._read_config('prompt') assert 'ccc' in keyparser.bindings assert 'ctrl+a' in keyparser.special_bindings - keyparser.read_config('test2') + keyparser._read_config('command') assert 'ccc' not in keyparser.bindings assert 'ctrl+a' not in keyparser.special_bindings assert 'foo' in keyparser.bindings assert 'ctrl+x' in keyparser.special_bindings - def test_on_keyconfig_changed_modename_none(self, keyparser): + def test_read_config_modename_none(self, keyparser): assert keyparser._modename is None # No config set so self._modename is None - with pytest.raises(AssertionError, match="on_keyconfig_changed called " - "but no section defined!"): - keyparser.on_keyconfig_changed('normal') + with pytest.raises(ValueError, match="read_config called with no mode " + "given, but None defined so far!"): + keyparser._read_config(None) - @pytest.mark.parametrize('mode,changed_mode, expected', [ - ('normal', 'normal', True), ('normal', 'normal2', False), + @pytest.mark.parametrize('mode, changed_mode, expected', [ + ('normal', 'normal', True), ('normal', 'command', False), ]) - def test_on_keyconfig_changed(self, keyparser, fake_keyconfig, mode, - changed_mode, expected): - keyparser.read_config(mode) + def test_read_config(self, keyparser, key_config_stub, + mode, changed_mode, expected): + keyparser._read_config(mode) # Sanity checks assert 'a' in keyparser.bindings assert 'new' not in keyparser.bindings - fake_keyconfig['normal'] = {'new': 'new'} - keyparser.on_keyconfig_changed(changed_mode) + key_config_stub.bind('new', 'message-info new', mode=changed_mode) - if expected: - assert 'a' not in keyparser.bindings - assert 'new' in keyparser.bindings - else: - assert 'a' in keyparser.bindings - assert 'new' not in keyparser.bindings + assert 'a' in keyparser.bindings + assert ('new' in keyparser.bindings) == expected @pytest.mark.parametrize('warn_on_keychains', [True, False]) def test_warn_on_keychains(self, caplog, warn_on_keychains): @@ -160,7 +153,7 @@ class TestReadConfig: kp._warn_on_keychains = warn_on_keychains with caplog.at_level(logging.WARNING): - kp.read_config('normal') + kp._read_config('normal') assert bool(caplog.records) == warn_on_keychains @@ -170,8 +163,8 @@ class TestSpecialKeys: """Check execute() with special keys.""" @pytest.fixture(autouse=True) - def read_config(self, fake_keyconfig, keyparser): - keyparser.read_config('test') + def read_config(self, keyinput_bindings, keyparser): + keyparser._read_config('prompt') def test_valid_key(self, fake_keyevent_factory, keyparser): if sys.platform == 'darwin': @@ -181,7 +174,7 @@ class TestSpecialKeys: keyparser.handle(fake_keyevent_factory(Qt.Key_A, modifier)) keyparser.handle(fake_keyevent_factory(Qt.Key_X, modifier)) keyparser.execute.assert_called_once_with( - 'ctrla', keyparser.Type.special, None) + 'message-info ctrla', keyparser.Type.special, None) def test_valid_key_count(self, fake_keyevent_factory, keyparser): if sys.platform == 'darwin': @@ -191,7 +184,7 @@ class TestSpecialKeys: keyparser.handle(fake_keyevent_factory(5, text='5')) keyparser.handle(fake_keyevent_factory(Qt.Key_A, modifier, text='A')) keyparser.execute.assert_called_once_with( - 'ctrla', keyparser.Type.special, 5) + 'message-info ctrla', keyparser.Type.special, 5) def test_invalid_key(self, fake_keyevent_factory, keyparser): keyparser.handle(fake_keyevent_factory( @@ -214,8 +207,8 @@ class TestKeyChain: """Test execute() with keychain support.""" @pytest.fixture(autouse=True) - def read_config(self, fake_keyconfig, keyparser): - keyparser.read_config('test') + def read_config(self, keyinput_bindings, keyparser): + keyparser._read_config('prompt') def test_valid_special_key(self, fake_keyevent_factory, keyparser): if sys.platform == 'darwin': @@ -225,7 +218,7 @@ class TestKeyChain: keyparser.handle(fake_keyevent_factory(Qt.Key_A, modifier)) keyparser.handle(fake_keyevent_factory(Qt.Key_X, modifier)) keyparser.execute.assert_called_once_with( - 'ctrla', keyparser.Type.special, None) + 'message-info ctrla', keyparser.Type.special, None) assert keyparser._keystring == '' def test_invalid_special_key(self, fake_keyevent_factory, keyparser): @@ -240,18 +233,18 @@ class TestKeyChain: # Then start the real chain (Qt.Key_B, 'b'), (Qt.Key_A, 'a')) keyparser.execute.assert_called_once_with( - 'ba', keyparser.Type.chain, None) + 'message-info ba', keyparser.Type.chain, None) assert keyparser._keystring == '' def test_0_press(self, handle_text, keyparser): handle_text((Qt.Key_0, '0')) keyparser.execute.assert_called_once_with( - '0', keyparser.Type.chain, None) + 'message-info 0', keyparser.Type.chain, None) assert keyparser._keystring == '' def test_ambiguous_keychain(self, qapp, handle_text, config_stub, keyparser): - config_stub.data = CONFIG + config_stub.val.input.ambiguous_timeout = 100 timer = keyparser._ambiguous_timer assert not timer.isActive() # We start with 'a' where the keychain gives us an ambiguous result. @@ -265,13 +258,13 @@ class TestKeyChain: # stopped. handle_text((Qt.Key_X, 'x')) keyparser.execute.assert_called_once_with( - 'ax', keyparser.Type.chain, None) + 'message-info ax', keyparser.Type.chain, None) assert not timer.isActive() assert keyparser._keystring == '' def test_ambiguous_keychain_no_timeout(self, handle_text, config_stub, keyparser): - config_stub.data = {'input': {'timeout': 0}} + config_stub.val.input.ambiguous_timeout = 0 handle_text((Qt.Key_A, 'a')) assert keyparser.execute.called assert not keyparser._ambiguous_timer.isActive() @@ -283,7 +276,7 @@ class TestKeyChain: def test_ambiguous_delayed_exec(self, handle_text, config_stub, qtbot, keyparser): - config_stub.data = CONFIG + config_stub.val.input.ambiguous_timeout = 100 # 'a' is an ambiguous result. handle_text((Qt.Key_A, 'a')) @@ -300,20 +293,20 @@ class TestCount: """Test execute() with counts.""" @pytest.fixture(autouse=True) - def read_keyparser_config(self, fake_keyconfig, keyparser): - keyparser.read_config('test') + def read_keyparser_config(self, keyinput_bindings, keyparser): + keyparser._read_config('prompt') def test_no_count(self, handle_text, keyparser): """Test with no count added.""" handle_text((Qt.Key_B, 'b'), (Qt.Key_A, 'a')) keyparser.execute.assert_called_once_with( - 'ba', keyparser.Type.chain, None) + 'message-info ba', keyparser.Type.chain, None) assert keyparser._keystring == '' def test_count_0(self, handle_text, keyparser): handle_text((Qt.Key_0, '0'), (Qt.Key_B, 'b'), (Qt.Key_A, 'a')) - calls = [mock.call('0', keyparser.Type.chain, None), - mock.call('ba', keyparser.Type.chain, None)] + calls = [mock.call('message-info 0', keyparser.Type.chain, None), + mock.call('message-info ba', keyparser.Type.chain, None)] keyparser.execute.assert_has_calls(calls) assert keyparser._keystring == '' @@ -321,7 +314,7 @@ class TestCount: handle_text((Qt.Key_4, '4'), (Qt.Key_2, '2'), (Qt.Key_B, 'b'), (Qt.Key_A, 'a')) keyparser.execute.assert_called_once_with( - 'ba', keyparser.Type.chain, 42) + 'message-info ba', keyparser.Type.chain, 42) assert keyparser._keystring == '' def test_count_42_invalid(self, handle_text, keyparser): @@ -334,7 +327,7 @@ class TestCount: handle_text((Qt.Key_6, '2'), (Qt.Key_2, '3'), (Qt.Key_C, 'c'), (Qt.Key_C, 'c'), (Qt.Key_C, 'c')) keyparser.execute.assert_called_once_with( - 'ccc', keyparser.Type.chain, 23) + 'message-info ccc', keyparser.Type.chain, 23) assert keyparser._keystring == ''