diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py index 2800236f4..a2a2697b1 100644 --- a/tests/unit/config/test_config.py +++ b/tests/unit/config/test_config.py @@ -39,6 +39,11 @@ def configdata_init(): configdata.init() +# Alias because we need this a lot in here. +def keyseq(s): + return keyutils.KeySequence.parse(s) + + class TestChangeFilter: @pytest.fixture(autouse=True) @@ -101,9 +106,8 @@ class TestKeyConfig: def test_prepare_invalid_mode(self, key_config_stub): """Make sure prepare checks the mode.""" - seq = keyutils.KeySequence('x') with pytest.raises(configexc.KeybindingError): - assert key_config_stub._prepare(seq, 'abnormal') + assert key_config_stub._prepare(keyseq('x'), 'abnormal') def test_prepare_invalid_type(self, key_config_stub): """Make sure prepare checks the type.""" @@ -112,32 +116,50 @@ class TestKeyConfig: @pytest.mark.parametrize('commands, expected', [ # Unbinding default key - ({'a': None}, {'b': 'message-info bar'}), + ({'a': None}, {keyseq('b'): 'message-info bar'}), # Additional binding ({'c': 'message-info baz'}, - {'a': 'message-info foo', 'b': 'message-info bar', - 'c': 'message-info baz'}), + {keyseq('a'): 'message-info foo', + keyseq('b'): 'message-info bar', + keyseq('c'): 'message-info baz'}), # Unbinding unknown key - ({'x': None}, {'a': 'message-info foo', 'b': 'message-info bar'}), + ({'x': None}, {keyseq('a'): 'message-info foo', + keyseq('b'): 'message-info bar'}), ]) def test_get_bindings_for_and_get_command(self, key_config_stub, config_stub, commands, expected): - orig_default_bindings = {'normal': {'a': 'message-info foo', - 'b': 'message-info bar'}, - 'insert': {}, - 'hint': {}, - 'passthrough': {}, - 'command': {}, - 'prompt': {}, - 'caret': {}, - 'register': {}} - config_stub.val.bindings.default = copy.deepcopy(orig_default_bindings) + orig_default_bindings = { + 'normal': {'a': 'message-info foo', + 'b': 'message-info bar'}, + 'insert': {}, + 'hint': {}, + 'passthrough': {}, + 'command': {}, + 'prompt': {}, + 'caret': {}, + 'register': {}, + 'yesno': {} + } + expected_default_bindings = { + 'normal': {keyseq('a'): 'message-info foo', + keyseq('b'): 'message-info bar'}, + 'insert': {}, + 'hint': {}, + 'passthrough': {}, + 'command': {}, + 'prompt': {}, + 'caret': {}, + 'register': {}, + 'yesno': {} + } + + config_stub.val.bindings.default = orig_default_bindings config_stub.val.bindings.commands = {'normal': commands} bindings = key_config_stub.get_bindings_for('normal') # Make sure the code creates a copy and doesn't modify the setting - assert config_stub.val.bindings.default == orig_default_bindings + assert config_stub.val.bindings.default == expected_default_bindings assert bindings == expected for key, command in expected.items(): assert key_config_stub.get_command(key, 'normal') == command @@ -146,15 +168,18 @@ class TestKeyConfig: no_bindings): config_stub.val.bindings.default = no_bindings config_stub.val.bindings.commands = no_bindings - assert key_config_stub.get_command('foobar', 'normal') is None + command = key_config_stub.get_command(keyseq('foobar'), + 'normal') + assert command is None def test_get_command_default(self, key_config_stub, config_stub): config_stub.val.bindings.default = { 'normal': {'x': 'message-info default'}} config_stub.val.bindings.commands = { 'normal': {'x': 'message-info custom'}} - cmd = 'message-info default' - assert key_config_stub.get_command('x', 'normal', default=True) == cmd + command = key_config_stub.get_command(keyseq('x'), 'normal', + default=True) + assert command == 'message-info default' @pytest.mark.parametrize('bindings, expected', [ # Simple @@ -163,9 +188,9 @@ class TestKeyConfig: # Multiple bindings ({'a': 'message-info foo', 'b': 'message-info foo'}, {'message-info foo': ['b', 'a']}), - # With special keys (should be listed last and normalized) - ({'a': 'message-info foo', '': 'message-info foo'}, - {'message-info foo': ['a', '']}), + # With modifier keys (should be listed last and normalized) + ({'a': 'message-info foo', '': 'message-info foo'}, + {'message-info foo': ['a', '']}), # Chained command ({'a': 'message-info foo ;; message-info bar'}, {'message-info foo': ['a'], 'message-info bar': ['a']}), @@ -178,11 +203,14 @@ class TestKeyConfig: @pytest.mark.parametrize('key', ['a', '', 'b']) def test_bind_duplicate(self, key_config_stub, config_stub, key): + seq = keyseq(key) config_stub.val.bindings.default = {'normal': {'a': 'nop', '': 'nop'}} config_stub.val.bindings.commands = {'normal': {'b': 'nop'}} - key_config_stub.bind(key, 'message-info foo', mode='normal') - assert key_config_stub.get_command(key, 'normal') == 'message-info foo' + key_config_stub.bind(seq, 'message-info foo', mode='normal') + + command = key_config_stub.get_command(seq, 'normal') + assert command == 'message-info foo' @pytest.mark.parametrize('mode', ['normal', 'caret']) @pytest.mark.parametrize('command', [ @@ -193,13 +221,14 @@ class TestKeyConfig: mode, command): config_stub.val.bindings.default = no_bindings config_stub.val.bindings.commands = no_bindings + seq = keyseq('a') with qtbot.wait_signal(config_stub.changed): - key_config_stub.bind('a', command, mode=mode) + key_config_stub.bind(seq, command, mode=mode) - assert config_stub.val.bindings.commands[mode]['a'] == command - assert key_config_stub.get_bindings_for(mode)['a'] == command - assert key_config_stub.get_command('a', mode) == command + assert config_stub.val.bindings.commands[mode][seq] == command + assert key_config_stub.get_bindings_for(mode)[seq] == command + assert key_config_stub.get_command(seq, mode) == command def test_bind_mode_changing(self, key_config_stub, config_stub, no_bindings): @@ -209,7 +238,8 @@ class TestKeyConfig: """ config_stub.val.bindings.default = no_bindings config_stub.val.bindings.commands = no_bindings - key_config_stub.bind('a', 'set-cmd-text :nop ;; rl-beginning-of-line', + key_config_stub.bind(keyseq('a'), + 'set-cmd-text :nop ;; rl-beginning-of-line', mode='normal') def test_bind_default(self, key_config_stub, config_stub): @@ -218,11 +248,15 @@ class TestKeyConfig: bound_cmd = 'message-info bound' config_stub.val.bindings.default = {'normal': {'a': default_cmd}} config_stub.val.bindings.commands = {'normal': {'a': bound_cmd}} - assert key_config_stub.get_command('a', mode='normal') == bound_cmd + seq = keyseq('a') - key_config_stub.bind_default('a', mode='normal') + command = key_config_stub.get_command(seq, mode='normal') + assert command == bound_cmd - assert key_config_stub.get_command('a', mode='normal') == default_cmd + key_config_stub.bind_default(seq, mode='normal') + + command = key_config_stub.get_command(keyseq('a'), mode='normal') + assert command == default_cmd def test_bind_default_unbound(self, key_config_stub, config_stub, no_bindings): @@ -231,42 +265,51 @@ class TestKeyConfig: config_stub.val.bindings.commands = no_bindings with pytest.raises(configexc.KeybindingError, match="Can't find binding 'foobar' in normal mode"): - key_config_stub.bind_default('foobar', mode='normal') + key_config_stub.bind_default(keyseq('foobar'), mode='normal') - @pytest.mark.parametrize('key, normalized', [ - ('a', 'a'), # default bindings - ('b', 'b'), # custom bindings - ('', '') + @pytest.mark.parametrize('key', [ + 'a', # default bindings + 'b', # custom bindings + '', ]) @pytest.mark.parametrize('mode', ['normal', 'caret', 'prompt']) def test_unbind(self, key_config_stub, config_stub, qtbot, - key, normalized, mode): + key, mode): default_bindings = { 'normal': {'a': 'nop', '': 'nop'}, 'caret': {'a': 'nop', '': 'nop'}, # prompt: a mode which isn't in bindings.commands yet 'prompt': {'a': 'nop', 'b': 'nop', '': 'nop'}, } - old_default_bindings = copy.deepcopy(default_bindings) + expected_default_bindings = { + 'normal': {keyseq('a'): 'nop', keyseq(''): 'nop'}, + 'caret': {keyseq('a'): 'nop', keyseq(''): 'nop'}, + # prompt: a mode which isn't in bindings.commands yet + 'prompt': {keyseq('a'): 'nop', + keyseq('b'): 'nop', + keyseq(''): 'nop'}, + } + config_stub.val.bindings.default = default_bindings config_stub.val.bindings.commands = { 'normal': {'b': 'nop'}, 'caret': {'b': 'nop'}, } + seq = keyseq(key) with qtbot.wait_signal(config_stub.changed): - key_config_stub.unbind(key, mode=mode) + key_config_stub.unbind(seq, mode=mode) - assert key_config_stub.get_command(key, mode) is None + assert key_config_stub.get_command(seq, mode) is None mode_bindings = config_stub.val.bindings.commands[mode] if key == 'b' and mode != 'prompt': # Custom binding - assert normalized not in mode_bindings + assert seq not in mode_bindings else: default_bindings = config_stub.val.bindings.default - assert default_bindings[mode] == old_default_bindings[mode] - assert mode_bindings[normalized] is None + assert default_bindings[mode] == expected_default_bindings[mode] + assert mode_bindings[seq] is None def test_unbind_unbound(self, key_config_stub, config_stub, no_bindings): """Try unbinding a key which is not bound.""" @@ -274,7 +317,7 @@ class TestKeyConfig: config_stub.val.bindings.commands = no_bindings with pytest.raises(configexc.KeybindingError, match="Can't find binding 'foobar' in normal mode"): - key_config_stub.unbind('foobar', mode='normal') + key_config_stub.unbind(keyseq('foobar'), mode='normal') def test_unbound_twice(self, key_config_stub, config_stub, no_bindings): """Try unbinding an already-unbound default key. @@ -286,17 +329,18 @@ class TestKeyConfig: """ config_stub.val.bindings.default = {'normal': {'a': 'nop'}} config_stub.val.bindings.commands = no_bindings + seq = keyseq('a') - key_config_stub.unbind('a') - assert key_config_stub.get_command('a', mode='normal') is None - key_config_stub.unbind('a') - assert key_config_stub.get_command('a', mode='normal') is None + key_config_stub.unbind(seq) + assert key_config_stub.get_command(seq, mode='normal') is None + key_config_stub.unbind(seq) + assert key_config_stub.get_command(seq, mode='normal') is None def test_empty_command(self, key_config_stub): """Try binding a key to an empty command.""" message = "Can't add binding 'x' with empty command in normal mode" with pytest.raises(configexc.KeybindingError, match=message): - key_config_stub.bind('x', ' ', mode='normal') + key_config_stub.bind(keyseq('x'), ' ', mode='normal') class TestConfig: