summaryrefslogtreecommitdiffstats
path: root/Lib/idlelib/idle_test
diff options
context:
space:
mode:
authorTerry Jan Reedy <tjreedy@udel.edu>2017-07-27 00:54:40 (GMT)
committerGitHub <noreply@github.com>2017-07-27 00:54:40 (GMT)
commit2bc8f0e6867f59e5e8444b2bde99bb0fa3dbefc8 (patch)
tree78946072316d95a5d036cdff438a298b8bd4f2cb /Lib/idlelib/idle_test
parent45bf723c6c591ec56a18dad8150ae89797450d8b (diff)
downloadcpython-2bc8f0e6867f59e5e8444b2bde99bb0fa3dbefc8.zip
cpython-2bc8f0e6867f59e5e8444b2bde99bb0fa3dbefc8.tar.gz
cpython-2bc8f0e6867f59e5e8444b2bde99bb0fa3dbefc8.tar.bz2
bpo-31003: IDLE - Add more tests for General tab (#2859)
* In configdialog: Document causal pathways in create_page_general. Move related functions to follow this. Simplify some attribute names. * In test_configdialog: Add tests for load and helplist functions. Coverage for the general tab is now complete, and 63% overall.
Diffstat (limited to 'Lib/idlelib/idle_test')
-rw-r--r--Lib/idlelib/idle_test/mock_idle.py6
-rw-r--r--Lib/idlelib/idle_test/test_configdialog.py192
2 files changed, 188 insertions, 10 deletions
diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py
index 8f3147b..f279a52 100644
--- a/Lib/idlelib/idle_test/mock_idle.py
+++ b/Lib/idlelib/idle_test/mock_idle.py
@@ -13,14 +13,16 @@ class Func:
self.args - capture positional arguments.
self.kwds - capture keyword arguments.
self.result - return or raise value set in __init__.
+ self.return_self - return self instead, to mock query class return.
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.
'''
- def __init__(self, result=None):
+ def __init__(self, result=None, return_self=False):
self.called = 0
self.result = result
+ self.return_self = return_self
self.args = None
self.kwds = None
def __call__(self, *args, **kwds):
@@ -29,6 +31,8 @@ class Func:
self.kwds = kwds
if isinstance(self.result, BaseException):
raise self.result
+ elif self.return_self:
+ return self
else:
return self.result
diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py
index ce02ae4..7296075 100644
--- a/Lib/idlelib/idle_test/test_configdialog.py
+++ b/Lib/idlelib/idle_test/test_configdialog.py
@@ -1,16 +1,17 @@
"""Test idlelib.configdialog.
Half the class creates dialog, half works with user customizations.
-Coverage: 46% just by creating dialog, 60% with current tests.
+Coverage: 63%.
"""
-from idlelib.configdialog import ConfigDialog, idleConf, changes, VarTrace
+from idlelib import configdialog
from test.support import requires
requires('gui')
-from tkinter import Tk, IntVar, BooleanVar
import unittest
from unittest import mock
-import idlelib.config as config
from idlelib.idle_test.mock_idle import Func
+from tkinter import Tk, IntVar, BooleanVar, DISABLED, NORMAL
+from idlelib import config
+from idlelib.configdialog import ConfigDialog, idleConf, changes, VarTrace
# Tests should not depend on fortuitous user configurations.
# They must not affect actual user .cfg files.
@@ -226,27 +227,200 @@ class KeysTest(unittest.TestCase):
class GeneralTest(unittest.TestCase):
+ """Test that general tab widgets enable users to make changes.
+
+ Test that widget actions set vars, that var changes add
+ options to changes and that helplist works correctly.
+ """
+ @classmethod
+ def setUpClass(cls):
+ # Mask instance methods used by help functions.
+ d = dialog
+ d.set = d.set_add_delete_state = Func()
+ d.upc = d.update_help_changes = Func()
+
+ @classmethod
+ def tearDownClass(cls):
+ d = dialog
+ del d.set, d.set_add_delete_state
+ del d.upc, d.update_help_changes
+ d.helplist.delete(0, 'end')
+ d.user_helplist.clear()
def setUp(self):
changes.clear()
+ def test_load_general_cfg(self):
+ # Set to wrong values, load, check right values.
+ eq = self.assertEqual
+ d = dialog
+ d.startup_edit.set(1)
+ d.autosave.set(1)
+ d.win_width.set(1)
+ d.win_height.set(1)
+ d.helplist.insert('end', 'bad')
+ d.user_helplist = ['bad', 'worse']
+ idleConf.SetOption('main', 'HelpFiles', '1', 'name;file')
+ d.load_general_cfg()
+ eq(d.startup_edit.get(), 0)
+ eq(d.autosave.get(), 0)
+ eq(d.win_width.get(), '80')
+ eq(d.win_height.get(), '40')
+ eq(d.helplist.get(0, 'end'), ('name',))
+ eq(d.user_helplist, [('name', 'file', '1')])
+
def test_startup(self):
- dialog.radio_startup_edit.invoke()
+ dialog.startup_editor_on.invoke()
self.assertEqual(mainpage,
{'General': {'editor-on-startup': '1'}})
+ changes.clear()
+ dialog.startup_shell_on.invoke()
+ self.assertEqual(mainpage,
+ {'General': {'editor-on-startup': '0'}})
def test_autosave(self):
- dialog.radio_save_auto.invoke()
+ dialog.save_auto_on.invoke()
self.assertEqual(mainpage, {'General': {'autosave': '1'}})
+ dialog.save_ask_on.invoke()
+ self.assertEqual(mainpage, {'General': {'autosave': '0'}})
def test_editor_size(self):
- dialog.entry_win_height.insert(0, '1')
+ dialog.win_height_int.insert(0, '1')
self.assertEqual(mainpage, {'EditorWindow': {'height': '140'}})
changes.clear()
- dialog.entry_win_width.insert(0, '1')
+ dialog.win_width_int.insert(0, '1')
self.assertEqual(mainpage, {'EditorWindow': {'width': '180'}})
- #def test_help_sources(self): pass # TODO
+ def test_source_selected(self):
+ d = dialog
+ d.set = d.set_add_delete_state
+ d.upc = d.update_help_changes
+ helplist = d.helplist
+ helplist.insert(0, 'source')
+ helplist.activate(0)
+
+ helplist.focus_force()
+ helplist.see(0)
+ helplist.update()
+ x, y, dx, dy = helplist.bbox(0)
+ x += dx // 2
+ y += dy // 2
+ d.set.called = d.upc.called = 0
+ helplist.event_generate('<Button-1>', x=x, y=y)
+ helplist.event_generate('<ButtonRelease-1>', x=x, y=y)
+ self.assertEqual(helplist.get('anchor'), 'source')
+ self.assertTrue(d.set.called)
+ self.assertFalse(d.upc.called)
+
+ def test_set_add_delete_state(self):
+ # Call with 0 items, 1 unselected item, 1 selected item.
+ eq = self.assertEqual
+ d = dialog
+ del d.set_add_delete_state # Unmask method.
+ sad = d.set_add_delete_state
+ h = d.helplist
+
+ h.delete(0, 'end')
+ sad()
+ eq(d.button_helplist_edit['state'], DISABLED)
+ eq(d.button_helplist_remove['state'], DISABLED)
+
+ h.insert(0, 'source')
+ sad()
+ eq(d.button_helplist_edit['state'], DISABLED)
+ eq(d.button_helplist_remove['state'], DISABLED)
+
+ h.selection_set(0)
+ sad()
+ eq(d.button_helplist_edit['state'], NORMAL)
+ eq(d.button_helplist_remove['state'], NORMAL)
+ d.set_add_delete_state = Func() # Mask method.
+
+ def test_helplist_item_add(self):
+ # Call without and twice with HelpSource result.
+ # Double call enables check on order.
+ eq = self.assertEqual
+ orig_helpsource = configdialog.HelpSource
+ hs = configdialog.HelpSource = Func(return_self=True)
+ d = dialog
+ d.helplist.delete(0, 'end')
+ d.user_helplist.clear()
+ d.set.called = d.upc.called = 0
+
+ hs.result = ''
+ d.helplist_item_add()
+ self.assertTrue(list(d.helplist.get(0, 'end')) ==
+ d.user_helplist == [])
+ self.assertFalse(d.upc.called)
+
+ hs.result = ('name1', 'file1')
+ d.helplist_item_add()
+ hs.result = ('name2', 'file2')
+ d.helplist_item_add()
+ eq(d.helplist.get(0, 'end'), ('name1', 'name2'))
+ eq(d.user_helplist, [('name1', 'file1'), ('name2', 'file2')])
+ eq(d.upc.called, 2)
+ self.assertFalse(d.set.called)
+
+ configdialog.HelpSource = orig_helpsource
+
+ def test_helplist_item_edit(self):
+ # Call without and with HelpSource change.
+ eq = self.assertEqual
+ orig_helpsource = configdialog.HelpSource
+ hs = configdialog.HelpSource = Func(return_self=True)
+ d = dialog
+ d.helplist.delete(0, 'end')
+ d.helplist.insert(0, 'name1')
+ d.helplist.selection_set(0)
+ d.helplist.selection_anchor(0)
+ d.user_helplist.clear()
+ d.user_helplist.append(('name1', 'file1'))
+ d.set.called = d.upc.called = 0
+
+ hs.result = ''
+ d.helplist_item_edit()
+ hs.result = ('name1', 'file1')
+ d.helplist_item_edit()
+ eq(d.helplist.get(0, 'end'), ('name1',))
+ eq(d.user_helplist, [('name1', 'file1')])
+ self.assertFalse(d.upc.called)
+
+ hs.result = ('name2', 'file2')
+ d.helplist_item_edit()
+ eq(d.helplist.get(0, 'end'), ('name2',))
+ eq(d.user_helplist, [('name2', 'file2')])
+ self.assertTrue(d.upc.called == d.set.called == 1)
+
+ configdialog.HelpSource = orig_helpsource
+
+ def test_helplist_item_remove(self):
+ eq = self.assertEqual
+ d = dialog
+ d.helplist.delete(0, 'end')
+ d.helplist.insert(0, 'name1')
+ d.helplist.selection_set(0)
+ d.helplist.selection_anchor(0)
+ d.user_helplist.clear()
+ d.user_helplist.append(('name1', 'file1'))
+ d.set.called = d.upc.called = 0
+
+ d.helplist_item_remove()
+ eq(d.helplist.get(0, 'end'), ())
+ eq(d.user_helplist, [])
+ self.assertTrue(d.upc.called == d.set.called == 1)
+
+ def test_update_help_changes(self):
+ d = dialog
+ del d.update_help_changes
+ d.user_helplist.clear()
+ d.user_helplist.append(('name1', 'file1'))
+ d.user_helplist.append(('name2', 'file2'))
+
+ d.update_help_changes()
+ self.assertEqual(mainpage['HelpFiles'],
+ {'1': 'name1;file1', '2': 'name2;file2'})
+ d.update_help_changes = Func()
class TestVarTrace(unittest.TestCase):