]> granicus.if.org Git - python/commitdiff
Issue #27922: IDLE tests no longer flash tk widgets (Merge 3.5).
authorTerry Jan Reedy <tjreedy@udel.edu>
Thu, 1 Sep 2016 01:09:02 +0000 (21:09 -0400)
committerTerry Jan Reedy <tjreedy@udel.edu>
Thu, 1 Sep 2016 01:09:02 +0000 (21:09 -0400)
1  2 
Lib/idlelib/idle_test/test_config_key.py
Lib/idlelib/idle_test/test_configdialog.py
Lib/idlelib/idle_test/test_editmenu.py
Lib/idlelib/idle_test/test_history.py
Lib/idlelib/idle_test/test_hyperparser.py
Lib/idlelib/idle_test/test_macosx.py
Lib/idlelib/idle_test/test_query.py
Lib/idlelib/idle_test/test_redirector.py
Lib/idlelib/idle_test/test_textview.py

index 59d8e817e30588a07e43e3636328b08053305f9b,0000000000000000000000000000000000000000..ee3f2c835c98b7bb1306f06e509b6f5ae8c65c2a
mode 100644,000000..100644
--- /dev/null
@@@ -1,32 -1,0 +1,33 @@@
 +''' Test idlelib.config_key.
 +
 +Coverage: 56% from creating and closing dialog.
 +'''
 +from idlelib import config_key
 +from test.support import requires
 +requires('gui')
 +import unittest
 +from tkinter import Tk, Text
 +
 +
 +class GetKeysTest(unittest.TestCase):
 +
 +    @classmethod
 +    def setUpClass(cls):
 +        cls.root = Tk()
++        cls.root.withdraw()
 +
 +    @classmethod
 +    def tearDownClass(cls):
 +        cls.root.update()  # Stop "can't run event command" warning.
 +        cls.root.destroy()
 +        del cls.root
 +
 +
 +    def test_init(self):
 +        dia = config_key.GetKeysDialog(
 +            self.root, 'test', '<<Test>>', ['<Key-F12>'], _utest=True)
 +        dia.Cancel()
 +
 +
 +if __name__ == '__main__':
 +    unittest.main(verbosity=2)
index 736b098d2a6593ad50a00e11a94519b12824798c,5c09790c646ef696e6ee0b28dc287472d7bad139..70bd14e8514de8c9fda7f8857acfbaa9827c6aa7
@@@ -14,6 -15,8 +14,7 @@@ class ConfigDialogTest(unittest.TestCas
      @classmethod
      def setUpClass(cls):
          cls.root = Tk()
 -        macosx._initializeTkVariantTests(cls.root)
+         cls.root.withdraw()
  
      @classmethod
      def tearDownClass(cls):
index 654f060225c4f14587a98175cde7207011e7f63c,a258e29e0fc83cc9ab88bf4ccbfca7e7da409947..17eb25c4b4c0d99c4271de72ab6f3d21704c5e36
@@@ -17,10 -16,10 +17,11 @@@ class PasteTest(unittest.TestCase)
      @classmethod
      def setUpClass(cls):
          cls.root = root = tk.Tk()
 -        root.withdraw()
 -        PyShell.fix_x11_paste(root)
++        cls.root.withdraw()
 +        pyshell.fix_x11_paste(root)
          cls.text = tk.Text(root)
          cls.entry = tk.Entry(root)
 +        cls.tentry = ttk.Entry(root)
          cls.spin = tk.Spinbox(root)
          root.clipboard_clear()
          root.clipboard_append('two')
Simple merge
index 3c6161c5182bfb1606b32e30da18a28ac05f4e61,0000000000000000000000000000000000000000..fae75d8a497320fb182fb46fc6a5fbb9866b65a3
mode 100644,000000..100644
--- /dev/null
@@@ -1,101 -1,0 +1,103 @@@
 +'''Test idlelib.macosx.py.
 +
 +Coverage: 71% on Windows.
 +'''
 +from idlelib import macosx
 +from test.support import requires
 +import sys
 +import tkinter as tk
 +import unittest
 +import unittest.mock as mock
 +from idlelib.filelist import FileList
 +
 +mactypes = {'carbon', 'cocoa', 'xquartz'}
 +nontypes = {'other'}
 +alltypes = mactypes | nontypes
 +
 +
 +class InitTktypeTest(unittest.TestCase):
 +    "Test _init_tk_type."
 +
 +    @classmethod
 +    def setUpClass(cls):
 +        requires('gui')
 +        cls.root = tk.Tk()
++        cls.root.withdraw()
 +        cls.orig_platform = macosx.platform
 +
 +    @classmethod
 +    def tearDownClass(cls):
 +        cls.root.update_idletasks()
 +        cls.root.destroy()
 +        del cls.root
 +        macosx.platform = cls.orig_platform
 +
 +    def test_init_sets_tktype(self):
 +        "Test that _init_tk_type sets _tk_type according to platform."
 +        for platform, types in ('darwin', alltypes), ('other', nontypes):
 +            with self.subTest(platform=platform):
 +                macosx.platform = platform
 +                macosx._tk_type == None
 +                macosx._init_tk_type()
 +                self.assertIn(macosx._tk_type, types)
 +
 +
 +class IsTypeTkTest(unittest.TestCase):
 +    "Test each of the four isTypeTk predecates."
 +    isfuncs = ((macosx.isAquaTk, ('carbon', 'cocoa')),
 +               (macosx.isCarbonTk, ('carbon')),
 +               (macosx.isCocoaTk, ('cocoa')),
 +               (macosx.isXQuartz, ('xquartz')),
 +               )
 +
 +    @mock.patch('idlelib.macosx._init_tk_type')
 +    def test_is_calls_init(self, mockinit):
 +        "Test that each isTypeTk calls _init_tk_type when _tk_type is None."
 +        macosx._tk_type = None
 +        for func, whentrue in self.isfuncs:
 +            with self.subTest(func=func):
 +                func()
 +                self.assertTrue(mockinit.called)
 +                mockinit.reset_mock()
 +
 +    def test_isfuncs(self):
 +        "Test that each isTypeTk return correct bool."
 +        for func, whentrue in self.isfuncs:
 +            for tktype in alltypes:
 +                with self.subTest(func=func, whentrue=whentrue, tktype=tktype):
 +                    macosx._tk_type = tktype
 +                    (self.assertTrue if tktype in whentrue else self.assertFalse)\
 +                                     (func())
 +
 +
 +class SetupTest(unittest.TestCase):
 +    "Test setupApp."
 +
 +    @classmethod
 +    def setUpClass(cls):
 +        requires('gui')
 +        cls.root = tk.Tk()
++        cls.root.withdraw()
 +
 +    @classmethod
 +    def tearDownClass(cls):
 +        cls.root.update_idletasks()
 +        cls.root.destroy()
 +        del cls.root
 +
 +    @mock.patch('idlelib.macosx.overrideRootMenu')  #27312
 +    def test_setupapp(self, overrideRootMenu):
 +        "Call setupApp with each possible graphics type."
 +        root = self.root
 +        flist = FileList(root)
 +        for tktype in alltypes:
 +            with self.subTest(tktype=tktype):
 +                macosx._tk_type = tktype
 +                macosx.setupApp(root, flist)
 +                if tktype in ('carbon', 'cocoa'):
 +                    self.assertTrue(overrideRootMenu.called)
 +                overrideRootMenu.reset_mock()
 +
 +
 +if __name__ == '__main__':
 +    unittest.main(verbosity=2)
index e9ed694dc0c611dae39ca02f21e7c8e9a1337e49,0000000000000000000000000000000000000000..66af8eb85b2598916fb3a46c1e464f61565dfef2
mode 100644,000000..100644
--- /dev/null
@@@ -1,349 -1,0 +1,353 @@@
 +"""Test idlelib.query.
 +
 +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
 +import sys
 +from tkinter import Tk
 +import unittest
 +from unittest import mock
 +from idlelib.idle_test.mock_tk import Var
 +from idlelib import query
 +
 +
 +# 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 and initialization needed for tests.
 +        entry = Var()
 +        entry_error = {}
 +        def __init__(self, dummy_entry):
 +            self.entry.set(dummy_entry)
 +            self.entry_error['text'] = ''
 +            self.result = None
 +            self.destroyed = False
 +        def showerror(self, message):
 +            self.entry_error['text'] = message
 +        def destroy(self):
 +            self.destroyed = True
 +
 +    def test_entry_ok_blank(self):
 +        dialog = self.Dummy_Query(' ')
 +        self.assertEqual(dialog.entry_ok(), None)
 +        self.assertEqual((dialog.result, dialog.destroyed), (None, False))
 +        self.assertIn('blank line', dialog.entry_error['text'])
 +
 +    def test_entry_ok_good(self):
 +        dialog = self.Dummy_Query('  good ')
 +        Equal = self.assertEqual
 +        Equal(dialog.entry_ok(), 'good')
 +        Equal((dialog.result, dialog.destroyed), (None, False))
 +        Equal(dialog.entry_error['text'], '')
 +
 +    def test_ok_blank(self):
 +        dialog = self.Dummy_Query('')
 +        dialog.entry.focus_set = mock.Mock()
 +        self.assertEqual(dialog.ok(), None)
 +        self.assertTrue(dialog.entry.focus_set.called)
 +        del dialog.entry.focus_set
 +        self.assertEqual((dialog.result, dialog.destroyed), (None, False))
 +
 +    def test_ok_good(self):
 +        dialog = self.Dummy_Query('good')
 +        self.assertEqual(dialog.ok(), None)
 +        self.assertEqual((dialog.result, dialog.destroyed), ('good', True))
 +
 +    def test_cancel(self):
 +        dialog = self.Dummy_Query('does not matter')
 +        self.assertEqual(dialog.cancel(), None)
 +        self.assertEqual((dialog.result, dialog.destroyed), (None, True))
 +
 +
 +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()
 +        entry_error = {}
 +        def __init__(self, dummy_entry):
 +            self.entry.set(dummy_entry)
 +            self.entry_error['text'] = ''
 +        def showerror(self, message):
 +            self.entry_error['text'] = message
 +
 +    def test_blank_section_name(self):
 +        dialog = self.Dummy_SectionName(' ')
 +        self.assertEqual(dialog.entry_ok(), None)
 +        self.assertIn('no name', dialog.entry_error['text'])
 +
 +    def test_used_section_name(self):
 +        dialog = self.Dummy_SectionName('used')
 +        self.assertEqual(dialog.entry_ok(), None)
 +        self.assertIn('use', dialog.entry_error['text'])
 +
 +    def test_long_section_name(self):
 +        dialog = self.Dummy_SectionName('good'*8)
 +        self.assertEqual(dialog.entry_ok(), None)
 +        self.assertIn('longer than 30', dialog.entry_error['text'])
 +
 +    def test_good_section_name(self):
 +        dialog = self.Dummy_SectionName('  good ')
 +        self.assertEqual(dialog.entry_ok(), 'good')
 +        self.assertEqual(dialog.entry_error['text'], '')
 +
 +
 +class ModuleNameTest(unittest.TestCase):
 +    "Test ModuleName subclass of Query."
 +
 +    class Dummy_ModuleName:
 +        entry_ok = query.ModuleName.entry_ok  # Function being tested.
 +        text0 = ''
 +        entry = Var()
 +        entry_error = {}
 +        def __init__(self, dummy_entry):
 +            self.entry.set(dummy_entry)
 +            self.entry_error['text'] = ''
 +        def showerror(self, message):
 +            self.entry_error['text'] = message
 +
 +    def test_blank_module_name(self):
 +        dialog = self.Dummy_ModuleName(' ')
 +        self.assertEqual(dialog.entry_ok(), None)
 +        self.assertIn('no name', dialog.entry_error['text'])
 +
 +    def test_bogus_module_name(self):
 +        dialog = self.Dummy_ModuleName('__name_xyz123_should_not_exist__')
 +        self.assertEqual(dialog.entry_ok(), None)
 +        self.assertIn('not found', dialog.entry_error['text'])
 +
 +    def test_c_source_name(self):
 +        dialog = self.Dummy_ModuleName('itertools')
 +        self.assertEqual(dialog.entry_ok(), None)
 +        self.assertIn('source-based', dialog.entry_error['text'])
 +
 +    def test_good_module_name(self):
 +        dialog = self.Dummy_ModuleName('idlelib')
 +        self.assertTrue(dialog.entry_ok().endswith('__init__.py'))
 +        self.assertEqual(dialog.entry_error['text'], '')
 +
 +
 +# 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()
 +
 +    def test_file_replaces_path(self):
 +        dialog = self.Dummy_HelpSource()
 +        # Path is widget entry, either '' or something.
 +        # Func return is file dialog return, either '' or something.
 +        # Func return should override widget entry.
 +        # We need all 4 combination to test all (most) code paths.
 +        for path, func, result in (
 +                ('', 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 HelpSource subclass of Query."
 +
 +    class Dummy_HelpSource:
 +        path_ok = query.HelpSource.path_ok
 +        path = Var()
 +        path_error = {}
 +        def __init__(self, dummy_path):
 +            self.path.set(dummy_path)
 +            self.path_error['text'] = ''
 +        def showerror(self, message, widget=None):
 +            self.path_error['text'] = message
 +
 +    @classmethod
 +    def tearDownClass(cls):
 +        query.platform = orig_platform
 +
 +    def test_path_ok_blank(self):
 +        dialog = self.Dummy_HelpSource(' ')
 +        self.assertEqual(dialog.path_ok(), None)
 +        self.assertIn('no help file', dialog.path_error['text'])
 +
 +    def test_path_ok_bad(self):
 +        dialog = self.Dummy_HelpSource(__file__ + 'bad-bad-bad')
 +        self.assertEqual(dialog.path_ok(), None)
 +        self.assertIn('not exist', dialog.path_error['text'])
 +
 +    def test_path_ok_web(self):
 +        dialog = self.Dummy_HelpSource('')
 +        Equal = self.assertEqual
 +        for url in 'www.py.org', 'http://py.org':
 +            with self.subTest():
 +                dialog.path.set(url)
 +                self.assertEqual(dialog.path_ok(), url)
 +                self.assertEqual(dialog.path_error['text'], '')
 +
 +    def test_path_ok_file(self):
 +        dialog = self.Dummy_HelpSource('')
 +        for platform, prefix in ('darwin', 'file://'), ('other', ''):
 +            with self.subTest():
 +                query.platform = platform
 +                dialog.path.set(__file__)
 +                self.assertEqual(dialog.path_ok(), prefix + __file__)
 +                self.assertEqual(dialog.path_error['text'], '')
 +
 +
 +class HelpsourceEntryokTest(unittest.TestCase):
 +    "Test entry_ok method of HelpSource subclass of Query."
 +
 +    class Dummy_HelpSource:
 +        entry_ok = query.HelpSource.entry_ok
 +        entry_error = {}
 +        path_error = {}
 +        def item_ok(self):
 +            return self.name
 +        def path_ok(self):
 +            return self.path
 +
 +    def test_entry_ok_helpsource(self):
 +        dialog = self.Dummy_HelpSource()
 +        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(dialog.entry_ok(), result)
 +
 +
 +# GUI TESTS
 +
 +class QueryGuiTest(unittest.TestCase):
 +
 +    @classmethod
 +    def setUpClass(cls):
 +        requires('gui')
 +        cls.root = root = Tk()
++        cls.root.withdraw()
 +        cls.dialog = query.Query(root, 'TEST', 'test', _utest=True)
 +        cls.dialog.destroy = mock.Mock()
 +
 +    @classmethod
 +    def tearDownClass(cls):
 +        del cls.dialog
 +        cls.root.destroy()
 +        del cls.root
 +
 +    def setUp(self):
 +        self.dialog.entry.delete(0, 'end')
 +        self.dialog.result = None
 +        self.dialog.destroy.reset_mock()
 +
 +    def test_click_ok(self):
 +        dialog = self.dialog
 +        dialog.entry.insert(0, 'abc')
 +        dialog.button_ok.invoke()
 +        self.assertEqual(dialog.result, 'abc')
 +        self.assertTrue(dialog.destroy.called)
 +
 +    def test_click_blank(self):
 +        dialog = self.dialog
 +        dialog.button_ok.invoke()
 +        self.assertEqual(dialog.result, None)
 +        self.assertFalse(dialog.destroy.called)
 +
 +    def test_click_cancel(self):
 +        dialog = self.dialog
 +        dialog.entry.insert(0, 'abc')
 +        dialog.button_cancel.invoke()
 +        self.assertEqual(dialog.result, None)
 +        self.assertTrue(dialog.destroy.called)
 +
 +
 +class SectionnameGuiTest(unittest.TestCase):
 +
 +    @classmethod
 +    def setUpClass(cls):
 +        requires('gui')
 +
 +    def test_click_section_name(self):
 +        root = Tk()
++        root.withdraw()
 +        dialog =  query.SectionName(root, 'T', 't', {'abc'}, _utest=True)
 +        Equal = self.assertEqual
 +        self.assertEqual(dialog.used_names, {'abc'})
 +        dialog.entry.insert(0, 'okay')
 +        dialog.button_ok.invoke()
 +        self.assertEqual(dialog.result, 'okay')
 +        del dialog
 +        root.destroy()
 +        del root
 +
 +
 +class ModulenameGuiTest(unittest.TestCase):
 +
 +    @classmethod
 +    def setUpClass(cls):
 +        requires('gui')
 +
 +    def test_click_module_name(self):
 +        root = Tk()
++        root.withdraw()
 +        dialog =  query.ModuleName(root, 'T', 't', 'idlelib', _utest=True)
 +        self.assertEqual(dialog.text0, 'idlelib')
 +        self.assertEqual(dialog.entry.get(), 'idlelib')
 +        dialog.button_ok.invoke()
 +        self.assertTrue(dialog.result.endswith('__init__.py'))
 +        del dialog
 +        root.destroy()
 +        del root
 +
 +
 +class HelpsourceGuiTest(unittest.TestCase):
 +
 +    @classmethod
 +    def setUpClass(cls):
 +        requires('gui')
 +
 +    def test_click_help_source(self):
 +        root = Tk()
++        root.withdraw()
 +        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()
 +        prefix = "file://" if sys.platform == 'darwin' else ''
 +        Equal(dialog.result, ('__test__', prefix + __file__))
 +        del dialog
 +        root.destroy()
 +        del root
 +
 +
 +if __name__ == '__main__':
 +    unittest.main(verbosity=2, exit=False)
index c1edcb040c6fc7cc0c72bcf21de86c2d3cb7b3b3,5d2e60019d75d66f98d774b873f8072842554474..f018f5ef1975bad32fdf07b6769315f31add3e63
@@@ -59,11 -60,11 +60,11 @@@ class TextViewTest(unittest.TestCase)
          view.destroy = Func()
          view.Ok()
          self.assertTrue(view.destroy.called)
-         del view.destroy  # unmask real function
-         view.destroy
+         del view.destroy  # Unmask real function.
+         view.destroy()
  
  
 -class textviewTest(unittest.TestCase):
 +class ViewFunctionTest(unittest.TestCase):
  
      @classmethod
      def setUpClass(cls):
  
      @classmethod
      def tearDownClass(cls):
 -        tv.tkMessageBox = cls.orig_mbox
 -        del cls.orig_mbox
 +        tv.showerror = cls.orig_error
 +        del cls.orig_error
  
      def test_view_text(self):
-         # If modal True, tkinter will error with 'can't invoke "event" command'
+         # If modal True, get tk error 'can't invoke "event" command'.
          view = tv.view_text(root, 'Title', 'test text', modal=False)
          self.assertIsInstance(view, tv.TextViewer)
+         view.Ok()
  
      def test_view_file(self):
          test_dir = os.path.dirname(__file__)
@@@ -88,7 -90,7 +90,7 @@@
          self.assertIn('Test', view.textView.get('1.0', '1.end'))
          view.Ok()
  
-         # Mock showerror will be used and view_file will return None
 -        # Mock messagebox will be used and view_file will not return anything
++        # Mock showerror will be used; view_file will return None.
          testfile = os.path.join(test_dir, '../notthere.py')
          view = tv.view_file(root, 'Title', testfile, modal=False)
          self.assertIsNone(view)