mirror of https://github.com/python/cpython
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:
parent
320eaa7f42
commit
adef445dc3
|
@ -551,7 +551,7 @@ class ColorDelegatorTest(unittest.TestCase):
|
|||
''')
|
||||
self._assert_highlighting(source, {'STRING': [('1.0', '5.4')]})
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop(delay=50)
|
||||
def test_incremental_editing(self):
|
||||
text = self.text
|
||||
eq = self.assertEqual
|
||||
|
|
|
@ -510,19 +510,19 @@ class ShellSidebarTest(unittest.TestCase):
|
|||
)
|
||||
self.assert_sidebar_lines_synced()
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_single_empty_input(self):
|
||||
self.do_input('\n')
|
||||
yield
|
||||
self.assert_sidebar_lines_end_with(['>>>', '>>>'])
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_single_line_statement(self):
|
||||
self.do_input('1\n')
|
||||
yield
|
||||
self.assert_sidebar_lines_end_with(['>>>', None, '>>>'])
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_multi_line_statement(self):
|
||||
# Block statements are not indented because IDLE auto-indents.
|
||||
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):
|
||||
self.do_input('1' * 200 + '\n')
|
||||
yield
|
||||
self.assert_sidebar_lines_end_with(['>>>', None, '>>>'])
|
||||
self.assert_sidebar_lines_synced()
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_squeeze_multi_line_output(self):
|
||||
shell = self.shell
|
||||
text = shell.text
|
||||
|
@ -567,7 +567,7 @@ class ShellSidebarTest(unittest.TestCase):
|
|||
self.assert_sidebar_lines_end_with(['>>>', None, None, None, '>>>'])
|
||||
self.assert_sidebar_lines_synced()
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_interrupt_recall_undo_redo(self):
|
||||
text = self.shell.text
|
||||
# Block statements are not indented because IDLE auto-indents.
|
||||
|
@ -613,7 +613,7 @@ class ShellSidebarTest(unittest.TestCase):
|
|||
['>>>', '...', '...', '...', None, '>>>']
|
||||
)
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_very_long_wrapped_line(self):
|
||||
with swap_attr(self.shell, 'squeezer', None):
|
||||
self.do_input('x = ' + '1'*10_000 + '\n')
|
||||
|
@ -678,7 +678,7 @@ class ShellSidebarTest(unittest.TestCase):
|
|||
sidebar.update_colors()
|
||||
self.assertEqual(get_sidebar_colors(), test_colors)
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_mousewheel(self):
|
||||
sidebar = self.shell.shell_sidebar
|
||||
text = self.shell.text
|
||||
|
@ -703,7 +703,7 @@ class ShellSidebarTest(unittest.TestCase):
|
|||
yield
|
||||
self.assertIsNotNone(text.dlineinfo(text.index(f'{last_lineno}.0')))
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_copy(self):
|
||||
sidebar = self.shell.shell_sidebar
|
||||
text = self.shell.text
|
||||
|
@ -728,7 +728,7 @@ class ShellSidebarTest(unittest.TestCase):
|
|||
copied_text = text.clipboard_get()
|
||||
self.assertEqual(copied_text, selected_text)
|
||||
|
||||
@run_in_tk_mainloop
|
||||
@run_in_tk_mainloop()
|
||||
def test_copy_with_prompts(self):
|
||||
sidebar = self.shell.shell_sidebar
|
||||
text = self.shell.text
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
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.
|
||||
|
||||
This starts a Tk mainloop before running the test, and stops it
|
||||
|
@ -13,44 +13,50 @@ def run_in_tk_mainloop(test_method):
|
|||
using "yield" to allow the mainloop to process events and "after"
|
||||
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,
|
||||
which is a tkinter.Tk object.
|
||||
|
||||
For example (from test_sidebar.py):
|
||||
|
||||
@run_test_with_tk_mainloop
|
||||
@run_test_with_tk_mainloop()
|
||||
def test_single_empty_input(self):
|
||||
self.do_input('\n')
|
||||
yield
|
||||
self.assert_sidebar_lines_end_with(['>>>', '>>>'])
|
||||
"""
|
||||
@functools.wraps(test_method)
|
||||
def new_test_method(self):
|
||||
test_generator = test_method(self)
|
||||
root = self.root
|
||||
# Exceptions raised by self.assert...() need to be raised
|
||||
# outside of the after() callback in order for the test
|
||||
# harness to capture them.
|
||||
exception = None
|
||||
def after_callback():
|
||||
nonlocal exception
|
||||
try:
|
||||
next(test_generator)
|
||||
except StopIteration:
|
||||
root.quit()
|
||||
except Exception as exc:
|
||||
exception = exc
|
||||
root.quit()
|
||||
else:
|
||||
# Schedule the Tk mainloop to call this function again,
|
||||
# using a robust method of ensuring that it gets a
|
||||
# chance to process queued events before doing so.
|
||||
# See: https://stackoverflow.com/q/18499082#comment65004099_38817470
|
||||
root.after(1, root.after_idle, after_callback)
|
||||
root.after(0, root.after_idle, after_callback)
|
||||
root.mainloop()
|
||||
def decorator(test_method):
|
||||
@functools.wraps(test_method)
|
||||
def new_test_method(self):
|
||||
test_generator = test_method(self)
|
||||
root = self.root
|
||||
# Exceptions raised by self.assert...() need to be raised
|
||||
# outside of the after() callback in order for the test
|
||||
# harness to capture them.
|
||||
exception = None
|
||||
def after_callback():
|
||||
nonlocal exception
|
||||
try:
|
||||
next(test_generator)
|
||||
except StopIteration:
|
||||
root.quit()
|
||||
except Exception as exc:
|
||||
exception = exc
|
||||
root.quit()
|
||||
else:
|
||||
# Schedule the Tk mainloop to call this function again,
|
||||
# using a robust method of ensuring that it gets a
|
||||
# chance to process queued events before doing so.
|
||||
# See: https://stackoverflow.com/q/18499082#comment65004099_38817470
|
||||
root.after(delay, root.after_idle, after_callback)
|
||||
root.after(0, root.after_idle, after_callback)
|
||||
root.mainloop()
|
||||
|
||||
if exception:
|
||||
raise exception
|
||||
if exception:
|
||||
raise exception
|
||||
|
||||
return new_test_method
|
||||
return new_test_method
|
||||
|
||||
return decorator
|
||||
|
|
Loading…
Reference in New Issue