bpo-44282: Fix occasional test_incremental_editing failures on buildbots (GH-26491)

Signed-off-by: Tal Einat <532281+taleinat@users.noreply.github.com>
This commit is contained in:
Tal Einat 2021-06-03 02:53:41 +03:00 committed by GitHub
parent 320eaa7f42
commit adef445dc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 41 deletions

View File

@ -551,7 +551,7 @@ class ColorDelegatorTest(unittest.TestCase):
''') ''')
self._assert_highlighting(source, {'STRING': [('1.0', '5.4')]}) self._assert_highlighting(source, {'STRING': [('1.0', '5.4')]})
@run_in_tk_mainloop @run_in_tk_mainloop(delay=50)
def test_incremental_editing(self): def test_incremental_editing(self):
text = self.text text = self.text
eq = self.assertEqual eq = self.assertEqual

View File

@ -510,19 +510,19 @@ class ShellSidebarTest(unittest.TestCase):
) )
self.assert_sidebar_lines_synced() self.assert_sidebar_lines_synced()
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_single_empty_input(self): def test_single_empty_input(self):
self.do_input('\n') self.do_input('\n')
yield yield
self.assert_sidebar_lines_end_with(['>>>', '>>>']) self.assert_sidebar_lines_end_with(['>>>', '>>>'])
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_single_line_statement(self): def test_single_line_statement(self):
self.do_input('1\n') self.do_input('1\n')
yield yield
self.assert_sidebar_lines_end_with(['>>>', None, '>>>']) self.assert_sidebar_lines_end_with(['>>>', None, '>>>'])
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_multi_line_statement(self): def test_multi_line_statement(self):
# Block statements are not indented because IDLE auto-indents. # Block statements are not indented because IDLE auto-indents.
self.do_input(dedent('''\ self.do_input(dedent('''\
@ -540,14 +540,14 @@ class ShellSidebarTest(unittest.TestCase):
'>>>', '>>>',
]) ])
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_single_long_line_wraps(self): def test_single_long_line_wraps(self):
self.do_input('1' * 200 + '\n') self.do_input('1' * 200 + '\n')
yield yield
self.assert_sidebar_lines_end_with(['>>>', None, '>>>']) self.assert_sidebar_lines_end_with(['>>>', None, '>>>'])
self.assert_sidebar_lines_synced() self.assert_sidebar_lines_synced()
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_squeeze_multi_line_output(self): def test_squeeze_multi_line_output(self):
shell = self.shell shell = self.shell
text = shell.text text = shell.text
@ -567,7 +567,7 @@ class ShellSidebarTest(unittest.TestCase):
self.assert_sidebar_lines_end_with(['>>>', None, None, None, '>>>']) self.assert_sidebar_lines_end_with(['>>>', None, None, None, '>>>'])
self.assert_sidebar_lines_synced() self.assert_sidebar_lines_synced()
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_interrupt_recall_undo_redo(self): def test_interrupt_recall_undo_redo(self):
text = self.shell.text text = self.shell.text
# Block statements are not indented because IDLE auto-indents. # Block statements are not indented because IDLE auto-indents.
@ -613,7 +613,7 @@ class ShellSidebarTest(unittest.TestCase):
['>>>', '...', '...', '...', None, '>>>'] ['>>>', '...', '...', '...', None, '>>>']
) )
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_very_long_wrapped_line(self): def test_very_long_wrapped_line(self):
with swap_attr(self.shell, 'squeezer', None): with swap_attr(self.shell, 'squeezer', None):
self.do_input('x = ' + '1'*10_000 + '\n') self.do_input('x = ' + '1'*10_000 + '\n')
@ -678,7 +678,7 @@ class ShellSidebarTest(unittest.TestCase):
sidebar.update_colors() sidebar.update_colors()
self.assertEqual(get_sidebar_colors(), test_colors) self.assertEqual(get_sidebar_colors(), test_colors)
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_mousewheel(self): def test_mousewheel(self):
sidebar = self.shell.shell_sidebar sidebar = self.shell.shell_sidebar
text = self.shell.text text = self.shell.text
@ -703,7 +703,7 @@ class ShellSidebarTest(unittest.TestCase):
yield yield
self.assertIsNotNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) self.assertIsNotNone(text.dlineinfo(text.index(f'{last_lineno}.0')))
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_copy(self): def test_copy(self):
sidebar = self.shell.shell_sidebar sidebar = self.shell.shell_sidebar
text = self.shell.text text = self.shell.text
@ -728,7 +728,7 @@ class ShellSidebarTest(unittest.TestCase):
copied_text = text.clipboard_get() copied_text = text.clipboard_get()
self.assertEqual(copied_text, selected_text) self.assertEqual(copied_text, selected_text)
@run_in_tk_mainloop @run_in_tk_mainloop()
def test_copy_with_prompts(self): def test_copy_with_prompts(self):
sidebar = self.shell.shell_sidebar sidebar = self.shell.shell_sidebar
text = self.shell.text text = self.shell.text

View File

@ -2,7 +2,7 @@
import functools import functools
def run_in_tk_mainloop(test_method): def run_in_tk_mainloop(delay=1):
"""Decorator for running a test method with a real Tk mainloop. """Decorator for running a test method with a real Tk mainloop.
This starts a Tk mainloop before running the test, and stops it This starts a Tk mainloop before running the test, and stops it
@ -13,17 +13,21 @@ def run_in_tk_mainloop(test_method):
using "yield" to allow the mainloop to process events and "after" using "yield" to allow the mainloop to process events and "after"
callbacks, and then continue the test from that point. callbacks, and then continue the test from that point.
The delay argument is passed into root.after(...) calls as the number
of ms to wait before passing execution back to the generator function.
This also assumes that the test class has a .root attribute, This also assumes that the test class has a .root attribute,
which is a tkinter.Tk object. which is a tkinter.Tk object.
For example (from test_sidebar.py): For example (from test_sidebar.py):
@run_test_with_tk_mainloop @run_test_with_tk_mainloop()
def test_single_empty_input(self): def test_single_empty_input(self):
self.do_input('\n') self.do_input('\n')
yield yield
self.assert_sidebar_lines_end_with(['>>>', '>>>']) self.assert_sidebar_lines_end_with(['>>>', '>>>'])
""" """
def decorator(test_method):
@functools.wraps(test_method) @functools.wraps(test_method)
def new_test_method(self): def new_test_method(self):
test_generator = test_method(self) test_generator = test_method(self)
@ -46,7 +50,7 @@ def run_in_tk_mainloop(test_method):
# using a robust method of ensuring that it gets a # using a robust method of ensuring that it gets a
# chance to process queued events before doing so. # chance to process queued events before doing so.
# See: https://stackoverflow.com/q/18499082#comment65004099_38817470 # See: https://stackoverflow.com/q/18499082#comment65004099_38817470
root.after(1, root.after_idle, after_callback) root.after(delay, root.after_idle, after_callback)
root.after(0, root.after_idle, after_callback) root.after(0, root.after_idle, after_callback)
root.mainloop() root.mainloop()
@ -54,3 +58,5 @@ def run_in_tk_mainloop(test_method):
raise exception raise exception
return new_test_method return new_test_method
return decorator