1 """Test idlelib.ParenMatch.""" 2 # This must currently be a gui test because ParenMatch methods use 3 # several text methods not defined on idlelib.idle_test.mock_tk.Text. 4 5 import unittest 6 from test.test_support import requires 7 from Tkinter import Tk, Text 8 from idlelib.ParenMatch import ParenMatch 9 10 class Mock: # 2.7 does not have unittest.mock 11 def __init__(self, *args, **kwargs): 12 self.called = False 13 14 def __call__(self, *args, **kwargs): 15 self.called = True 16 17 def reset_mock(self, *args, **kwargs): 18 self.called = False 19 20 def after(self, *args, **kwargs): 21 pass 22 23 class DummyEditwin: 24 def __init__(self, text): 25 self.text = text 26 self.indentwidth = 8 27 self.tabwidth = 8 28 self.context_use_ps1 = True 29 30 31 class ParenMatchTest(unittest.TestCase): 32 33 @classmethod 34 def setUpClass(cls): 35 requires('gui') 36 cls.root = Tk() 37 cls.text = Text(cls.root) 38 cls.editwin = DummyEditwin(cls.text) 39 cls.editwin.text_frame = Mock() 40 41 @classmethod 42 def tearDownClass(cls): 43 del cls.text, cls.editwin 44 cls.root.destroy() 45 del cls.root 46 47 def tearDown(self): 48 self.text.delete('1.0', 'end') 49 50 def test_paren_expression(self): 51 """ 52 Test ParenMatch with 'expression' style. 53 """ 54 text = self.text 55 pm = ParenMatch(self.editwin) 56 pm.set_style('expression') 57 58 text.insert('insert', 'def foobar(a, b') 59 pm.flash_paren_event('event') 60 self.assertIn('<<parenmatch-check-restore>>', text.event_info()) 61 self.assertTupleEqual(text.tag_prevrange('paren', 'end'), 62 ('1.10', '1.15')) 63 text.insert('insert', ')') 64 pm.restore_event() 65 self.assertNotIn('<<parenmatch-check-restore>>', text.event_info()) 66 self.assertEqual(text.tag_prevrange('paren', 'end'), ()) 67 68 # paren_closed_event can only be tested as below 69 pm.paren_closed_event('event') 70 self.assertTupleEqual(text.tag_prevrange('paren', 'end'), 71 ('1.10', '1.16')) 72 73 def test_paren_default(self): 74 """ 75 Test ParenMatch with 'default' style. 76 """ 77 text = self.text 78 pm = ParenMatch(self.editwin) 79 pm.set_style('default') 80 81 text.insert('insert', 'def foobar(a, b') 82 pm.flash_paren_event('event') 83 self.assertIn('<<parenmatch-check-restore>>', text.event_info()) 84 self.assertTupleEqual(text.tag_prevrange('paren', 'end'), 85 ('1.10', '1.11')) 86 text.insert('insert', ')') 87 pm.restore_event() 88 self.assertNotIn('<<parenmatch-check-restore>>', text.event_info()) 89 self.assertEqual(text.tag_prevrange('paren', 'end'), ()) 90 91 def test_paren_corner(self): 92 """ 93 Test corner cases in flash_paren_event and paren_closed_event. 94 95 These cases force conditional expression and alternate paths. 96 """ 97 text = self.text 98 pm = ParenMatch(self.editwin) 99 100 text.insert('insert', '# this is a commen)') 101 self.assertIsNone(pm.paren_closed_event('event')) 102 103 text.insert('insert', '\ndef') 104 self.assertIsNone(pm.flash_paren_event('event')) 105 self.assertIsNone(pm.paren_closed_event('event')) 106 107 text.insert('insert', ' a, *arg)') 108 self.assertIsNone(pm.paren_closed_event('event')) 109 110 def test_handle_restore_timer(self): 111 pm = ParenMatch(self.editwin) 112 pm.restore_event = Mock() 113 pm.handle_restore_timer(0) 114 self.assertTrue(pm.restore_event.called) 115 pm.restore_event.reset_mock() 116 pm.handle_restore_timer(1) 117 self.assertFalse(pm.restore_event.called) 118 119 120 if __name__ == '__main__': 121 unittest.main(verbosity=2) 122