Coverage for idle_test/test_parenmatch.py: 4%

71 statements  

« prev     ^ index     » next       coverage.py v7.2.5, created at 2023-05-11 13:22 -0700

1"""Test parenmatch, coverage 91%. 

2 

3This must currently be a gui test because ParenMatch methods use 

4several text methods not defined on idlelib.idle_test.mock_tk.Text. 

5""" 

6from idlelib.parenmatch import ParenMatch 

7from test.support import requires 

8requires('gui') 

9 

10import unittest 

11from unittest.mock import Mock 

12from tkinter import Tk, Text 

13 

14 

15class DummyEditwin: 

16 def __init__(self, text): 

17 self.text = text 

18 self.indentwidth = 8 

19 self.tabwidth = 8 

20 self.prompt_last_line = '>>>' # Currently not used by parenmatch. 

21 

22 

23class ParenMatchTest(unittest.TestCase): 

24 

25 @classmethod 

26 def setUpClass(cls): 

27 cls.root = Tk() 

28 cls.root.withdraw() 

29 cls.text = Text(cls.root) 

30 cls.editwin = DummyEditwin(cls.text) 

31 cls.editwin.text_frame = Mock() 

32 

33 @classmethod 

34 def tearDownClass(cls): 

35 del cls.text, cls.editwin 

36 cls.root.update_idletasks() 

37 cls.root.destroy() 

38 del cls.root 

39 

40 def tearDown(self): 

41 self.text.delete('1.0', 'end') 

42 

43 def get_parenmatch(self): 

44 pm = ParenMatch(self.editwin) 

45 pm.bell = lambda: None 

46 return pm 

47 

48 def test_paren_styles(self): 

49 """ 

50 Test ParenMatch with each style. 

51 """ 

52 text = self.text 

53 pm = self.get_parenmatch() 

54 for style, range1, range2 in ( 

55 ('opener', ('1.10', '1.11'), ('1.10', '1.11')), 

56 ('default',('1.10', '1.11'),('1.10', '1.11')), 

57 ('parens', ('1.14', '1.15'), ('1.15', '1.16')), 

58 ('expression', ('1.10', '1.15'), ('1.10', '1.16'))): 

59 with self.subTest(style=style): 

60 text.delete('1.0', 'end') 

61 pm.STYLE = style 

62 text.insert('insert', 'def foobar(a, b') 

63 

64 pm.flash_paren_event('event') 

65 self.assertIn('<<parenmatch-check-restore>>', text.event_info()) 

66 if style == 'parens': 

67 self.assertTupleEqual(text.tag_nextrange('paren', '1.0'), 

68 ('1.10', '1.11')) 

69 self.assertTupleEqual( 

70 text.tag_prevrange('paren', 'end'), range1) 

71 

72 text.insert('insert', ')') 

73 pm.restore_event() 

74 self.assertNotIn('<<parenmatch-check-restore>>', 

75 text.event_info()) 

76 self.assertEqual(text.tag_prevrange('paren', 'end'), ()) 

77 

78 pm.paren_closed_event('event') 

79 self.assertTupleEqual( 

80 text.tag_prevrange('paren', 'end'), range2) 

81 

82 def test_paren_corner(self): 

83 """ 

84 Test corner cases in flash_paren_event and paren_closed_event. 

85 

86 Force execution of conditional expressions and alternate paths. 

87 """ 

88 text = self.text 

89 pm = self.get_parenmatch() 

90 

91 text.insert('insert', '# Comment.)') 

92 pm.paren_closed_event('event') 

93 

94 text.insert('insert', '\ndef') 

95 pm.flash_paren_event('event') 

96 pm.paren_closed_event('event') 

97 

98 text.insert('insert', ' a, *arg)') 

99 pm.paren_closed_event('event') 

100 

101 def test_handle_restore_timer(self): 

102 pm = self.get_parenmatch() 

103 pm.restore_event = Mock() 

104 pm.handle_restore_timer(0) 

105 self.assertTrue(pm.restore_event.called) 

106 pm.restore_event.reset_mock() 

107 pm.handle_restore_timer(1) 

108 self.assertFalse(pm.restore_event.called) 

109 

110 

111if __name__ == '__main__': 

112 unittest.main(verbosity=2)