| 
									
										
										
										
											2018-06-18 04:47:59 -04:00
										 |  |  | """Test parenmatch, coverage 91%.
 | 
					
						
							| 
									
										
										
										
											2016-06-03 23:53:56 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | This must currently be a gui test because ParenMatch methods use | 
					
						
							|  |  |  | several text methods not defined on idlelib.idle_test.mock_tk.Text. | 
					
						
							| 
									
										
										
										
											2018-06-18 04:47:59 -04:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2017-06-27 21:36:23 -05:00
										 |  |  | from idlelib.parenmatch import ParenMatch | 
					
						
							| 
									
										
										
										
											2016-05-17 22:48:22 -04:00
										 |  |  | from test.support import requires | 
					
						
							|  |  |  | requires('gui') | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | from unittest.mock import Mock | 
					
						
							|  |  |  | from tkinter import Tk, Text | 
					
						
							| 
									
										
										
										
											2017-06-27 21:36:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class DummyEditwin: | 
					
						
							|  |  |  |     def __init__(self, text): | 
					
						
							|  |  |  |         self.text = text | 
					
						
							|  |  |  |         self.indentwidth = 8 | 
					
						
							|  |  |  |         self.tabwidth = 8 | 
					
						
							| 
									
										
										
										
											2019-06-02 14:56:47 -04:00
										 |  |  |         self.prompt_last_line = '>>>' # Currently not used by parenmatch. | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ParenMatchTest(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def setUpClass(cls): | 
					
						
							|  |  |  |         cls.root = Tk() | 
					
						
							| 
									
										
										
										
											2017-06-13 14:40:10 -04:00
										 |  |  |         cls.root.withdraw() | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  |         cls.text = Text(cls.root) | 
					
						
							|  |  |  |         cls.editwin = DummyEditwin(cls.text) | 
					
						
							|  |  |  |         cls.editwin.text_frame = Mock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def tearDownClass(cls): | 
					
						
							|  |  |  |         del cls.text, cls.editwin | 
					
						
							| 
									
										
										
										
											2016-06-03 23:53:56 -04:00
										 |  |  |         cls.root.update_idletasks() | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  |         cls.root.destroy() | 
					
						
							|  |  |  |         del cls.root | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         self.text.delete('1.0', 'end') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-10 23:44:54 -04:00
										 |  |  |     def get_parenmatch(self): | 
					
						
							|  |  |  |         pm = ParenMatch(self.editwin) | 
					
						
							|  |  |  |         pm.bell = lambda: None | 
					
						
							|  |  |  |         return pm | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-27 21:36:23 -05:00
										 |  |  |     def test_paren_styles(self): | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2017-06-27 21:36:23 -05:00
										 |  |  |         Test ParenMatch with each style. | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         text = self.text | 
					
						
							| 
									
										
										
										
											2016-08-10 23:44:54 -04:00
										 |  |  |         pm = self.get_parenmatch() | 
					
						
							| 
									
										
										
										
											2017-06-27 21:36:23 -05:00
										 |  |  |         for style, range1, range2 in ( | 
					
						
							|  |  |  |                 ('opener', ('1.10', '1.11'), ('1.10', '1.11')), | 
					
						
							|  |  |  |                 ('default',('1.10', '1.11'),('1.10', '1.11')), | 
					
						
							|  |  |  |                 ('parens', ('1.14', '1.15'), ('1.15', '1.16')), | 
					
						
							|  |  |  |                 ('expression', ('1.10', '1.15'), ('1.10', '1.16'))): | 
					
						
							|  |  |  |             with self.subTest(style=style): | 
					
						
							|  |  |  |                 text.delete('1.0', 'end') | 
					
						
							| 
									
										
										
										
											2017-09-16 01:42:28 -04:00
										 |  |  |                 pm.STYLE = style | 
					
						
							| 
									
										
										
										
											2017-06-27 21:36:23 -05:00
										 |  |  |                 text.insert('insert', 'def foobar(a, b') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 pm.flash_paren_event('event') | 
					
						
							|  |  |  |                 self.assertIn('<<parenmatch-check-restore>>', text.event_info()) | 
					
						
							|  |  |  |                 if style == 'parens': | 
					
						
							|  |  |  |                     self.assertTupleEqual(text.tag_nextrange('paren', '1.0'), | 
					
						
							|  |  |  |                                           ('1.10', '1.11')) | 
					
						
							|  |  |  |                 self.assertTupleEqual( | 
					
						
							|  |  |  |                         text.tag_prevrange('paren', 'end'), range1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 text.insert('insert', ')') | 
					
						
							|  |  |  |                 pm.restore_event() | 
					
						
							|  |  |  |                 self.assertNotIn('<<parenmatch-check-restore>>', | 
					
						
							|  |  |  |                                  text.event_info()) | 
					
						
							|  |  |  |                 self.assertEqual(text.tag_prevrange('paren', 'end'), ()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 pm.paren_closed_event('event') | 
					
						
							|  |  |  |                 self.assertTupleEqual( | 
					
						
							|  |  |  |                         text.tag_prevrange('paren', 'end'), range2) | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_paren_corner(self): | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         Test corner cases in flash_paren_event and paren_closed_event. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 21:41:59 -04:00
										 |  |  |         Force execution of conditional expressions and alternate paths. | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         text = self.text | 
					
						
							| 
									
										
										
										
											2016-08-10 23:44:54 -04:00
										 |  |  |         pm = self.get_parenmatch() | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-29 21:41:59 -04:00
										 |  |  |         text.insert('insert', '# Comment.)') | 
					
						
							| 
									
										
										
										
											2017-06-27 07:02:32 +03:00
										 |  |  |         pm.paren_closed_event('event') | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         text.insert('insert', '\ndef') | 
					
						
							| 
									
										
										
										
											2017-06-27 07:02:32 +03:00
										 |  |  |         pm.flash_paren_event('event') | 
					
						
							|  |  |  |         pm.paren_closed_event('event') | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         text.insert('insert', ' a, *arg)') | 
					
						
							| 
									
										
										
										
											2017-06-27 07:02:32 +03:00
										 |  |  |         pm.paren_closed_event('event') | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_handle_restore_timer(self): | 
					
						
							| 
									
										
										
										
											2016-08-10 23:44:54 -04:00
										 |  |  |         pm = self.get_parenmatch() | 
					
						
							| 
									
										
										
										
											2014-06-17 16:35:20 -04:00
										 |  |  |         pm.restore_event = Mock() | 
					
						
							|  |  |  |         pm.handle_restore_timer(0) | 
					
						
							|  |  |  |         self.assertTrue(pm.restore_event.called) | 
					
						
							|  |  |  |         pm.restore_event.reset_mock() | 
					
						
							|  |  |  |         pm.handle_restore_timer(1) | 
					
						
							|  |  |  |         self.assertFalse(pm.restore_event.called) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     unittest.main(verbosity=2) |