-
-
Save sahutd/289d2297eb83a020a6dd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 601a08fcb507 Lib/idlelib/idle_test/test_keybinding.py | |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 | |
+++ b/Lib/idlelib/idle_test/test_keybinding.py Sun Jun 15 19:47:51 2014 +0530 | |
@@ -0,0 +1,141 @@ | |
+"""Unittest for idlelib.keybindingDialog.py""" | |
+import unittest | |
+import string | |
+import re | |
+ | |
+modifierKeys = ['Control', 'Alt', 'Shift', 'Meta'] | |
+typeKeys = ['Key'] | |
+functionKeys=('F1','F2','F3','F4','F5','F6','F7','F8','F9', | |
+ 'F10','F11','F12') | |
+alphanumKeys=tuple(string.ascii_lowercase+string.digits) | |
+whitespaceKeys=('Tab','space','Return') | |
+editKeys=('BackSpace','Delete','Insert') | |
+moveKeys=('Home','End','Prior','Next','Left', | |
+ 'Right','Up','Down') | |
+otherKeys = ('Escape', 'bracketright', 'bracketleft', 'KP_Enter') | |
+detailKeys = alphanumKeys + functionKeys + editKeys + moveKeys + \ | |
+ whitespaceKeys + otherKeys | |
+ | |
+modifier_regex = '(' + ')|('.join(modifierKeys) + ')' | |
+type_regex = '(' + ')|('.join(typeKeys) + ')' | |
+detail_regex = '(' + ')|('.join(detailKeys) + ')' | |
+ | |
+def key_ok(keyseq): | |
+ """Utility function to validate a keyseq""" | |
+ | |
+ if not keyseq.startswith('<'): | |
+ raise ValueError("Invalid startkey '{}'. Key sequence should start with" | |
+ "'<' key.".format(keyseq[0])) | |
+ | |
+ if not keyseq.endswith('>'): | |
+ raise ValueError("Invalid endkey '{}'. Key sequence should end with" | |
+ "'>' key.".format(keyseq[-1])) | |
+ | |
+ def validate_modifiers(modifiers): | |
+ modifiers =[m for m in modifiers.split('-') if m] | |
+ if len(set(modifiers)) != len(modifiers): | |
+ raise ValueError('{} has repeated modifier keys.'.format(keyseq)) | |
+ return True | |
+ | |
+ def validate_type(_type): | |
+ typekeys = [t for t in _type.split('-') if t] | |
+ if len(set(typekeys)) != len(typekeys): | |
+ raise ValueError('{} has repeated type keys.'.format(keyseq)) | |
+ return True | |
+ | |
+ def validate_detail(detail): | |
+ if detail in detailKeys: | |
+ return True | |
+ else: | |
+ raise ValueError('{} in {} is an invalid key for detailkey'.format(detail, keyseq)) | |
+ | |
+ | |
+ pat = '^<(?P<modifiers>(({modifier})-){{1,3}})(?P<type>(({type})-)?)(?P<detail>({detail}))>$'.format(modifier=modifier_regex,type=type_regex, detail=detail_regex) | |
+ p = re.search(pat, keyseq) | |
+ | |
+ if not p: | |
+ """ | |
+ Try to ascertain which part is invalid. | |
+ """ | |
+ | |
+ pat = '^<(?P<modifiers>(({modifiers})-){{1,3}})'.format(modifiers=modifier_regex) | |
+ p = re.search(pat, keyseq) | |
+ if p: | |
+ validate_modifiers(p.group('modifiers')) | |
+ else: | |
+ raise ValueError('{} has an invalid modifier.'.format(keyseq)) | |
+ | |
+ pat = '(?P<type>({type}-)+)'.format(type=type_regex) | |
+ p = re.search(pat, keyseq) | |
+ if p: | |
+ validate_type(p.group('type')) | |
+ else: | |
+ raise ValueError('{} has an invalid typekey.'.format(keyseq)) | |
+ | |
+ pat = '-(?P<detail>{detail})>$'.format(detail=detail_regex) | |
+ p = re.search(pat, keyseq) | |
+ if p: | |
+ validate_type(p.group('detail')) | |
+ else: | |
+ raise ValueError('{} has an invalid detail'.format(keyseq)) | |
+ | |
+ # if we come this far, we cant ascertain the reason. | |
+ # just that it is invalid | |
+ raise ValueError('{} is an invalid keysequence'.format(keyseq)) | |
+ | |
+ modifiers_valid = _type_valid = detail_valid = False | |
+ | |
+ modifiers_valid = validate_modifiers(p.group('modifiers')) | |
+ _type_valid = validate_type(p.group('type')) | |
+ detail_valid = validate_detail(p.group('detail')) | |
+ | |
+ return modifiers_valid and _type_valid and detail_valid | |
+ | |
+ | |
+class TestIsValidKeyseq(unittest.TestCase): | |
+ | |
+ def test_key_ok(self): | |
+ ok = key_ok | |
+ | |
+ with self.assertRaises(ValueError) as ve: | |
+ ok('Alt-X>') | |
+ self.assertIn('startkey', str(ve.exception)) | |
+ | |
+ with self.assertRaises(ValueError) as ve: | |
+ ok('<Alt-X') | |
+ self.assertIn('endkey', str(ve.exception)) | |
+ | |
+ # invalid modifer key | |
+ with self.assertRaises(ValueError) as ve: | |
+ ok('<Contro-Alt-Key-x>') | |
+ self.assertIn('invalid', str(ve.exception)) | |
+ self.assertIn('modifier', str(ve.exception)) | |
+ | |
+ self.assertTrue(ok('<Control-Alt-Key-x>')) | |
+ # repeated modifier key | |
+ with self.assertRaises(ValueError) as ve: | |
+ ok('<Control-Alt-Control-Key-x>') | |
+ self.assertIn('repeated', str(ve.exception)) | |
+ self.assertIn('modifier', str(ve.exception)) | |
+ | |
+ self.assertTrue(ok('<Control-Key-x>')) | |
+ self.assertTrue(ok('<Control-x>')) | |
+ # invalid type key | |
+ with self.assertRaises(ValueError) as ve: | |
+ ok('<Control-key-x>') | |
+ self.assertIn('invalid', str(ve.exception)) | |
+ self.assertIn('typekey', str(ve.exception)) | |
+ # repeated type key | |
+ with self.assertRaises(ValueError) as ve: | |
+ ok('<Control-Key-Key-x>') | |
+ self.assertIn('repeated', str(ve.exception)) | |
+ # invalid detail key | |
+ with self.assertRaises(ValueError) as ve: | |
+ ok('<Control-Alt-Key-xa>') | |
+ self.assertIn('invalid', str(ve.exception)) | |
+ self.assertIn('detail', str(ve.exception)) | |
+ | |
+ | |
+ | |
+if __name__ == '__main__': | |
+ unittest.main(verbosity=2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment