diff options
author | Terry Jan Reedy <tjreedy@udel.edu> | 2016-07-08 00:22:50 -0400 |
---|---|---|
committer | Terry Jan Reedy <tjreedy@udel.edu> | 2016-07-08 00:22:50 -0400 |
commit | 8b22c0aada7ef9fdf6226ee07bd95b4916e5bbb1 (patch) | |
tree | 34c1ec8489a871881a08cbabf690de37e7d6e945 /Lib/idlelib/idle_test/test_query.py | |
parent | d6402a40d3b52aa945dfc0a875b05510e88a2dab (diff) | |
download | cpython-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.py | 214 |
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) |