| 
									
										
										
										
											2018-06-15 18:20:55 -04:00
										 |  |  | "Test codecontext, coverage 100%" | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-15 18:20:55 -04:00
										 |  |  | from idlelib import codecontext | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | import unittest | 
					
						
							|  |  |  | from test.support import requires | 
					
						
							|  |  |  | from tkinter import Tk, Frame, Text, TclError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-19 19:12:52 -04:00
										 |  |  | from unittest import mock | 
					
						
							| 
									
										
										
										
											2018-06-15 18:20:55 -04:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2018-12-22 01:25:45 -05:00
										 |  |  |         self.label = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def update_menu_label(self, **kwargs): | 
					
						
							|  |  |  |         self.label = kwargs['label'] | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         # Need to pack for creation of code context text widget. | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         frame.pack(side='left', fill='both', expand=1) | 
					
						
							|  |  |  |         text.pack(side='top', fill='both', expand=1) | 
					
						
							|  |  |  |         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): | 
					
						
							| 
									
										
										
										
											2018-06-08 01:21:15 -04:00
										 |  |  |         self.text.yview(0) | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         self.cc = codecontext.CodeContext(self.editor) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         if self.cc.context: | 
					
						
							|  |  |  |             self.cc.context.destroy() | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         # Explicitly call __del__ to remove scheduled scripts. | 
					
						
							|  |  |  |         self.cc.__del__() | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         del self.cc.context, self.cc | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_init(self): | 
					
						
							|  |  |  |         eq = self.assertEqual | 
					
						
							|  |  |  |         ed = self.editor | 
					
						
							|  |  |  |         cc = self.cc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         eq(cc.editwin, ed) | 
					
						
							|  |  |  |         eq(cc.text, ed.text) | 
					
						
							|  |  |  |         eq(cc.textfont, ed.text['font']) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         self.assertIsNone(cc.context) | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         eq(cc.info, [(0, -1, '', False)]) | 
					
						
							|  |  |  |         eq(cc.topvisible, 1) | 
					
						
							|  |  |  |         eq(self.root.tk.call('after', 'info', self.cc.t1)[1], 'timer') | 
					
						
							|  |  |  |         eq(self.root.tk.call('after', 'info', self.cc.t2)[1], 'timer') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_del(self): | 
					
						
							|  |  |  |         self.cc.__del__() | 
					
						
							|  |  |  |         with self.assertRaises(TclError) as msg: | 
					
						
							|  |  |  |             self.root.tk.call('after', 'info', self.cc.t1) | 
					
						
							|  |  |  |             self.assertIn("doesn't exist", msg) | 
					
						
							|  |  |  |         with self.assertRaises(TclError) as msg: | 
					
						
							|  |  |  |             self.root.tk.call('after', 'info', self.cc.t2) | 
					
						
							|  |  |  |             self.assertIn("doesn't exist", msg) | 
					
						
							|  |  |  |         # For coverage on the except.  Have to delete because the | 
					
						
							|  |  |  |         # above Tcl error is caught by after_cancel. | 
					
						
							|  |  |  |         del self.cc.t1, self.cc.t2 | 
					
						
							|  |  |  |         self.cc.__del__() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_reload(self): | 
					
						
							|  |  |  |         codecontext.CodeContext.reload() | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         self.assertEqual(self.cc.colors, {'background': 'lightgray', | 
					
						
							|  |  |  |                                           'foreground': '#000000'}) | 
					
						
							| 
									
										
										
										
											2018-06-01 19:23:00 -04:00
										 |  |  |         self.assertEqual(self.cc.context_depth, 15) | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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. | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         if cc.context: | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |             toggle() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Toggle on. | 
					
						
							|  |  |  |         eq(toggle(), 'break') | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         self.assertIsNotNone(cc.context) | 
					
						
							|  |  |  |         eq(cc.context['font'], cc.textfont) | 
					
						
							|  |  |  |         eq(cc.context['fg'], cc.colors['foreground']) | 
					
						
							|  |  |  |         eq(cc.context['bg'], cc.colors['background']) | 
					
						
							|  |  |  |         eq(cc.context.get('1.0', 'end-1c'), '') | 
					
						
							| 
									
										
										
										
											2018-12-22 01:25:45 -05:00
										 |  |  |         eq(cc.editwin.label, 'Hide Code Context') | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Toggle off. | 
					
						
							|  |  |  |         eq(toggle(), 'break') | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         self.assertIsNone(cc.context) | 
					
						
							| 
									
										
										
										
											2018-12-22 01:25:45 -05:00
										 |  |  |         eq(cc.editwin.label, 'Show Code Context') | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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. | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         if not cc.context: | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |             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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 19:23:00 -04:00
										 |  |  |         # Scroll down to line 1. | 
					
						
							|  |  |  |         cc.text.yview(1) | 
					
						
							|  |  |  |         cc.update_code_context() | 
					
						
							|  |  |  |         eq(cc.info, [(0, -1, '', False)]) | 
					
						
							|  |  |  |         eq(cc.topvisible, 2) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context.get('1.0', 'end-1c'), '') | 
					
						
							| 
									
										
										
										
											2018-06-01 19:23:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         # 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) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context.get('1.0', 'end-1c'), 'class C1():') | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # 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) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context.get('1.0', 'end-1c'), 'class C1():') | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # 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) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n' | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |                              '    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) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n' | 
					
						
							| 
									
										
										
										
											2018-06-01 19:23:00 -04:00
										 |  |  |                              '    def compare(self):\n' | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |                              '        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) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context.get('1.0', 'end-1c'), 'class C1():\n' | 
					
						
							| 
									
										
										
										
											2018-06-01 19:23:00 -04:00
										 |  |  |                              '    def compare(self):\n' | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |                              '        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. | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context.get('1.0', 'end-1c'), '    def __init__(self, a, b):') | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 01:21:15 -04:00
										 |  |  |     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(f'{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(f'{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(f'{12}.0') | 
					
						
							|  |  |  |         cc.update_code_context() | 
					
						
							|  |  |  |         eq(cc.topvisible, 12) | 
					
						
							|  |  |  |         cc.context.mark_set('insert', '1.0') | 
					
						
							|  |  |  |         jump() | 
					
						
							|  |  |  |         eq(cc.topvisible, 8) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |     @mock.patch.object(codecontext.CodeContext, 'update_code_context') | 
					
						
							|  |  |  |     def test_timer_event(self, mock_update): | 
					
						
							|  |  |  |         # Ensure code context is not active. | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         if self.cc.context: | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |             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() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |     def test_config_timer_event(self): | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         eq = self.assertEqual | 
					
						
							|  |  |  |         cc = self.cc | 
					
						
							|  |  |  |         save_font = cc.text['font'] | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         save_colors = codecontext.CodeContext.colors | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         test_font = 'FakeFont' | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         test_colors = {'background': '#222222', 'foreground': '#ffff00'} | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Ensure code context is not active. | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         if cc.context: | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |             cc.toggle_code_context_event() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Nothing updates on inactive code context. | 
					
						
							|  |  |  |         cc.text['font'] = test_font | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         codecontext.CodeContext.colors = test_colors | 
					
						
							|  |  |  |         cc.config_timer_event() | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         eq(cc.textfont, save_font) | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         eq(cc.contextcolors, save_colors) | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         # Activate code context, but no change to font or color. | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         cc.toggle_code_context_event() | 
					
						
							|  |  |  |         cc.text['font'] = save_font | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         codecontext.CodeContext.colors = save_colors | 
					
						
							|  |  |  |         cc.config_timer_event() | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         eq(cc.textfont, save_font) | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         eq(cc.contextcolors, save_colors) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context['font'], save_font) | 
					
						
							|  |  |  |         eq(cc.context['background'], save_colors['background']) | 
					
						
							|  |  |  |         eq(cc.context['foreground'], save_colors['foreground']) | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Active code context, change font. | 
					
						
							|  |  |  |         cc.text['font'] = test_font | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         cc.config_timer_event() | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         eq(cc.textfont, test_font) | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         eq(cc.contextcolors, save_colors) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context['font'], test_font) | 
					
						
							|  |  |  |         eq(cc.context['background'], save_colors['background']) | 
					
						
							|  |  |  |         eq(cc.context['foreground'], save_colors['foreground']) | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         # Active code context, change color. | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         cc.text['font'] = save_font | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         codecontext.CodeContext.colors = test_colors | 
					
						
							|  |  |  |         cc.config_timer_event() | 
					
						
							|  |  |  |         eq(cc.textfont, save_font) | 
					
						
							|  |  |  |         eq(cc.contextcolors, test_colors) | 
					
						
							| 
									
										
										
										
											2018-06-04 11:58:44 -04:00
										 |  |  |         eq(cc.context['font'], save_font) | 
					
						
							|  |  |  |         eq(cc.context['background'], test_colors['background']) | 
					
						
							|  |  |  |         eq(cc.context['foreground'], test_colors['foreground']) | 
					
						
							| 
									
										
										
										
											2018-06-01 21:45:54 -04:00
										 |  |  |         codecontext.CodeContext.colors = save_colors | 
					
						
							|  |  |  |         cc.config_timer_event() | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class HelperFunctionText(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-23 22:18:15 -04:00
										 |  |  |     def test_get_spaces_firstword(self): | 
					
						
							|  |  |  |         get = codecontext.get_spaces_firstword | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  |         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)')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-23 22:18:15 -04:00
										 |  |  |     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')) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-19 15:34:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     unittest.main(verbosity=2) |