diff options
author | Cheryl Sabella <cheryl.sabella@gmail.com> | 2018-12-30 04:25:09 (GMT) |
---|---|---|
committer | Terry Jan Reedy <tjreedy@udel.edu> | 2018-12-30 04:25:09 (GMT) |
commit | b0a6196ffd58ff91462191f426706897dc920eee (patch) | |
tree | d3675190937f2dc90f74d62c6c5f8d396546ddb3 | |
parent | 0e5f771f38138714415f665651de7e674fcebc38 (diff) | |
download | cpython-b0a6196ffd58ff91462191f426706897dc920eee.zip cpython-b0a6196ffd58ff91462191f426706897dc920eee.tar.gz cpython-b0a6196ffd58ff91462191f426706897dc920eee.tar.bz2 |
bpo-35598: IDLE: Increase test coverage for config_key.py (#11360)
-rw-r--r-- | Lib/idlelib/config_key.py | 8 | ||||
-rw-r--r-- | Lib/idlelib/idle_test/test_config_key.py | 195 | ||||
-rw-r--r-- | Misc/NEWS.d/next/IDLE/2018-12-27-15-29-11.bpo-35598.FWOOm8.rst | 2 |
3 files changed, 197 insertions, 8 deletions
diff --git a/Lib/idlelib/config_key.py b/Lib/idlelib/config_key.py index 4b02323..4e7b38b 100644 --- a/Lib/idlelib/config_key.py +++ b/Lib/idlelib/config_key.py @@ -67,7 +67,7 @@ class GetKeysDialog(Toplevel): messagebox.showerror(*args, **kwargs) def create_widgets(self): - frame = Frame(self, borderwidth=2, relief=SUNKEN) + self.frame = frame = Frame(self, borderwidth=2, relief=SUNKEN) frame.pack(side=TOP, expand=True, fill=BOTH) frame_buttons = Frame(self) @@ -81,7 +81,7 @@ class GetKeysDialog(Toplevel): self.button_cancel.grid(row=0, column=1, padx=5, pady=5) # Basic entry key sequence. - self.frame_keyseq_basic = Frame(frame) + self.frame_keyseq_basic = Frame(frame, name='keyseq_basic') self.frame_keyseq_basic.grid(row=0, column=0, sticky=NSEW, padx=5, pady=5) basic_title = Label(self.frame_keyseq_basic, @@ -135,7 +135,7 @@ class GetKeysDialog(Toplevel): self.button_clear.grid(row=2, column=0, columnspan=4) # Advanced entry key sequence. - self.frame_keyseq_advanced = Frame(frame) + self.frame_keyseq_advanced = Frame(frame, name='keyseq_advanced') self.frame_keyseq_advanced.grid(row=0, column=0, sticky=NSEW, padx=5, pady=5) advanced_title = Label(self.frame_keyseq_advanced, justify=LEFT, @@ -197,7 +197,7 @@ class GetKeysDialog(Toplevel): self.frame_controls_basic.lift() self.advanced = False - def final_key_selected(self, event): + def final_key_selected(self, event=None): "Handler for clicking on key in basic settings list." self.build_key_string() diff --git a/Lib/idlelib/idle_test/test_config_key.py b/Lib/idlelib/idle_test/test_config_key.py index adf02c9..9412b22 100644 --- a/Lib/idlelib/idle_test/test_config_key.py +++ b/Lib/idlelib/idle_test/test_config_key.py @@ -1,17 +1,25 @@ -"Test config_key, coverage 82%" +"""Test config_key, coverage 98%. + +Coverage is effectively 100%. Tkinter dialog is mocked, Mac-only line +may be skipped, and dummy function in bind test should not be called. +Not tested: exit with 'self.advanced or self.keys_ok(keys)) ...' False. +""" from idlelib import config_key from test.support import requires import unittest -from tkinter import Tk +from unittest import mock +from tkinter import Tk, TclError from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_tk import Mbox_func +gkd = config_key.GetKeysDialog + class ValidationTest(unittest.TestCase): "Test validation methods: ok, keys_ok, bind_ok." - class Validator(config_key.GetKeysDialog): + class Validator(gkd): def __init__(self, *args, **kwargs): config_key.GetKeysDialog.__init__(self, *args, **kwargs) class list_keys_final: @@ -95,5 +103,186 @@ class ValidationTest(unittest.TestCase): self.assertIn('not accepted', self.dialog.showerror.message) +class ToggleLevelTest(unittest.TestCase): + "Test toggle between Basic and Advanced frames." + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.dialog = gkd(cls.root, 'Title', '<<Test>>', [], _utest=True) + + @classmethod + def tearDownClass(cls): + cls.dialog.cancel() + cls.root.update_idletasks() + cls.root.destroy() + del cls.dialog, cls.root + + def test_toggle_level(self): + dialog = self.dialog + + def stackorder(): + """Get the stack order of the children of the frame. + + winfo_children() stores the children in stack order, so + this can be used to check whether a frame is above or + below another one. + """ + for index, child in enumerate(dialog.frame.winfo_children()): + if child._name == 'keyseq_basic': + basic = index + if child._name == 'keyseq_advanced': + advanced = index + return basic, advanced + + # New window starts at basic level. + self.assertFalse(dialog.advanced) + self.assertIn('Advanced', dialog.button_level['text']) + basic, advanced = stackorder() + self.assertGreater(basic, advanced) + + # Toggle to advanced. + dialog.toggle_level() + self.assertTrue(dialog.advanced) + self.assertIn('Basic', dialog.button_level['text']) + basic, advanced = stackorder() + self.assertGreater(advanced, basic) + + # Toggle to basic. + dialog.button_level.invoke() + self.assertFalse(dialog.advanced) + self.assertIn('Advanced', dialog.button_level['text']) + basic, advanced = stackorder() + self.assertGreater(basic, advanced) + + +class KeySelectionTest(unittest.TestCase): + "Test selecting key on Basic frames." + + class Basic(gkd): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + class list_keys_final: + get = Func() + select_clear = Func() + yview = Func() + self.list_keys_final = list_keys_final + def set_modifiers_for_platform(self): + self.modifiers = ['foo', 'bar', 'BAZ'] + self.modifier_label = {'BAZ': 'ZZZ'} + showerror = Mbox_func() + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.dialog = cls.Basic(cls.root, 'Title', '<<Test>>', [], _utest=True) + + @classmethod + def tearDownClass(cls): + cls.dialog.cancel() + cls.root.update_idletasks() + cls.root.destroy() + del cls.dialog, cls.root + + def setUp(self): + self.dialog.clear_key_seq() + + def test_get_modifiers(self): + dialog = self.dialog + gm = dialog.get_modifiers + eq = self.assertEqual + + # Modifiers are set by selecting/deselecting the checkbutton. + dialog.modifier_checkbuttons['foo'].select() + eq(gm(), ['foo']) + + dialog.modifier_checkbuttons['BAZ'].select() + eq(gm(), ['foo', 'BAZ']) + + dialog.modifier_checkbuttons['foo'].deselect() + eq(gm(), ['BAZ']) + + def test_translate_key(self): + dialog = self.dialog + tr = dialog.translate_key + eq = self.assertEqual + + # Letters return unchanged with no 'Shift'. + eq(tr('q', []), 'Key-q') + eq(tr('q', ['Control', 'Alt']), 'Key-q') + + # 'Shift' uppercases single lowercase letters. + eq(tr('q', ['Shift']), 'Key-Q') + eq(tr('q', ['Control', 'Shift']), 'Key-Q') + eq(tr('q', ['Control', 'Alt', 'Shift']), 'Key-Q') + + # Convert key name to keysym. + eq(tr('Page Up', []), 'Key-Prior') + # 'Shift' doesn't change case. + eq(tr('Page Down', ['Shift']), 'Key-Next') + + @mock.patch.object(gkd, 'get_modifiers') + def test_build_key_string(self, mock_modifiers): + dialog = self.dialog + key = dialog.list_keys_final + string = dialog.key_string.get + eq = self.assertEqual + + key.get.result = 'a' + mock_modifiers.return_value = [] + dialog.build_key_string() + eq(string(), '<Key-a>') + + mock_modifiers.return_value = ['mymod'] + dialog.build_key_string() + eq(string(), '<mymod-Key-a>') + + key.get.result = '' + mock_modifiers.return_value = ['mymod', 'test'] + dialog.build_key_string() + eq(string(), '<mymod-test>') + + @mock.patch.object(gkd, 'get_modifiers') + def test_final_key_selected(self, mock_modifiers): + dialog = self.dialog + key = dialog.list_keys_final + string = dialog.key_string.get + eq = self.assertEqual + + mock_modifiers.return_value = ['Shift'] + key.get.result = '{' + dialog.final_key_selected() + eq(string(), '<Shift-Key-braceleft>') + + +class CancelTest(unittest.TestCase): + "Simulate user clicking [Cancel] button." + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.dialog = gkd(cls.root, 'Title', '<<Test>>', [], _utest=True) + + @classmethod + def tearDownClass(cls): + cls.dialog.cancel() + cls.root.update_idletasks() + cls.root.destroy() + del cls.dialog, cls.root + + def test_cancel(self): + self.assertEqual(self.dialog.winfo_class(), 'Toplevel') + self.dialog.button_cancel.invoke() + with self.assertRaises(TclError): + self.dialog.winfo_class() + self.assertEqual(self.dialog.result, '') + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Misc/NEWS.d/next/IDLE/2018-12-27-15-29-11.bpo-35598.FWOOm8.rst b/Misc/NEWS.d/next/IDLE/2018-12-27-15-29-11.bpo-35598.FWOOm8.rst index 54347c5..6cc3557 100644 --- a/Misc/NEWS.d/next/IDLE/2018-12-27-15-29-11.bpo-35598.FWOOm8.rst +++ b/Misc/NEWS.d/next/IDLE/2018-12-27-15-29-11.bpo-35598.FWOOm8.rst @@ -1 +1 @@ -Apply PEP8 naming convention to config_key.py. +Update config_key: use PEP 8 names and add tests. |