1"Test undo, coverage 77%." 2# Only test UndoDelegator so far. 3 4from idlelib.undo import UndoDelegator 5import unittest 6from test.support import requires 7requires('gui') 8 9from unittest.mock import Mock 10from tkinter import Text, Tk 11from idlelib.percolator import Percolator 12 13 14class UndoDelegatorTest(unittest.TestCase): 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 134if __name__ == '__main__': 135 unittest.main(verbosity=2, exit=False) 136