aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_pyrepl/test_keymap.py
diff options
context:
space:
mode:
authorEugene Triguba <eugenetriguba@gmail.com>2024-05-21 22:36:01 -0400
committerGitHub <noreply@github.com>2024-05-22 04:36:01 +0200
commit73ab83b27f105a4509046ce26e35f20d66625195 (patch)
treebcb20b17d09ee4cb329abdebf70d632682e51b9f /Lib/test/test_pyrepl/test_keymap.py
parentc886bece3b3a49f8a0f188aecfc1d6ff89d281e6 (diff)
downloadcpython-73ab83b27f105a4509046ce26e35f20d66625195.tar.gz
cpython-73ab83b27f105a4509046ce26e35f20d66625195.zip
gh-119357: Increase test coverage for keymap in _pyrepl (#119358)
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Lib/test/test_pyrepl/test_keymap.py')
-rw-r--r--Lib/test/test_pyrepl/test_keymap.py82
1 files changed, 64 insertions, 18 deletions
diff --git a/Lib/test/test_pyrepl/test_keymap.py b/Lib/test/test_pyrepl/test_keymap.py
index 419f1643030..2c97066b2c7 100644
--- a/Lib/test/test_pyrepl/test_keymap.py
+++ b/Lib/test/test_pyrepl/test_keymap.py
@@ -1,41 +1,78 @@
+import string
import unittest
-from _pyrepl.keymap import parse_keys, compile_keymap
+from _pyrepl.keymap import _keynames, _escapes, parse_keys, compile_keymap, KeySpecError
class TestParseKeys(unittest.TestCase):
def test_single_character(self):
- self.assertEqual(parse_keys("a"), ["a"])
- self.assertEqual(parse_keys("b"), ["b"])
- self.assertEqual(parse_keys("1"), ["1"])
+ """Ensure that single ascii characters or single digits are parsed as single characters."""
+ test_cases = [(key, [key]) for key in string.ascii_letters + string.digits]
+ for test_key, expected_keys in test_cases:
+ with self.subTest(f"{test_key} should be parsed as {expected_keys}"):
+ self.assertEqual(parse_keys(test_key), expected_keys)
+
+ def test_keynames(self):
+ """Ensure that keynames are parsed to their corresponding mapping.
+
+ A keyname is expected to be of the following form: \\<keyname> such as \\<left>
+ which would get parsed as "left".
+ """
+ test_cases = [(f"\\<{keyname}>", [parsed_keyname]) for keyname, parsed_keyname in _keynames.items()]
+ for test_key, expected_keys in test_cases:
+ with self.subTest(f"{test_key} should be parsed as {expected_keys}"):
+ self.assertEqual(parse_keys(test_key), expected_keys)
def test_escape_sequences(self):
- self.assertEqual(parse_keys("\\n"), ["\n"])
- self.assertEqual(parse_keys("\\t"), ["\t"])
- self.assertEqual(parse_keys("\\\\"), ["\\"])
- self.assertEqual(parse_keys("\\'"), ["'"])
- self.assertEqual(parse_keys('\\"'), ['"'])
+ """Ensure that escaping sequences are parsed to their corresponding mapping."""
+ test_cases = [(f"\\{escape}", [parsed_escape]) for escape, parsed_escape in _escapes.items()]
+ for test_key, expected_keys in test_cases:
+ with self.subTest(f"{test_key} should be parsed as {expected_keys}"):
+ self.assertEqual(parse_keys(test_key), expected_keys)
def test_control_sequences(self):
- self.assertEqual(parse_keys("\\C-a"), ["\x01"])
- self.assertEqual(parse_keys("\\C-b"), ["\x02"])
- self.assertEqual(parse_keys("\\C-c"), ["\x03"])
+ """Ensure that supported control sequences are parsed successfully."""
+ keys = ["@", "[", "]", "\\", "^", "_", "\\<space>", "\\<delete>"]
+ keys.extend(string.ascii_letters)
+ test_cases = [(f"\\C-{key}", chr(ord(key) & 0x1F)) for key in []]
+ for test_key, expected_keys in test_cases:
+ with self.subTest(f"{test_key} should be parsed as {expected_keys}"):
+ self.assertEqual(parse_keys(test_key), expected_keys)
def test_meta_sequences(self):
self.assertEqual(parse_keys("\\M-a"), ["\033", "a"])
self.assertEqual(parse_keys("\\M-b"), ["\033", "b"])
self.assertEqual(parse_keys("\\M-c"), ["\033", "c"])
- def test_keynames(self):
- self.assertEqual(parse_keys("\\<up>"), ["up"])
- self.assertEqual(parse_keys("\\<down>"), ["down"])
- self.assertEqual(parse_keys("\\<left>"), ["left"])
- self.assertEqual(parse_keys("\\<right>"), ["right"])
-
def test_combinations(self):
self.assertEqual(parse_keys("\\C-a\\n\\<up>"), ["\x01", "\n", "up"])
self.assertEqual(parse_keys("\\M-a\\t\\<down>"), ["\033", "a", "\t", "down"])
+ def test_keyspec_errors(self):
+ cases = [
+ ("\\Ca", "\\C must be followed by `-'"),
+ ("\\ca", "\\C must be followed by `-'"),
+ ("\\C-\\C-", "doubled \\C-"),
+ ("\\Ma", "\\M must be followed by `-'"),
+ ("\\ma", "\\M must be followed by `-'"),
+ ("\\M-\\M-", "doubled \\M-"),
+ ("\\<left", "unterminated \\<"),
+ ("\\<unsupported>", "unrecognised keyname"),
+ ("\\大", "unknown backslash escape"),
+ ("\\C-\\<backspace>", "\\C- followed by invalid key")
+ ]
+ for test_keys, expected_err in cases:
+ with self.subTest(f"{test_keys} should give error {expected_err}"):
+ with self.assertRaises(KeySpecError) as e:
+ parse_keys(test_keys)
+ self.assertIn(expected_err, str(e.exception))
+
+ def test_index_errors(self):
+ test_cases = ["\\", "\\C", "\\C-\\C"]
+ for test_keys in test_cases:
+ with self.assertRaises(IndexError):
+ parse_keys(test_keys)
+
class TestCompileKeymap(unittest.TestCase):
def test_empty_keymap(self):
@@ -72,3 +109,12 @@ class TestCompileKeymap(unittest.TestCase):
keymap = {b"a": {b"b": {b"c": "action"}}}
result = compile_keymap(keymap)
self.assertEqual(result, {b"a": {b"b": {b"c": "action"}}})
+
+ def test_clashing_definitions(self):
+ km = {b'a': 'c', b'a' + b'b': 'd'}
+ with self.assertRaises(KeySpecError):
+ compile_keymap(km)
+
+ def test_non_bytes_key(self):
+ with self.assertRaises(TypeError):
+ compile_keymap({123: 'a'})