-
-
Notifications
You must be signed in to change notification settings - Fork 34.8k
bpo-30870: IDLE: Add configdialog fontlist unittest #2666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
ff8ab19
bd1c784
5f8df49
255fd75
e676416
65b9c25
4ed55c9
331354d
961cc3d
f43d396
6f58026
ec67c26
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,15 @@ | ||
| """Test idlelib.configdialog. | ||
|
|
||
| Half the class creates dialog, half works with user customizations. | ||
| Coverage: 46% just by creating dialog, 56% with current tests. | ||
| Coverage: 46% just by creating dialog, 60% with current tests. | ||
| """ | ||
| from idlelib.configdialog import ConfigDialog, idleConf, changes | ||
| from test.support import requires | ||
| requires('gui') | ||
| from tkinter import Tk | ||
| import unittest | ||
| import idlelib.config as config | ||
| from idlelib.idle_test.mock_idle import Func | ||
|
|
||
| # Tests should not depend on fortuitous user configurations. | ||
| # They must not affect actual user .cfg files. | ||
|
|
@@ -22,27 +23,29 @@ | |
| } | ||
|
|
||
| root = None | ||
| configure = None | ||
| dialog = None | ||
| mainpage = changes['main'] | ||
| highpage = changes['highlight'] | ||
| keyspage = changes['keys'] | ||
|
|
||
| class TestDialog(ConfigDialog): pass # Delete? | ||
|
|
||
| class TestDialog(ConfigDialog): | ||
| pass # Delete? | ||
|
|
||
|
|
||
| def setUpModule(): | ||
| global root, configure | ||
| global root, dialog | ||
| idleConf.userCfg = testcfg | ||
| root = Tk() | ||
| root.withdraw() | ||
| configure = TestDialog(root, 'Test', _utest=True) | ||
| # root.withdraw() # Comment out, see issue 30870 | ||
| dialog = TestDialog(root, 'Test', _utest=True) | ||
|
|
||
|
|
||
| def tearDownModule(): | ||
| global root, configure | ||
| global root, dialog | ||
| idleConf.userCfg = usercfg | ||
| configure.remove_var_callbacks() | ||
| del configure | ||
| dialog.remove_var_callbacks() | ||
| del dialog | ||
| root.update_idletasks() | ||
| root.destroy() | ||
| del root | ||
|
|
@@ -58,31 +61,103 @@ def test_font(self): | |
| default_font = idleConf.GetFont(root, 'main', 'EditorWindow') | ||
| default_size = str(default_font[1]) | ||
| default_bold = default_font[2] == 'bold' | ||
| configure.font_name.set('Test Font') | ||
| dialog.font_name.set('Test Font') | ||
| expected = {'EditorWindow': {'font': 'Test Font', | ||
| 'font-size': default_size, | ||
| 'font-bold': str(default_bold)}} | ||
| self.assertEqual(mainpage, expected) | ||
| changes.clear() | ||
| configure.font_size.set(20) | ||
| dialog.font_size.set(20) | ||
| expected = {'EditorWindow': {'font': 'Test Font', | ||
| 'font-size': '20', | ||
| 'font-bold': str(default_bold)}} | ||
| self.assertEqual(mainpage, expected) | ||
| changes.clear() | ||
| configure.font_bold.set(not default_bold) | ||
| dialog.font_bold.set(not default_bold) | ||
| expected = {'EditorWindow': {'font': 'Test Font', | ||
| 'font-size': '20', | ||
| 'font-bold': str(not default_bold)}} | ||
| self.assertEqual(mainpage, expected) | ||
|
|
||
| #def test_sample(self): pass # TODO | ||
| def test_set_sample(self): | ||
| # Set_font_sample also sets highlight_sample. | ||
| pass | ||
|
|
||
| def test_tabspace(self): | ||
| configure.space_num.set(6) | ||
| dialog.space_num.set(6) | ||
| self.assertEqual(mainpage, {'Indent': {'num-spaces': '6'}}) | ||
|
|
||
|
|
||
| class FontSelectTest(unittest.TestCase): | ||
| # These two functions test that selecting a new font in the | ||
| # list of fonts changes font_name and calls set_font_sample. | ||
| # The fontlist widget and on_fontlist_select event handler | ||
| # are tested here together. | ||
|
|
||
| @classmethod | ||
| def setUpClass(cls): | ||
| if dialog.fontlist.size() < 2: | ||
| cls.skipTest('need at least 2 fonts') | ||
| dialog.set_font_sample = Func() # Mask instance method | ||
|
|
||
| @classmethod | ||
| def tearDownClass(cls): | ||
| del dialog.set_font_sample # Unmask instance method | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Old habits die hard. I added the '.'s. |
||
|
|
||
| def setUp(self): | ||
| dialog.set_font_sample.called = 0 | ||
| changes.clear() | ||
|
|
||
| def test_select_font_key(self): | ||
| # Up and Down keys should select a new font. | ||
|
|
||
| fontlist = dialog.fontlist | ||
| fontlist.activate(0) | ||
| font = dialog.fontlist.get('active') | ||
|
|
||
| # Test Down key. | ||
| fontlist.focus_force() | ||
| fontlist.update() | ||
| fontlist.event_generate('<Key-Down>') | ||
| fontlist.event_generate('<KeyRelease-Down>') | ||
|
|
||
| down_font = fontlist.get('active') | ||
| self.assertNotEqual(down_font, font) | ||
| self.assertIn(dialog.font_name.get(), down_font.lower()) | ||
| self.assertEqual(dialog.set_font_sample.called, 1) | ||
|
|
||
| # Test Up key. | ||
| fontlist.focus_force() | ||
| fontlist.update() | ||
| fontlist.event_generate('<Key-Up>') | ||
| fontlist.event_generate('<KeyRelease-Up>') | ||
|
|
||
| up_font = fontlist.get('active') | ||
| self.assertEqual(up_font, font) | ||
| self.assertIn(dialog.font_name.get(), up_font.lower()) | ||
| self.assertEqual(dialog.set_font_sample.called, 2) | ||
|
|
||
| def test_select_font_mouse(self): | ||
| # Click on item should select that item. | ||
|
|
||
| fontlist = dialog.fontlist | ||
| fontlist.activate(0) | ||
|
|
||
| # Select next item in listbox | ||
| fontlist.focus_force() | ||
| fontlist.see(1) | ||
| fontlist.update() | ||
| x, y, dx, dy = fontlist.bbox(1) | ||
| fontlist.event_generate('<Button-1>', x=x + dx // 2, y=y + dy // 2) | ||
| fontlist.event_generate('<ButtonRelease-1>', x=x + dx // 2, y=y + dy // 2) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree. For an assignment statement, I would write
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After re-reading PEP8, I concur with your way to present I convert it to another way to represent: I hope this will be more general in this case.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With two uses, that looks better. |
||
|
|
||
| font1 = fontlist.get(1) | ||
| select_font = fontlist.get('anchor') | ||
| self.assertEqual(select_font, font1) | ||
| self.assertIn(dialog.font_name.get(), font1.lower()) | ||
| self.assertEqual(dialog.set_font_sample.called, 1) | ||
|
|
||
|
|
||
| class HighlightTest(unittest.TestCase): | ||
|
|
||
| def setUp(self): | ||
|
|
@@ -103,19 +178,19 @@ def setUp(self): | |
| changes.clear() | ||
|
|
||
| def test_startup(self): | ||
| configure.radio_startup_edit.invoke() | ||
| dialog.radio_startup_edit.invoke() | ||
| self.assertEqual(mainpage, | ||
| {'General': {'editor-on-startup': '1'}}) | ||
|
|
||
| def test_autosave(self): | ||
| configure.radio_save_auto.invoke() | ||
| dialog.radio_save_auto.invoke() | ||
| self.assertEqual(mainpage, {'General': {'autosave': '1'}}) | ||
|
|
||
| def test_editor_size(self): | ||
| configure.entry_win_height.insert(0, '1') | ||
| dialog.entry_win_height.insert(0, '1') | ||
| self.assertEqual(mainpage, {'EditorWindow': {'height': '140'}}) | ||
| changes.clear() | ||
| configure.entry_win_width.insert(0, '1') | ||
| dialog.entry_win_width.insert(0, '1') | ||
| self.assertEqual(mainpage, {'EditorWindow': {'width': '180'}}) | ||
|
|
||
| #def test_help_sources(self): pass # TODO | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe at least some other dialogs have grab_set here already. Is this move also needed for event_generate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only saw it at
textviewthat control withmodelargument.grab_setsomehow will affectevent_generate, too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test_textviewmock out thegrab_set, hmm. Should we mock out, too?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it will not be called, no need. I just read the UNM Shipman doc "Widget w grabs all events for w's application. If there was another grab in force, it goes away. See Section 54, “Events” for a discussion of grabs." Seems to be related to dialog being modal. Did not see anything in Sect.54 though. I need to make sure I know about all the calls in various inits.