summaryrefslogtreecommitdiff
path: root/Lib/idlelib/idle_test/test_query.py
diff options
context:
space:
mode:
authorTerry Jan Reedy <tjreedy@udel.edu>2016-07-08 00:22:50 -0400
committerTerry Jan Reedy <tjreedy@udel.edu>2016-07-08 00:22:50 -0400
commit8b22c0aada7ef9fdf6226ee07bd95b4916e5bbb1 (patch)
tree34c1ec8489a871881a08cbabf690de37e7d6e945 /Lib/idlelib/idle_test/test_query.py
parentd6402a40d3b52aa945dfc0a875b05510e88a2dab (diff)
downloadcpython-git-8b22c0aada7ef9fdf6226ee07bd95b4916e5bbb1.tar.gz
Issue #27380: IDLE: add query.HelpSource class and tests.
Remove modules that are combined in new module.
Diffstat (limited to 'Lib/idlelib/idle_test/test_query.py')
-rw-r--r--Lib/idlelib/idle_test/test_query.py214
1 files changed, 184 insertions, 30 deletions
diff --git a/Lib/idlelib/idle_test/test_query.py b/Lib/idlelib/idle_test/test_query.py
index 58873c4998..45c99fac24 100644
--- a/Lib/idlelib/idle_test/test_query.py
+++ b/Lib/idlelib/idle_test/test_query.py
@@ -1,6 +1,16 @@
"""Test idlelib.query.
-Coverage: 100%.
+Non-gui tests for Query, SectionName, ModuleName, and HelpSource use
+dummy versions that extract the non-gui methods and add other needed
+attributes. GUI tests create an instance of each class and simulate
+entries and button clicks. Subclass tests only target the new code in
+the subclass definition.
+
+The appearance of the widgets is checked by the Query and
+HelpSource htests. These are run by running query.py.
+
+Coverage: 94% (100% for Query and SectionName).
+6 of 8 missing are ModuleName exceptions I don't know how to trigger.
"""
from test.support import requires
from tkinter import Tk
@@ -9,21 +19,9 @@ from unittest import mock
from idlelib.idle_test.mock_tk import Var, Mbox_func
from idlelib import query
-Query = query.Query
-class Dummy_Query:
- # Mock for testing the following methods Query
- entry_ok = Query.entry_ok
- ok = Query.ok
- cancel = Query.cancel
- # Attributes, constant or variable, needed for tests
- entry = Var()
- result = None
- destroyed = False
- def destroy(self):
- self.destroyed = True
-
-# entry_ok calls modal messagebox.showerror if entry is not ok.
-# Mock showerrer so don't need to click to continue.
+# Mock entry.showerror messagebox so don't need click to continue
+# when entry_ok and path_ok methods call it to display errors.
+
orig_showerror = query.showerror
showerror = Mbox_func() # Instance has __call__ method.
@@ -34,7 +32,23 @@ def tearDownModule():
query.showerror = orig_showerror
+# NON-GUI TESTS
+
class QueryTest(unittest.TestCase):
+ "Test Query base class."
+
+ class Dummy_Query:
+ # Test the following Query methods.
+ entry_ok = query.Query.entry_ok
+ ok = query.Query.ok
+ cancel = query.Query.cancel
+ # Add attributes needed for the tests.
+ entry = Var()
+ result = None
+ destroyed = False
+ def destroy(self):
+ self.destroyed = True
+
dialog = Dummy_Query()
def setUp(self):
@@ -42,7 +56,7 @@ class QueryTest(unittest.TestCase):
self.dialog.result = None
self.dialog.destroyed = False
- def test_blank_entry(self):
+ def test_entry_ok_blank(self):
dialog = self.dialog
Equal = self.assertEqual
dialog.entry.set(' ')
@@ -51,7 +65,7 @@ class QueryTest(unittest.TestCase):
Equal(showerror.title, 'Entry Error')
self.assertIn('Blank', showerror.message)
- def test_good_entry(self):
+ def test_entry_ok_good(self):
dialog = self.dialog
Equal = self.assertEqual
dialog.entry.set(' good ')
@@ -59,7 +73,17 @@ class QueryTest(unittest.TestCase):
Equal((dialog.result, dialog.destroyed), (None, False))
Equal(showerror.title, None)
- def test_ok(self):
+ def test_ok_blank(self):
+ dialog = self.dialog
+ Equal = self.assertEqual
+ dialog.entry.set('')
+ dialog.entry.focus_set = mock.Mock()
+ Equal(dialog.ok(), None)
+ self.assertTrue(dialog.entry.focus_set.called)
+ del dialog.entry.focus_set
+ Equal((dialog.result, dialog.destroyed), (None, False))
+
+ def test_ok_good(self):
dialog = self.dialog
Equal = self.assertEqual
dialog.entry.set('good')
@@ -73,12 +97,14 @@ class QueryTest(unittest.TestCase):
Equal((dialog.result, dialog.destroyed), (None, True))
-class Dummy_SectionName:
- entry_ok = query.SectionName.entry_ok # Test override.
- used_names = ['used']
- entry = Var()
-
class SectionNameTest(unittest.TestCase):
+ "Test SectionName subclass of Query."
+
+ class Dummy_SectionName:
+ entry_ok = query.SectionName.entry_ok # Function being tested.
+ used_names = ['used']
+ entry = Var()
+
dialog = Dummy_SectionName()
def setUp(self):
@@ -116,12 +142,14 @@ class SectionNameTest(unittest.TestCase):
Equal(showerror.title, None)
-class Dummy_ModuleName:
- entry_ok = query.ModuleName.entry_ok # Test override
- text0 = ''
- entry = Var()
-
class ModuleNameTest(unittest.TestCase):
+ "Test ModuleName subclass of Query."
+
+ class Dummy_ModuleName:
+ entry_ok = query.ModuleName.entry_ok # Funtion being tested.
+ text0 = ''
+ entry = Var()
+
dialog = Dummy_ModuleName()
def setUp(self):
@@ -159,13 +187,119 @@ class ModuleNameTest(unittest.TestCase):
Equal(showerror.title, None)
+# 3 HelpSource test classes each test one function.
+
+orig_platform = query.platform
+
+class HelpsourceBrowsefileTest(unittest.TestCase):
+ "Test browse_file method of ModuleName subclass of Query."
+
+ class Dummy_HelpSource:
+ browse_file = query.HelpSource.browse_file
+ pathvar = Var()
+
+ dialog = Dummy_HelpSource()
+
+ def test_file_replaces_path(self):
+ # Path is widget entry, file is file dialog return.
+ dialog = self.dialog
+ for path, func, result in (
+ # We need all combination to test all (most) code paths.
+ ('', lambda a,b,c:'', ''),
+ ('', lambda a,b,c: __file__, __file__),
+ ('htest', lambda a,b,c:'', 'htest'),
+ ('htest', lambda a,b,c: __file__, __file__)):
+ with self.subTest():
+ dialog.pathvar.set(path)
+ dialog.askfilename = func
+ dialog.browse_file()
+ self.assertEqual(dialog.pathvar.get(), result)
+
+
+class HelpsourcePathokTest(unittest.TestCase):
+ "Test path_ok method of ModuleName subclass of Query."
+
+ class Dummy_HelpSource:
+ path_ok = query.HelpSource.path_ok
+ path = Var()
+
+ dialog = Dummy_HelpSource()
+
+ @classmethod
+ def tearDownClass(cls):
+ query.platform = orig_platform
+
+ def setUp(self):
+ showerror.title = None
+
+ def test_path_ok_blank(self):
+ dialog = self.dialog
+ Equal = self.assertEqual
+ dialog.path.set(' ')
+ Equal(dialog.path_ok(), None)
+ Equal(showerror.title, 'File Path Error')
+ self.assertIn('No help', showerror.message)
+
+ def test_path_ok_bad(self):
+ dialog = self.dialog
+ Equal = self.assertEqual
+ dialog.path.set(__file__ + 'bad-bad-bad')
+ Equal(dialog.path_ok(), None)
+ Equal(showerror.title, 'File Path Error')
+ self.assertIn('not exist', showerror.message)
+
+ def test_path_ok_web(self):
+ dialog = self.dialog
+ Equal = self.assertEqual
+ for url in 'www.py.org', 'http://py.org':
+ with self.subTest():
+ dialog.path.set(url)
+ Equal(dialog.path_ok(), url)
+ Equal(showerror.title, None)
+
+ def test_path_ok_file(self):
+ dialog = self.dialog
+ Equal = self.assertEqual
+ for platform, prefix in ('darwin', 'file://'), ('other', ''):
+ with self.subTest():
+ query.platform = platform
+ dialog.path.set(__file__)
+ Equal(dialog.path_ok(), prefix + __file__)
+ Equal(showerror.title, None)
+
+
+class HelpsourceEntryokTest(unittest.TestCase):
+ "Test entry_ok method of ModuleName subclass of Query."
+
+ class Dummy_HelpSource:
+ entry_ok = query.HelpSource.entry_ok
+ def item_ok(self):
+ return self.name
+ def path_ok(self):
+ return self.path
+
+ dialog = Dummy_HelpSource()
+
+ def test_entry_ok_helpsource(self):
+ dialog = self.dialog
+ for name, path, result in ((None, None, None),
+ (None, 'doc.txt', None),
+ ('doc', None, None),
+ ('doc', 'doc.txt', ('doc', 'doc.txt'))):
+ with self.subTest():
+ dialog.name, dialog.path = name, path
+ self.assertEqual(self.dialog.entry_ok(), result)
+
+
+# GUI TESTS
+
class QueryGuiTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
requires('gui')
cls.root = root = Tk()
- cls.dialog = Query(root, 'TEST', 'test', _utest=True)
+ cls.dialog = query.Query(root, 'TEST', 'test', _utest=True)
cls.dialog.destroy = mock.Mock()
@classmethod
@@ -238,5 +372,25 @@ class ModulenameGuiTest(unittest.TestCase):
del root
+class HelpsourceGuiTest(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ requires('gui')
+
+ def test_click_help_source(self):
+ root = Tk()
+ dialog = query.HelpSource(root, 'T', menuitem='__test__',
+ filepath=__file__, _utest=True)
+ Equal = self.assertEqual
+ Equal(dialog.entry.get(), '__test__')
+ Equal(dialog.path.get(), __file__)
+ dialog.button_ok.invoke()
+ Equal(dialog.result, ('__test__', __file__))
+ del dialog
+ root.destroy()
+ del root
+
+
if __name__ == '__main__':
unittest.main(verbosity=2, exit=False)