1 "Test undo, coverage 77%."
2 # Only test UndoDelegator so far.
3
4 from idlelib.undo import UndoDelegator
5 import unittest
6 from test.support import requires
7 requires('gui')
8
9 from unittest.mock import Mock
10 from tkinter import Text, Tk
11 from idlelib.percolator import Percolator
12
13
14 class ESC[4;38;5;81mUndoDelegatorTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
15
16 @classmethod
17 def setUpClass(cls):
18 cls.root = Tk()
19 cls.text = Text(cls.root)
20 cls.percolator = Percolator(cls.text)
21
22 @classmethod
23 def tearDownClass(cls):
24 cls.percolator.redir.close()
25 del cls.percolator, cls.text
26 cls.root.destroy()
27 del cls.root
28
29 def setUp(self):
30 self.delegator = UndoDelegator()
31 self.delegator.bell = Mock()
32 self.percolator.insertfilter(self.delegator)
33
34 def tearDown(self):
35 self.percolator.removefilter(self.delegator)
36 self.text.delete('1.0', 'end')
37 self.delegator.resetcache()
38
39 def test_undo_event(self):
40 text = self.text
41
42 text.insert('insert', 'foobar')
43 text.insert('insert', 'h')
44 text.event_generate('<<undo>>')
45 self.assertEqual(text.get('1.0', 'end'), '\n')
46
47 text.insert('insert', 'foo')
48 text.insert('insert', 'bar')
49 text.delete('1.2', '1.4')
50 text.insert('insert', 'hello')
51 text.event_generate('<<undo>>')
52 self.assertEqual(text.get('1.0', '1.4'), 'foar')
53 text.event_generate('<<undo>>')
54 self.assertEqual(text.get('1.0', '1.6'), 'foobar')
55 text.event_generate('<<undo>>')
56 self.assertEqual(text.get('1.0', '1.3'), 'foo')
57 text.event_generate('<<undo>>')
58 self.delegator.undo_event('event')
59 self.assertTrue(self.delegator.bell.called)
60
61 def test_redo_event(self):
62 text = self.text
63
64 text.insert('insert', 'foo')
65 text.insert('insert', 'bar')
66 text.delete('1.0', '1.3')
67 text.event_generate('<<undo>>')
68 text.event_generate('<<redo>>')
69 self.assertEqual(text.get('1.0', '1.3'), 'bar')
70 text.event_generate('<<redo>>')
71 self.assertTrue(self.delegator.bell.called)
72
73 def test_dump_event(self):
74 """
75 Dump_event cannot be tested directly without changing
76 environment variables. So, test statements in dump_event
77 indirectly
78 """
79 text = self.text
80 d = self.delegator
81
82 text.insert('insert', 'foo')
83 text.insert('insert', 'bar')
84 text.delete('1.2', '1.4')
85 self.assertTupleEqual((d.pointer, d.can_merge), (3, True))
86 text.event_generate('<<undo>>')
87 self.assertTupleEqual((d.pointer, d.can_merge), (2, False))
88
89 def test_get_set_saved(self):
90 # test the getter method get_saved
91 # test the setter method set_saved
92 # indirectly test check_saved
93 d = self.delegator
94
95 self.assertTrue(d.get_saved())
96 self.text.insert('insert', 'a')
97 self.assertFalse(d.get_saved())
98 d.saved_change_hook = Mock()
99
100 d.set_saved(True)
101 self.assertEqual(d.pointer, d.saved)
102 self.assertTrue(d.saved_change_hook.called)
103
104 d.set_saved(False)
105 self.assertEqual(d.saved, -1)
106 self.assertTrue(d.saved_change_hook.called)
107
108 def test_undo_start_stop(self):
109 # test the undo_block_start and undo_block_stop methods
110 text = self.text
111
112 text.insert('insert', 'foo')
113 self.delegator.undo_block_start()
114 text.insert('insert', 'bar')
115 text.insert('insert', 'bar')
116 self.delegator.undo_block_stop()
117 self.assertEqual(text.get('1.0', '1.3'), 'foo')
118
119 # test another code path
120 self.delegator.undo_block_start()
121 text.insert('insert', 'bar')
122 self.delegator.undo_block_stop()
123 self.assertEqual(text.get('1.0', '1.3'), 'foo')
124
125 def test_addcmd(self):
126 text = self.text
127 # when number of undo operations exceeds max_undo
128 self.delegator.max_undo = max_undo = 10
129 for i in range(max_undo + 10):
130 text.insert('insert', 'foo')
131 self.assertLessEqual(len(self.delegator.undolist), max_undo)
132
133
134 if __name__ == '__main__':
135 unittest.main(verbosity=2, exit=False)