From ef4584ceb6c7e0f1751acb81622394cab6d1167b Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Thu, 14 Sep 2017 19:28:42 -0400 Subject: [PATCH 01/10] bpo-30780: IDLE: Complete keys and highlight coverage for configdialog and add tests for buttons. --- Lib/idlelib/configdialog.py | 17 +- Lib/idlelib/idle_test/test_configdialog.py | 227 ++++++++++++++++++++- 2 files changed, 227 insertions(+), 17 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index aaf319bbe1befd..59d414ca9aa5d3 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -149,17 +149,19 @@ def create_action_buttons(self): else: padding_args = {'padding': (6, 3)} outer = Frame(self, padding=2) - buttons = Frame(outer, padding=2) + buttons_frame = Frame(outer, padding=2) + self.buttons = {} for txt, cmd in ( ('Ok', self.ok), ('Apply', self.apply), ('Cancel', self.cancel), ('Help', self.help)): - Button(buttons, text=txt, command=cmd, takefocus=FALSE, - **padding_args).pack(side=LEFT, padx=5) + self.buttons[txt] = Button(buttons_frame, text=txt, command=cmd, + takefocus=FALSE, **padding_args) + self.buttons[txt].pack(side=LEFT, padx=5) # Add space above buttons. Frame(outer, height=2, borderwidth=0).pack(side=TOP) - buttons.pack(side=BOTTOM) + buttons_frame.pack(side=BOTTOM) return outer def ok(self): @@ -209,8 +211,9 @@ def help(self): view_text: Method from textview module. """ page = self.note.tab(self.note.select(), option='text').strip() - view_text(self, title='Help for IDLE preferences', - text=help_common+help_pages.get(page, '')) + self._current_viewtext = view_text( + self, title='Help for IDLE preferences', + text=help_common+help_pages.get(page, '')) def deactivate_current_config(self): """Remove current key bindings. @@ -851,6 +854,8 @@ def create_page_highlight(self): text.configure( font=('courier', 12, ''), cursor='hand2', width=1, height=1, takefocus=FALSE, highlightthickness=0, wrap=NONE) + # Override to prevent double click and motion from propagating to + # other handlers. text.bind('', lambda e: 'break') text.bind('', lambda e: 'break') string_tags=( diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 1f14ed1f264730..4e95879e0721e9 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -8,7 +8,8 @@ import unittest from unittest import mock from idlelib.idle_test.mock_idle import Func -from tkinter import Tk, StringVar, IntVar, BooleanVar, DISABLED, NORMAL +from tkinter import (Tk, StringVar, IntVar, BooleanVar, DISABLED, + NORMAL, TclError) from idlelib import config from idlelib.configdialog import idleConf, changes, tracers @@ -30,6 +31,7 @@ keyspage = changes['keys'] extpage = changes['extensions'] + def setUpModule(): global root, dialog idleConf.userCfg = testcfg @@ -37,6 +39,7 @@ def setUpModule(): # root.withdraw() # Comment out, see issue 30870 dialog = configdialog.ConfigDialog(root, 'Test', _utest=True) + def tearDownModule(): global root, dialog idleConf.userCfg = usercfg @@ -48,6 +51,66 @@ def tearDownModule(): root = dialog = None +class ConfigDialogTest(unittest.TestCase): + + def test_deactivate_current_config(self): + pass + + def activate_config_changes(self): + pass + + +class ConfigDialogGUITest(unittest.TestCase): + + def test_click_ok(self): + d = dialog + apply = d.apply = mock.Mock() + destroy = d.destroy = mock.Mock() + d.buttons['Ok'].invoke() + apply.assert_called_once() + destroy.assert_called_once() + del d.destroy, d.apply + + def test_click_apply(self): + d = dialog + deactivate = d.deactivate_current_config = mock.Mock() + save_ext = d.save_all_changed_extensions = mock.Mock() + activate = d.activate_config_changes = mock.Mock() + d.buttons['Apply'].invoke() + deactivate.assert_called_once() + save_ext.assert_called_once() + activate.assert_called_once() + del d.save_all_changed_extensions + del d.activate_config_changes, d.deactivate_current_config + + def test_click_cancel(self): + d = dialog + destroy = d.destroy = mock.Mock() + d.buttons['Cancel'].invoke() + destroy.assert_called_once() + del d.destroy + + @mock.patch.object(configdialog, 'view_text') + def test_click_help(self, mock_textview): + d = dialog + + # Highlight help has extra text. + d.note.select(dialog.highpage) + d.buttons['Help'].invoke() + mock_textview.assert_called_once() + kwargs = mock_textview.call_args[1] + self.assertEqual(kwargs['title'], 'Help for IDLE preferences') + self.assertIn('Highlighting:', kwargs['text']) + + # Keys help page extra text. + d.note.select(dialog.keyspage) + d.buttons['Help'].invoke() + mock_textview.assert_called() + kwargs = mock_textview.call_args[1] + self.assertEqual(kwargs['title'], 'Help for IDLE preferences') + self.assertIn('Keys:', kwargs['text']) + + class FontPageTest(unittest.TestCase): """Test that font widgets enable users to make font changes. @@ -420,6 +483,90 @@ def click_it(start): eq(d.highlight_target.get(), elem[tag]) eq(d.set_highlight_target.called, count) + def test_highlight_sample_double_click(self): + # Test double click on highlight_sample. + eq = self.assertEqual + d = self.page + + hs = d.highlight_sample + hs.focus_force() + hs.see(1.0) + hs.update_idletasks() + + # Test binding from configdialog. + hs.event_generate('', x=0, y=0) + hs.event_generate('', x=0, y=0) + # Double click is a sequence of two clicks in a row. + for _ in range(2): + hs.event_generate('', x=0, y=0) + hs.event_generate('', x=0, y=0) + + self.assertNotEqual(d.highlight_target.get(), 'text double') + with self.assertRaises(TclError, msg='text doesn\'t contain any characters tagged with "sel"'): + hs.get('sel.first', 'sel.last') + + # Change binding on double click. This will allow the event to + # propagate to the other levels. The default binding for double + # click is to select the word that was double clicked. + hs.bind('', lambda e: d.highlight_target.set('test double')) + + hs.event_generate('', x=0, y=0) + hs.event_generate('', x=0, y=0) + # Double click is a sequence of two clicks in a row. + for _ in range(2): + hs.event_generate('', x=0, y=0) + hs.event_generate('', x=0, y=0) + + eq(d.highlight_target.get(), 'test double') + eq(hs.get('sel.first', 'sel.last'), '\n') + + # Remove selection and rebind. + hs.tag_remove('sel', '0.0', 'end') + hs.bind('', lambda e: 'break') + + def test_highlight_sample_b1_motion(self): + # Test button motion on highlight_sample. + eq = self.assertEqual + d = self.page + + hs = d.highlight_sample + hs.focus_force() + hs.see(1.0) + hs.update_idletasks() + + x, y, dx, dy, offset = hs.dlineinfo('1.0') + + # Test binding from configdialog. + hs.event_generate('') + hs.event_generate('') + hs.event_generate('', x=x, y=y) + hs.event_generate('', x=x, y=y) + hs.event_generate('', x=dx, y=dy) + hs.event_generate('', x=dx, y=dy) + + eq(hs.tag_ranges('sel'), ()) + + # Remove binding on button motion. This will allow the event to + # propagate to the other levels. The default binding for button + # motion is to select the text that was moused over while the button + # is held. + hs.unbind('') + x, y, dx, dy, offset = hs.dlineinfo('4.0') + + hs.event_generate('') + hs.event_generate('') + hs.event_generate('', x=x, y=y) + hs.event_generate('', x=x, y=y) + hs.event_generate('', x=x+dx, y=y+dy) + hs.event_generate('', x=x+dx, y=y+dy) + + self.assertNotEqual(hs.tag_ranges('sel'), ()) + self.assertIn('def', hs.get('sel.first', 'sel.last')) + + # Remove selection and rebind. + hs.tag_remove('sel', '0.0', 'end') + hs.bind('', lambda e: 'break') + def test_set_theme_type(self): eq = self.assertEqual d = self.page @@ -550,6 +697,17 @@ def test_create_new_and_save_new(self): self.assertFalse(d.theme_source.get()) # Use custom set. eq(d.set_theme_type.called, 1) + # Call with same name as first time to make sure it adds it only once. + d.theme_source.set(True) + d.builtin_name.set('IDLE Classic') + d.create_new(first_new) + eq(idleConf.GetSectionList('user', 'highlight'), [first_new]) + eq(idleConf.GetThemeDict('default', 'IDLE Classic'), + idleConf.GetThemeDict('user', first_new)) + eq(d.custom_name.get(), first_new) + self.assertFalse(d.theme_source.get()) # Use custom set. + eq(d.set_theme_type.called, 2) + # Test that changed targets are in new theme. changes.add_option('highlight', first_new, 'hit-background', 'yellow') self.assertNotIn(second_new, idleConf.userCfg) @@ -648,8 +806,13 @@ def test_delete_custom(self): idleConf.userCfg['highlight'].SetOption(theme_name, 'name', 'value') highpage[theme_name] = {'option': 'True'} + theme_name2 = 'other theme' + idleConf.userCfg['highlight'].SetOption(theme_name2, 'name', 'value') + highpage[theme_name2] = {'option': 'False'} + # Force custom theme. - d.theme_source.set(False) + d.custom_theme_on.state(('!disabled',)) + d.custom_theme_on.invoke() d.custom_name.set(theme_name) # Cancel deletion. @@ -657,7 +820,7 @@ def test_delete_custom(self): d.button_delete_custom.invoke() eq(yesno.called, 1) eq(highpage[theme_name], {'option': 'True'}) - eq(idleConf.GetSectionList('user', 'highlight'), ['spam theme']) + eq(idleConf.GetSectionList('user', 'highlight'), [theme_name, theme_name2]) eq(dialog.deactivate_current_config.called, 0) eq(dialog.activate_config_changes.called, 0) eq(d.set_theme_type.called, 0) @@ -667,13 +830,26 @@ def test_delete_custom(self): d.button_delete_custom.invoke() eq(yesno.called, 2) self.assertNotIn(theme_name, highpage) - eq(idleConf.GetSectionList('user', 'highlight'), []) - eq(d.custom_theme_on.state(), ('disabled',)) - eq(d.custom_name.get(), '- no custom themes -') + eq(idleConf.GetSectionList('user', 'highlight'), [theme_name2]) + eq(d.custom_theme_on.state(), ()) + eq(d.custom_name.get(), theme_name2) eq(dialog.deactivate_current_config.called, 1) eq(dialog.activate_config_changes.called, 1) eq(d.set_theme_type.called, 1) + # Confirm deletion of second theme - empties list. + d.custom_name.set(theme_name2) + yesno.result = True + d.button_delete_custom.invoke() + eq(yesno.called, 3) + self.assertNotIn(theme_name, highpage) + eq(idleConf.GetSectionList('user', 'highlight'), []) + eq(d.custom_theme_on.state(), ('disabled',)) + eq(d.custom_name.get(), '- no custom themes -') + eq(dialog.deactivate_current_config.called, 2) + eq(dialog.activate_config_changes.called, 2) + eq(d.set_theme_type.called, 2) + del dialog.activate_config_changes, dialog.deactivate_current_config del d.askyesno @@ -975,6 +1151,17 @@ def test_create_new_key_set_and_save_new_key_set(self): self.assertFalse(d.keyset_source.get()) # Use custom set. eq(d.set_keys_type.called, 1) + # Call with same name as first time to make sure it adds it only once. + d.keyset_source.set(True) + d.builtin_name.set('IDLE Classic Windows') + d.create_new_key_set(first_new) + eq(idleConf.GetSectionList('user', 'keys'), [first_new]) + eq(idleConf.GetKeySet('IDLE Classic Windows'), + idleConf.GetKeySet(first_new)) + eq(d.custom_name.get(), first_new) + self.assertFalse(d.keyset_source.get()) # Use custom set. + eq(d.set_keys_type.called, 2) + # Test that changed keybindings are in new keyset. changes.add_option('keys', first_new, 'copy', '') self.assertNotIn(second_new, idleConf.userCfg) @@ -1041,8 +1228,13 @@ def test_delete_custom_keys(self): idleConf.userCfg['keys'].SetOption(keyset_name, 'name', 'value') keyspage[keyset_name] = {'option': 'True'} + keyset_name2 = 'other key set' + idleConf.userCfg['keys'].SetOption(keyset_name2, 'name', 'value') + keyspage[keyset_name2] = {'option': 'False'} + # Force custom keyset. - d.keyset_source.set(False) + d.custom_keyset_on.state(('!disabled',)) + d.custom_keyset_on.invoke() d.custom_name.set(keyset_name) # Cancel deletion. @@ -1050,7 +1242,7 @@ def test_delete_custom_keys(self): d.button_delete_custom_keys.invoke() eq(yesno.called, 1) eq(keyspage[keyset_name], {'option': 'True'}) - eq(idleConf.GetSectionList('user', 'keys'), ['spam key set']) + eq(idleConf.GetSectionList('user', 'keys'), [keyset_name, keyset_name2]) eq(dialog.deactivate_current_config.called, 0) eq(dialog.activate_config_changes.called, 0) eq(d.set_keys_type.called, 0) @@ -1060,13 +1252,26 @@ def test_delete_custom_keys(self): d.button_delete_custom_keys.invoke() eq(yesno.called, 2) self.assertNotIn(keyset_name, keyspage) - eq(idleConf.GetSectionList('user', 'keys'), []) - eq(d.custom_keyset_on.state(), ('disabled',)) - eq(d.custom_name.get(), '- no custom keys -') + eq(idleConf.GetSectionList('user', 'keys'), [keyset_name2]) + eq(d.custom_keyset_on.state(), ()) + eq(d.custom_name.get(), keyset_name2) eq(dialog.deactivate_current_config.called, 1) eq(dialog.activate_config_changes.called, 1) eq(d.set_keys_type.called, 1) + # Confirm deletion of second keyset - empties list. + d.custom_name.set(keyset_name2) + yesno.result = True + d.button_delete_custom_keys.invoke() + eq(yesno.called, 3) + self.assertNotIn(keyset_name, keyspage) + eq(idleConf.GetSectionList('user', 'keys'), []) + eq(d.custom_keyset_on.state(), ('disabled',)) + eq(d.custom_name.get(), '- no custom keys -') + eq(dialog.deactivate_current_config.called, 2) + eq(dialog.activate_config_changes.called, 2) + eq(d.set_keys_type.called, 2) + del dialog.activate_config_changes, dialog.deactivate_current_config del d.askyesno From 648b8507f40ead2b52dcfa2a28055206dac665d6 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Sun, 19 Jan 2020 13:07:47 -0500 Subject: [PATCH 02/10] Correct tests due to other changes --- Lib/idlelib/idle_test/test_configdialog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 4e95879e0721e9..fd5fcc20ac1924 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -518,7 +518,7 @@ def test_highlight_sample_double_click(self): hs.event_generate('', x=0, y=0) eq(d.highlight_target.get(), 'test double') - eq(hs.get('sel.first', 'sel.last'), '\n') + eq(hs.get('sel.first', 'sel.last'), ' 1 # Click selects item.\n') # Remove selection and rebind. hs.tag_remove('sel', '0.0', 'end') From 45e60ffa2e96b778799ee64a369b96e5b2b87cc0 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 25 Jan 2020 17:05:25 -0500 Subject: [PATCH 03/10] Fix test failure - cannot use patch for instance addition and deletion. --- Lib/idlelib/idle_test/test_configdialog.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 3a088fd48674ab..614a3d4849456b 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -83,12 +83,14 @@ def test_click_apply(self): del d.save_all_changed_extensions del d.activate_config_changes, d.deactivate_current_config - @mock.patch.object(dialog, 'destroy', new_callable=Func) - def test_click_cancel(self, destroy): + def test_click_cancel(self): + d = dialog + d.destroy = Func() changes['main']['something'] = 1 - dialog.buttons['Cancel'].invoke() + d.buttons['Cancel'].invoke() self.assertEqual(changes['main'], {}) - self.assertEqual(destroy.called, 1) + self.assertEqual(d.destroy.called, 1) + del d.destroy @mock.patch.object(configdialog, 'view_text', new_callable=Func) def test_click_help(self, view): From 5a8e94f1d183aefdc97b22bbae033a1cb8fbc9ab Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 25 Jan 2020 17:47:10 -0500 Subject: [PATCH 04/10] Use mock.patch.object as context manager. --- Lib/idlelib/idle_test/test_configdialog.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 614a3d4849456b..59add20049f50c 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -92,12 +92,13 @@ def test_click_cancel(self): self.assertEqual(d.destroy.called, 1) del d.destroy - @mock.patch.object(configdialog, 'view_text', new_callable=Func) - def test_click_help(self, view): + def test_click_help(self): dialog.note.select(dialog.keyspage) - dialog.buttons['Help'].invoke() - self.assertEqual(view.kwds['title'], 'Help for IDLE preferences') - contents = view.kwds['contents'] + with mock.patch.object(configdialog, 'view_text', + new_callable=Func) as view: + dialog.buttons['Help'].invoke() + title, contents = view.kwds['title'], view.kwds['contents'] + self.assertEqual(title, 'Help for IDLE preferences') self.assertTrue(contents.startswith('When you click') and contents.endswith('a different name.\n')) From 14e9efce73a309563a16cc8a9dc50a761d547692 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 26 Jan 2020 01:03:57 -0500 Subject: [PATCH 05/10] Test selection block bindings. --- Lib/idlelib/configdialog.py | 3 +- Lib/idlelib/idle_test/test_configdialog.py | 47 +--------------------- 2 files changed, 3 insertions(+), 47 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index ba653188cf216d..876ce72a3dc067 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -853,8 +853,7 @@ def create_page_highlight(self): text.configure( font=('courier', 12, ''), cursor='hand2', width=1, height=1, takefocus=FALSE, highlightthickness=0, wrap=NONE) - # Override to prevent double click and motion from propagating to - # other handlers. + # Prevent perhaps invisible selection of word or slice. text.bind('', lambda e: 'break') text.bind('', lambda e: 'break') string_tags=( diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 59add20049f50c..20e568de1b4983 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -8,8 +8,7 @@ import unittest from unittest import mock from idlelib.idle_test.mock_idle import Func -from tkinter import (Tk, StringVar, IntVar, BooleanVar, DISABLED, - NORMAL, TclError) +from tkinter import (Tk, StringVar, IntVar, BooleanVar, DISABLED, NORMAL) from idlelib import config from idlelib.configdialog import idleConf, changes, tracers @@ -493,28 +492,7 @@ def test_highlight_sample_double_click(self): hs.event_generate('', x=0, y=0) hs.event_generate('', x=0, y=0) - self.assertNotEqual(d.highlight_target.get(), 'text double') - with self.assertRaises(TclError, msg='text doesn\'t contain any characters tagged with "sel"'): - hs.get('sel.first', 'sel.last') - - # Change binding on double click. This will allow the event to - # propagate to the other levels. The default binding for double - # click is to select the word that was double clicked. - hs.bind('', lambda e: d.highlight_target.set('test double')) - - hs.event_generate('', x=0, y=0) - hs.event_generate('', x=0, y=0) - # Double click is a sequence of two clicks in a row. - for _ in range(2): - hs.event_generate('', x=0, y=0) - hs.event_generate('', x=0, y=0) - - eq(d.highlight_target.get(), 'test double') - eq(hs.get('sel.first', 'sel.last'), ' 1 # Click selects item.\n') - - # Remove selection and rebind. - hs.tag_remove('sel', '0.0', 'end') - hs.bind('', lambda e: 'break') + eq(hs.tag_ranges('sel'), ()) def test_highlight_sample_b1_motion(self): # Test button motion on highlight_sample. @@ -538,27 +516,6 @@ def test_highlight_sample_b1_motion(self): eq(hs.tag_ranges('sel'), ()) - # Remove binding on button motion. This will allow the event to - # propagate to the other levels. The default binding for button - # motion is to select the text that was moused over while the button - # is held. - hs.unbind('') - x, y, dx, dy, offset = hs.dlineinfo('4.0') - - hs.event_generate('') - hs.event_generate('') - hs.event_generate('', x=x, y=y) - hs.event_generate('', x=x, y=y) - hs.event_generate('', x=x+dx, y=y+dy) - hs.event_generate('', x=x+dx, y=y+dy) - - self.assertNotEqual(hs.tag_ranges('sel'), ()) - self.assertIn('def', hs.get('sel.first', 'sel.last')) - - # Remove selection and rebind. - hs.tag_remove('sel', '0.0', 'end') - hs.bind('', lambda e: 'break') - def test_set_theme_type(self): eq = self.assertEqual d = self.page From 0b234eb6ca9895523a48787b4ecfa3d2bd7c54a3 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 26 Jan 2020 01:34:43 -0500 Subject: [PATCH 06/10] Eliminate reason to test with duplicate new names. --- Lib/idlelib/configdialog.py | 3 +-- Lib/idlelib/idle_test/test_configdialog.py | 11 ----------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 876ce72a3dc067..23156ac79ca102 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1286,8 +1286,7 @@ def save_new(self, theme_name, theme): theme_name - string, the name of the new theme theme - dictionary containing the new theme """ - if not idleConf.userCfg['highlight'].has_section(theme_name): - idleConf.userCfg['highlight'].add_section(theme_name) + idleConf.userCfg['highlight'].AddSection(theme_name) for element in theme: value = theme[element] idleConf.userCfg['highlight'].SetOption(theme_name, element, value) diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 20e568de1b4983..2baebf91ecd332 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -1100,17 +1100,6 @@ def test_create_new_key_set_and_save_new_key_set(self): self.assertFalse(d.keyset_source.get()) # Use custom set. eq(d.set_keys_type.called, 1) - # Call with same name as first time to make sure it adds it only once. - d.keyset_source.set(True) - d.builtin_name.set('IDLE Classic Windows') - d.create_new_key_set(first_new) - eq(idleConf.GetSectionList('user', 'keys'), [first_new]) - eq(idleConf.GetKeySet('IDLE Classic Windows'), - idleConf.GetKeySet(first_new)) - eq(d.custom_name.get(), first_new) - self.assertFalse(d.keyset_source.get()) # Use custom set. - eq(d.set_keys_type.called, 2) - # Test that changed keybindings are in new keyset. changes.add_option('keys', first_new, 'copy', '') self.assertNotIn(second_new, idleConf.userCfg) From 168d07e927fb0bff5d3b6142385ac6b7e83b0941 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 26 Jan 2020 01:41:58 -0500 Subject: [PATCH 07/10] Complete last commit, which changed highlight code and deleted unneeded keys test code. This does opposite. --- Lib/idlelib/configdialog.py | 3 +-- Lib/idlelib/idle_test/test_configdialog.py | 11 ----------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py index 23156ac79ca102..22359735874d19 100644 --- a/Lib/idlelib/configdialog.py +++ b/Lib/idlelib/configdialog.py @@ -1731,8 +1731,7 @@ def save_new_key_set(keyset_name, keyset): keyset_name - string, the name of the new key set keyset - dictionary containing the new keybindings """ - if not idleConf.userCfg['keys'].has_section(keyset_name): - idleConf.userCfg['keys'].add_section(keyset_name) + idleConf.userCfg['keys'].AddSection(keyset_name) for event in keyset: value = keyset[event] idleConf.userCfg['keys'].SetOption(keyset_name, event, value) diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py index 2baebf91ecd332..1fea6d41df811c 100644 --- a/Lib/idlelib/idle_test/test_configdialog.py +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -646,17 +646,6 @@ def test_create_new_and_save_new(self): self.assertFalse(d.theme_source.get()) # Use custom set. eq(d.set_theme_type.called, 1) - # Call with same name as first time to make sure it adds it only once. - d.theme_source.set(True) - d.builtin_name.set('IDLE Classic') - d.create_new(first_new) - eq(idleConf.GetSectionList('user', 'highlight'), [first_new]) - eq(idleConf.GetThemeDict('default', 'IDLE Classic'), - idleConf.GetThemeDict('user', first_new)) - eq(d.custom_name.get(), first_new) - self.assertFalse(d.theme_source.get()) # Use custom set. - eq(d.set_theme_type.called, 2) - # Test that changed targets are in new theme. changes.add_option('highlight', first_new, 'hit-background', 'yellow') self.assertNotIn(second_new, idleConf.userCfg) From 18499bf71d390e4555f0688cbd68372feec498fb Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 27 Jan 2020 16:45:53 -0500 Subject: [PATCH 08/10] News items. --- Lib/idlelib/NEWS.txt | 3 +++ Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst | 1 + 2 files changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index eda7c2788764d3..debbe8a6064f5b 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2020-10-05? ====================================== +bpo-30780: Add remaining configdialog tests for buttons and +highlight and keys tabs. + bpo-39388: Settings dialog Cancel button cancels pending changes. bpo-39050: Settings dialog Help button again displays help text. diff --git a/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst b/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst new file mode 100644 index 00000000000000..be16558771ca58 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst @@ -0,0 +1 @@ +Add remaining configdialog tests for buttons and highlight and keys tabs. From 60982c49c377f29970f25823aa8e27b2658891a4 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 27 Jan 2020 16:49:12 -0500 Subject: [PATCH 09/10] Update NEWS.txt --- Lib/idlelib/NEWS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index debbe8a6064f5b..2b543985b37837 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,7 +4,7 @@ Released on 2020-10-05? bpo-30780: Add remaining configdialog tests for buttons and -highlight and keys tabs. +highlights and keys tabs. bpo-39388: Settings dialog Cancel button cancels pending changes. From c7d7ce2da079dbd7c571886464e7f396a7477543 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Mon, 27 Jan 2020 16:49:40 -0500 Subject: [PATCH 10/10] Update 2020-01-27-16-44-29.bpo-30780.nR80qu.rst --- Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst b/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst index be16558771ca58..2f65a00a5af3b4 100644 --- a/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst +++ b/Misc/NEWS.d/next/IDLE/2020-01-27-16-44-29.bpo-30780.nR80qu.rst @@ -1 +1 @@ -Add remaining configdialog tests for buttons and highlight and keys tabs. +Add remaining configdialog tests for buttons and highlights and keys tabs.