mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-30870: IDLE: Add configdialog fontlist selection unittest (#2666)
Initial patch by Louie Lu.
This commit is contained in:
parent
c40ad03bf2
commit
9b622fb903
3 changed files with 108 additions and 29 deletions
|
@ -47,6 +47,7 @@ class ConfigDialog(Toplevel):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
if _htest:
|
if _htest:
|
||||||
parent.instance_dict = {}
|
parent.instance_dict = {}
|
||||||
|
if not _utest:
|
||||||
self.withdraw()
|
self.withdraw()
|
||||||
|
|
||||||
self.configure(borderwidth=5)
|
self.configure(borderwidth=5)
|
||||||
|
@ -76,7 +77,6 @@ class ConfigDialog(Toplevel):
|
||||||
self.create_widgets()
|
self.create_widgets()
|
||||||
self.resizable(height=FALSE, width=FALSE)
|
self.resizable(height=FALSE, width=FALSE)
|
||||||
self.transient(parent)
|
self.transient(parent)
|
||||||
self.grab_set()
|
|
||||||
self.protocol("WM_DELETE_WINDOW", self.cancel)
|
self.protocol("WM_DELETE_WINDOW", self.cancel)
|
||||||
self.fontlist.focus_set()
|
self.fontlist.focus_set()
|
||||||
# XXX Decide whether to keep or delete these key bindings.
|
# XXX Decide whether to keep or delete these key bindings.
|
||||||
|
@ -88,6 +88,7 @@ class ConfigDialog(Toplevel):
|
||||||
self.attach_var_callbacks() # Avoid callbacks during load_configs.
|
self.attach_var_callbacks() # Avoid callbacks during load_configs.
|
||||||
|
|
||||||
if not _utest:
|
if not _utest:
|
||||||
|
self.grab_set()
|
||||||
self.wm_deiconify()
|
self.wm_deiconify()
|
||||||
self.wait_window()
|
self.wait_window()
|
||||||
|
|
||||||
|
|
|
@ -6,24 +6,25 @@ Attributes and methods will be added as needed for tests.
|
||||||
from idlelib.idle_test.mock_tk import Text
|
from idlelib.idle_test.mock_tk import Text
|
||||||
|
|
||||||
class Func:
|
class Func:
|
||||||
'''Mock function captures args and returns result set by test.
|
'''Record call, capture args, return/raise result set by test.
|
||||||
|
|
||||||
Attributes:
|
When mock function is called, set or use attributes:
|
||||||
self.called - records call even if no args, kwds passed.
|
self.called - increment call number even if no args, kwds passed.
|
||||||
self.result - set by init, returned by call.
|
self.args - capture positional arguments.
|
||||||
self.args - captures positional arguments.
|
self.kwds - capture keyword arguments.
|
||||||
self.kwds - captures keyword arguments.
|
self.result - return or raise value set in __init__.
|
||||||
|
|
||||||
Most common use will probably be to mock methods.
|
Most common use will probably be to mock instance methods.
|
||||||
|
Given class instance, can set and delete as instance attribute.
|
||||||
Mock_tk.Var and Mbox_func are special variants of this.
|
Mock_tk.Var and Mbox_func are special variants of this.
|
||||||
'''
|
'''
|
||||||
def __init__(self, result=None):
|
def __init__(self, result=None):
|
||||||
self.called = False
|
self.called = 0
|
||||||
self.result = result
|
self.result = result
|
||||||
self.args = None
|
self.args = None
|
||||||
self.kwds = None
|
self.kwds = None
|
||||||
def __call__(self, *args, **kwds):
|
def __call__(self, *args, **kwds):
|
||||||
self.called = True
|
self.called += 1
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwds = kwds
|
self.kwds = kwds
|
||||||
if isinstance(self.result, BaseException):
|
if isinstance(self.result, BaseException):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"""Test idlelib.configdialog.
|
"""Test idlelib.configdialog.
|
||||||
|
|
||||||
Half the class creates dialog, half works with user customizations.
|
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 idlelib.configdialog import ConfigDialog, idleConf, changes
|
||||||
from test.support import requires
|
from test.support import requires
|
||||||
|
@ -9,6 +9,7 @@ requires('gui')
|
||||||
from tkinter import Tk
|
from tkinter import Tk
|
||||||
import unittest
|
import unittest
|
||||||
import idlelib.config as config
|
import idlelib.config as config
|
||||||
|
from idlelib.idle_test.mock_idle import Func
|
||||||
|
|
||||||
# Tests should not depend on fortuitous user configurations.
|
# Tests should not depend on fortuitous user configurations.
|
||||||
# They must not affect actual user .cfg files.
|
# They must not affect actual user .cfg files.
|
||||||
|
@ -22,27 +23,29 @@ testcfg = {
|
||||||
}
|
}
|
||||||
|
|
||||||
root = None
|
root = None
|
||||||
configure = None
|
dialog = None
|
||||||
mainpage = changes['main']
|
mainpage = changes['main']
|
||||||
highpage = changes['highlight']
|
highpage = changes['highlight']
|
||||||
keyspage = changes['keys']
|
keyspage = changes['keys']
|
||||||
|
|
||||||
class TestDialog(ConfigDialog): pass # Delete?
|
|
||||||
|
class TestDialog(ConfigDialog):
|
||||||
|
pass # Delete?
|
||||||
|
|
||||||
|
|
||||||
def setUpModule():
|
def setUpModule():
|
||||||
global root, configure
|
global root, dialog
|
||||||
idleConf.userCfg = testcfg
|
idleConf.userCfg = testcfg
|
||||||
root = Tk()
|
root = Tk()
|
||||||
root.withdraw()
|
# root.withdraw() # Comment out, see issue 30870
|
||||||
configure = TestDialog(root, 'Test', _utest=True)
|
dialog = TestDialog(root, 'Test', _utest=True)
|
||||||
|
|
||||||
|
|
||||||
def tearDownModule():
|
def tearDownModule():
|
||||||
global root, configure
|
global root, dialog
|
||||||
idleConf.userCfg = usercfg
|
idleConf.userCfg = usercfg
|
||||||
configure.remove_var_callbacks()
|
dialog.remove_var_callbacks()
|
||||||
del configure
|
del dialog
|
||||||
root.update_idletasks()
|
root.update_idletasks()
|
||||||
root.destroy()
|
root.destroy()
|
||||||
del root
|
del root
|
||||||
|
@ -58,31 +61,105 @@ class FontTabTest(unittest.TestCase):
|
||||||
default_font = idleConf.GetFont(root, 'main', 'EditorWindow')
|
default_font = idleConf.GetFont(root, 'main', 'EditorWindow')
|
||||||
default_size = str(default_font[1])
|
default_size = str(default_font[1])
|
||||||
default_bold = default_font[2] == 'bold'
|
default_bold = default_font[2] == 'bold'
|
||||||
configure.font_name.set('Test Font')
|
dialog.font_name.set('Test Font')
|
||||||
expected = {'EditorWindow': {'font': 'Test Font',
|
expected = {'EditorWindow': {'font': 'Test Font',
|
||||||
'font-size': default_size,
|
'font-size': default_size,
|
||||||
'font-bold': str(default_bold)}}
|
'font-bold': str(default_bold)}}
|
||||||
self.assertEqual(mainpage, expected)
|
self.assertEqual(mainpage, expected)
|
||||||
changes.clear()
|
changes.clear()
|
||||||
configure.font_size.set(20)
|
dialog.font_size.set(20)
|
||||||
expected = {'EditorWindow': {'font': 'Test Font',
|
expected = {'EditorWindow': {'font': 'Test Font',
|
||||||
'font-size': '20',
|
'font-size': '20',
|
||||||
'font-bold': str(default_bold)}}
|
'font-bold': str(default_bold)}}
|
||||||
self.assertEqual(mainpage, expected)
|
self.assertEqual(mainpage, expected)
|
||||||
changes.clear()
|
changes.clear()
|
||||||
configure.font_bold.set(not default_bold)
|
dialog.font_bold.set(not default_bold)
|
||||||
expected = {'EditorWindow': {'font': 'Test Font',
|
expected = {'EditorWindow': {'font': 'Test Font',
|
||||||
'font-size': '20',
|
'font-size': '20',
|
||||||
'font-bold': str(not default_bold)}}
|
'font-bold': str(not default_bold)}}
|
||||||
self.assertEqual(mainpage, expected)
|
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):
|
def test_tabspace(self):
|
||||||
configure.space_num.set(6)
|
dialog.space_num.set(6)
|
||||||
self.assertEqual(mainpage, {'Indent': {'num-spaces': '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.
|
||||||
|
|
||||||
|
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)
|
||||||
|
x += dx // 2
|
||||||
|
y += dy // 2
|
||||||
|
fontlist.event_generate('<Button-1>', x=x, y=y)
|
||||||
|
fontlist.event_generate('<ButtonRelease-1>', x=x, y=y)
|
||||||
|
|
||||||
|
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):
|
class HighlightTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -103,19 +180,19 @@ class GeneralTest(unittest.TestCase):
|
||||||
changes.clear()
|
changes.clear()
|
||||||
|
|
||||||
def test_startup(self):
|
def test_startup(self):
|
||||||
configure.radio_startup_edit.invoke()
|
dialog.radio_startup_edit.invoke()
|
||||||
self.assertEqual(mainpage,
|
self.assertEqual(mainpage,
|
||||||
{'General': {'editor-on-startup': '1'}})
|
{'General': {'editor-on-startup': '1'}})
|
||||||
|
|
||||||
def test_autosave(self):
|
def test_autosave(self):
|
||||||
configure.radio_save_auto.invoke()
|
dialog.radio_save_auto.invoke()
|
||||||
self.assertEqual(mainpage, {'General': {'autosave': '1'}})
|
self.assertEqual(mainpage, {'General': {'autosave': '1'}})
|
||||||
|
|
||||||
def test_editor_size(self):
|
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'}})
|
self.assertEqual(mainpage, {'EditorWindow': {'height': '140'}})
|
||||||
changes.clear()
|
changes.clear()
|
||||||
configure.entry_win_width.insert(0, '1')
|
dialog.entry_win_width.insert(0, '1')
|
||||||
self.assertEqual(mainpage, {'EditorWindow': {'width': '180'}})
|
self.assertEqual(mainpage, {'EditorWindow': {'width': '180'}})
|
||||||
|
|
||||||
#def test_help_sources(self): pass # TODO
|
#def test_help_sources(self): pass # TODO
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue