diff options
Diffstat (limited to 'Lib/idlelib/idle_test/test_codecontext.py')
-rw-r--r-- | Lib/idlelib/idle_test/test_codecontext.py | 447 |
1 files changed, 0 insertions, 447 deletions
diff --git a/Lib/idlelib/idle_test/test_codecontext.py b/Lib/idlelib/idle_test/test_codecontext.py deleted file mode 100644 index 3ec49e9..0000000 --- a/Lib/idlelib/idle_test/test_codecontext.py +++ /dev/null @@ -1,447 +0,0 @@ -"Test codecontext, coverage 100%" - -from idlelib import codecontext -import unittest -import unittest.mock -from test.support import requires -from tkinter import NSEW, Tk, Frame, Text, TclError - -from unittest import mock -import re -from idlelib import config - - -usercfg = codecontext.idleConf.userCfg -testcfg = { - 'main': config.IdleUserConfParser(''), - 'highlight': config.IdleUserConfParser(''), - 'keys': config.IdleUserConfParser(''), - 'extensions': config.IdleUserConfParser(''), -} -code_sample = """\ - -class C1(): - # Class comment. - def __init__(self, a, b): - self.a = a - self.b = b - def compare(self): - if a > b: - return a - elif a < b: - return b - else: - return None -""" - - -class DummyEditwin: - def __init__(self, root, frame, text): - self.root = root - self.top = root - self.text_frame = frame - self.text = text - self.label = '' - - def getlineno(self, index): - return int(float(self.text.index(index))) - - def update_menu_label(self, **kwargs): - self.label = kwargs['label'] - - -class CodeContextTest(unittest.TestCase): - - @classmethod - def setUpClass(cls): - requires('gui') - root = cls.root = Tk() - root.withdraw() - frame = cls.frame = Frame(root) - text = cls.text = Text(frame) - text.insert('1.0', code_sample) - # Need to pack for creation of code context text widget. - frame.pack(side='left', fill='both', expand=1) - text.grid(row=1, column=1, sticky=NSEW) - cls.editor = DummyEditwin(root, frame, text) - codecontext.idleConf.userCfg = testcfg - - @classmethod - def tearDownClass(cls): - codecontext.idleConf.userCfg = usercfg - cls.editor.text.delete('1.0', 'end') - del cls.editor, cls.frame, cls.text - cls.root.update_idletasks() - cls.root.destroy() - del cls.root - - def setUp(self): - self.text.yview(0) - self.text['font'] = 'TkFixedFont' - self.cc = codecontext.CodeContext(self.editor) - - self.highlight_cfg = {"background": '#abcdef', - "foreground": '#123456'} - orig_idleConf_GetHighlight = codecontext.idleConf.GetHighlight - def mock_idleconf_GetHighlight(theme, element): - if element == 'context': - return self.highlight_cfg - return orig_idleConf_GetHighlight(theme, element) - GetHighlight_patcher = unittest.mock.patch.object( - codecontext.idleConf, 'GetHighlight', mock_idleconf_GetHighlight) - GetHighlight_patcher.start() - self.addCleanup(GetHighlight_patcher.stop) - - self.font_override = 'TkFixedFont' - def mock_idleconf_GetFont(root, configType, section): - return self.font_override - GetFont_patcher = unittest.mock.patch.object( - codecontext.idleConf, 'GetFont', mock_idleconf_GetFont) - GetFont_patcher.start() - self.addCleanup(GetFont_patcher.stop) - - def tearDown(self): - if self.cc.context: - self.cc.context.destroy() - # Explicitly call __del__ to remove scheduled scripts. - self.cc.__del__() - del self.cc.context, self.cc - - def test_init(self): - eq = self.assertEqual - ed = self.editor - cc = self.cc - - eq(cc.editwin, ed) - eq(cc.text, ed.text) - eq(cc.text['font'], ed.text['font']) - self.assertIsNone(cc.context) - eq(cc.info, [(0, -1, '', False)]) - eq(cc.topvisible, 1) - self.assertIsNone(self.cc.t1) - - def test_del(self): - self.cc.__del__() - - def test_del_with_timer(self): - timer = self.cc.t1 = self.text.after(10000, lambda: None) - self.cc.__del__() - with self.assertRaises(TclError) as cm: - self.root.tk.call('after', 'info', timer) - self.assertIn("doesn't exist", str(cm.exception)) - - def test_reload(self): - codecontext.CodeContext.reload() - self.assertEqual(self.cc.context_depth, 15) - - def test_toggle_code_context_event(self): - eq = self.assertEqual - cc = self.cc - toggle = cc.toggle_code_context_event - - # Make sure code context is off. - if cc.context: - toggle() - - # Toggle on. - toggle() - self.assertIsNotNone(cc.context) - eq(cc.context['font'], self.text['font']) - eq(cc.context['fg'], self.highlight_cfg['foreground']) - eq(cc.context['bg'], self.highlight_cfg['background']) - eq(cc.context.get('1.0', 'end-1c'), '') - eq(cc.editwin.label, 'Hide Code Context') - eq(self.root.tk.call('after', 'info', self.cc.t1)[1], 'timer') - - # Toggle off. - toggle() - self.assertIsNone(cc.context) - eq(cc.editwin.label, 'Show Code Context') - self.assertIsNone(self.cc.t1) - - # Scroll down and toggle back on. - line11_context = '\n'.join(x[2] for x in cc.get_context(11)[0]) - cc.text.yview(11) - toggle() - eq(cc.context.get('1.0', 'end-1c'), line11_context) - - # Toggle off and on again. - toggle() - toggle() - eq(cc.context.get('1.0', 'end-1c'), line11_context) - - def test_get_context(self): - eq = self.assertEqual - gc = self.cc.get_context - - # stopline must be greater than 0. - with self.assertRaises(AssertionError): - gc(1, stopline=0) - - eq(gc(3), ([(2, 0, 'class C1():', 'class')], 0)) - - # Don't return comment. - eq(gc(4), ([(2, 0, 'class C1():', 'class')], 0)) - - # Two indentation levels and no comment. - eq(gc(5), ([(2, 0, 'class C1():', 'class'), - (4, 4, ' def __init__(self, a, b):', 'def')], 0)) - - # Only one 'def' is returned, not both at the same indent level. - eq(gc(10), ([(2, 0, 'class C1():', 'class'), - (7, 4, ' def compare(self):', 'def'), - (8, 8, ' if a > b:', 'if')], 0)) - - # With 'elif', also show the 'if' even though it's at the same level. - eq(gc(11), ([(2, 0, 'class C1():', 'class'), - (7, 4, ' def compare(self):', 'def'), - (8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')], 0)) - - # Set stop_line to not go back to first line in source code. - # Return includes stop_line. - eq(gc(11, stopline=2), ([(2, 0, 'class C1():', 'class'), - (7, 4, ' def compare(self):', 'def'), - (8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')], 0)) - eq(gc(11, stopline=3), ([(7, 4, ' def compare(self):', 'def'), - (8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')], 4)) - eq(gc(11, stopline=8), ([(8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')], 8)) - - # Set stop_indent to test indent level to stop at. - eq(gc(11, stopindent=4), ([(7, 4, ' def compare(self):', 'def'), - (8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')], 4)) - # Check that the 'if' is included. - eq(gc(11, stopindent=8), ([(8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')], 8)) - - def test_update_code_context(self): - eq = self.assertEqual - cc = self.cc - # Ensure code context is active. - if not cc.context: - cc.toggle_code_context_event() - - # Invoke update_code_context without scrolling - nothing happens. - self.assertIsNone(cc.update_code_context()) - eq(cc.info, [(0, -1, '', False)]) - eq(cc.topvisible, 1) - - # Scroll down to line 1. - cc.text.yview(1) - cc.update_code_context() - eq(cc.info, [(0, -1, '', False)]) - eq(cc.topvisible, 2) - eq(cc.context.get('1.0', 'end-1c'), '') - - # Scroll down to line 2. - cc.text.yview(2) - cc.update_code_context() - eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1():', 'class')]) - eq(cc.topvisible, 3) - eq(cc.context.get('1.0', 'end-1c'), 'class C1():') - - # Scroll down to line 3. Since it's a comment, nothing changes. - cc.text.yview(3) - cc.update_code_context() - eq(cc.info, [(0, -1, '', False), (2, 0, 'class C1():', 'class')]) - eq(cc.topvisible, 4) - eq(cc.context.get('1.0', 'end-1c'), 'class C1():') - - # Scroll down to line 4. - cc.text.yview(4) - cc.update_code_context() - eq(cc.info, [(0, -1, '', False), - (2, 0, 'class C1():', 'class'), - (4, 4, ' def __init__(self, a, b):', 'def')]) - eq(cc.topvisible, 5) - eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n' - ' def __init__(self, a, b):') - - # Scroll down to line 11. Last 'def' is removed. - cc.text.yview(11) - cc.update_code_context() - eq(cc.info, [(0, -1, '', False), - (2, 0, 'class C1():', 'class'), - (7, 4, ' def compare(self):', 'def'), - (8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')]) - eq(cc.topvisible, 12) - eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n' - ' def compare(self):\n' - ' if a > b:\n' - ' elif a < b:') - - # No scroll. No update, even though context_depth changed. - cc.update_code_context() - cc.context_depth = 1 - eq(cc.info, [(0, -1, '', False), - (2, 0, 'class C1():', 'class'), - (7, 4, ' def compare(self):', 'def'), - (8, 8, ' if a > b:', 'if'), - (10, 8, ' elif a < b:', 'elif')]) - eq(cc.topvisible, 12) - eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n' - ' def compare(self):\n' - ' if a > b:\n' - ' elif a < b:') - - # Scroll up. - cc.text.yview(5) - cc.update_code_context() - eq(cc.info, [(0, -1, '', False), - (2, 0, 'class C1():', 'class'), - (4, 4, ' def __init__(self, a, b):', 'def')]) - eq(cc.topvisible, 6) - # context_depth is 1. - eq(cc.context.get('1.0', 'end-1c'), ' def __init__(self, a, b):') - - def test_jumptoline(self): - eq = self.assertEqual - cc = self.cc - jump = cc.jumptoline - - if not cc.context: - cc.toggle_code_context_event() - - # Empty context. - cc.text.yview('2.0') - cc.update_code_context() - eq(cc.topvisible, 2) - cc.context.mark_set('insert', '1.5') - jump() - eq(cc.topvisible, 1) - - # 4 lines of context showing. - cc.text.yview('12.0') - cc.update_code_context() - eq(cc.topvisible, 12) - cc.context.mark_set('insert', '3.0') - jump() - eq(cc.topvisible, 8) - - # More context lines than limit. - cc.context_depth = 2 - cc.text.yview('12.0') - cc.update_code_context() - eq(cc.topvisible, 12) - cc.context.mark_set('insert', '1.0') - jump() - eq(cc.topvisible, 8) - - @mock.patch.object(codecontext.CodeContext, 'update_code_context') - def test_timer_event(self, mock_update): - # Ensure code context is not active. - if self.cc.context: - self.cc.toggle_code_context_event() - self.cc.timer_event() - mock_update.assert_not_called() - - # Activate code context. - self.cc.toggle_code_context_event() - self.cc.timer_event() - mock_update.assert_called() - - def test_font(self): - eq = self.assertEqual - cc = self.cc - - orig_font = cc.text['font'] - test_font = 'TkTextFont' - self.assertNotEqual(orig_font, test_font) - - # Ensure code context is not active. - if cc.context is not None: - cc.toggle_code_context_event() - - self.font_override = test_font - # Nothing breaks or changes with inactive code context. - cc.update_font() - - # Activate code context, previous font change is immediately effective. - cc.toggle_code_context_event() - eq(cc.context['font'], test_font) - - # Call the font update, change is picked up. - self.font_override = orig_font - cc.update_font() - eq(cc.context['font'], orig_font) - - def test_highlight_colors(self): - eq = self.assertEqual - cc = self.cc - - orig_colors = dict(self.highlight_cfg) - test_colors = {'background': '#222222', 'foreground': '#ffff00'} - - def assert_colors_are_equal(colors): - eq(cc.context['background'], colors['background']) - eq(cc.context['foreground'], colors['foreground']) - - # Ensure code context is not active. - if cc.context: - cc.toggle_code_context_event() - - self.highlight_cfg = test_colors - # Nothing breaks with inactive code context. - cc.update_highlight_colors() - - # Activate code context, previous colors change is immediately effective. - cc.toggle_code_context_event() - assert_colors_are_equal(test_colors) - - # Call colors update with no change to the configured colors. - cc.update_highlight_colors() - assert_colors_are_equal(test_colors) - - # Call the colors update with code context active, change is picked up. - self.highlight_cfg = orig_colors - cc.update_highlight_colors() - assert_colors_are_equal(orig_colors) - - -class HelperFunctionText(unittest.TestCase): - - def test_get_spaces_firstword(self): - get = codecontext.get_spaces_firstword - test_lines = ( - (' first word', (' ', 'first')), - ('\tfirst word', ('\t', 'first')), - (' \u19D4\u19D2: ', (' ', '\u19D4\u19D2')), - ('no spaces', ('', 'no')), - ('', ('', '')), - ('# TEST COMMENT', ('', '')), - (' (continuation)', (' ', '')) - ) - for line, expected_output in test_lines: - self.assertEqual(get(line), expected_output) - - # Send the pattern in the call. - self.assertEqual(get(' (continuation)', - c=re.compile(r'^(\s*)([^\s]*)')), - (' ', '(continuation)')) - - def test_get_line_info(self): - eq = self.assertEqual - gli = codecontext.get_line_info - lines = code_sample.splitlines() - - # Line 1 is not a BLOCKOPENER. - eq(gli(lines[0]), (codecontext.INFINITY, '', False)) - # Line 2 is a BLOCKOPENER without an indent. - eq(gli(lines[1]), (0, 'class C1():', 'class')) - # Line 3 is not a BLOCKOPENER and does not return the indent level. - eq(gli(lines[2]), (codecontext.INFINITY, ' # Class comment.', False)) - # Line 4 is a BLOCKOPENER and is indented. - eq(gli(lines[3]), (4, ' def __init__(self, a, b):', 'def')) - # Line 8 is a different BLOCKOPENER and is indented. - eq(gli(lines[7]), (8, ' if a > b:', 'if')) - # Test tab. - eq(gli('\tif a == b:'), (1, '\tif a == b:', 'if')) - - -if __name__ == '__main__': - unittest.main(verbosity=2) |