1" Test history, coverage 100%." 2 3from idlelib.history import History 4import unittest 5from test.support import requires 6 7import tkinter as tk 8from tkinter import Text as tkText 9from idlelib.idle_test.mock_tk import Text as mkText 10from idlelib.config import idleConf 11 12line1 = 'a = 7' 13line2 = 'b = a' 14 15 16class StoreTest(unittest.TestCase): 17 '''Tests History.__init__ and History.store with mock Text''' 18 19 @classmethod 20 def setUpClass(cls): 21 cls.text = mkText() 22 cls.history = History(cls.text) 23 24 def tearDown(self): 25 self.text.delete('1.0', 'end') 26 self.history.history = [] 27 28 def test_init(self): 29 self.assertIs(self.history.text, self.text) 30 self.assertEqual(self.history.history, []) 31 self.assertIsNone(self.history.prefix) 32 self.assertIsNone(self.history.pointer) 33 self.assertEqual(self.history.cyclic, 34 idleConf.GetOption("main", "History", "cyclic", 1, "bool")) 35 36 def test_store_short(self): 37 self.history.store('a') 38 self.assertEqual(self.history.history, []) 39 self.history.store(' a ') 40 self.assertEqual(self.history.history, []) 41 42 def test_store_dup(self): 43 self.history.store(line1) 44 self.assertEqual(self.history.history, [line1]) 45 self.history.store(line2) 46 self.assertEqual(self.history.history, [line1, line2]) 47 self.history.store(line1) 48 self.assertEqual(self.history.history, [line2, line1]) 49 50 def test_store_reset(self): 51 self.history.prefix = line1 52 self.history.pointer = 0 53 self.history.store(line2) 54 self.assertIsNone(self.history.prefix) 55 self.assertIsNone(self.history.pointer) 56 57 58class TextWrapper: 59 def __init__(self, master): 60 self.text = tkText(master=master) 61 self._bell = False 62 def __getattr__(self, name): 63 return getattr(self.text, name) 64 def bell(self): 65 self._bell = True 66 67 68class FetchTest(unittest.TestCase): 69 '''Test History.fetch with wrapped tk.Text. 70 ''' 71 @classmethod 72 def setUpClass(cls): 73 requires('gui') 74 cls.root = tk.Tk() 75 cls.root.withdraw() 76 77 def setUp(self): 78 self.text = text = TextWrapper(self.root) 79 text.insert('1.0', ">>> ") 80 text.mark_set('iomark', '1.4') 81 text.mark_gravity('iomark', 'left') 82 self.history = History(text) 83 self.history.history = [line1, line2] 84 85 @classmethod 86 def tearDownClass(cls): 87 cls.root.destroy() 88 del cls.root 89 90 def fetch_test(self, reverse, line, prefix, index, *, bell=False): 91 # Perform one fetch as invoked by Alt-N or Alt-P 92 # Test the result. The line test is the most important. 93 # The last two are diagnostic of fetch internals. 94 History = self.history 95 History.fetch(reverse) 96 97 Equal = self.assertEqual 98 Equal(self.text.get('iomark', 'end-1c'), line) 99 Equal(self.text._bell, bell) 100 if bell: 101 self.text._bell = False 102 Equal(History.prefix, prefix) 103 Equal(History.pointer, index) 104 Equal(self.text.compare("insert", '==', "end-1c"), 1) 105 106 def test_fetch_prev_cyclic(self): 107 prefix = '' 108 test = self.fetch_test 109 test(True, line2, prefix, 1) 110 test(True, line1, prefix, 0) 111 test(True, prefix, None, None, bell=True) 112 113 def test_fetch_next_cyclic(self): 114 prefix = '' 115 test = self.fetch_test 116 test(False, line1, prefix, 0) 117 test(False, line2, prefix, 1) 118 test(False, prefix, None, None, bell=True) 119 120 # Prefix 'a' tests skip line2, which starts with 'b' 121 def test_fetch_prev_prefix(self): 122 prefix = 'a' 123 self.text.insert('iomark', prefix) 124 self.fetch_test(True, line1, prefix, 0) 125 self.fetch_test(True, prefix, None, None, bell=True) 126 127 def test_fetch_next_prefix(self): 128 prefix = 'a' 129 self.text.insert('iomark', prefix) 130 self.fetch_test(False, line1, prefix, 0) 131 self.fetch_test(False, prefix, None, None, bell=True) 132 133 def test_fetch_prev_noncyclic(self): 134 prefix = '' 135 self.history.cyclic = False 136 test = self.fetch_test 137 test(True, line2, prefix, 1) 138 test(True, line1, prefix, 0) 139 test(True, line1, prefix, 0, bell=True) 140 141 def test_fetch_next_noncyclic(self): 142 prefix = '' 143 self.history.cyclic = False 144 test = self.fetch_test 145 test(False, prefix, None, None, bell=True) 146 test(True, line2, prefix, 1) 147 test(False, prefix, None, None, bell=True) 148 test(False, prefix, None, None, bell=True) 149 150 def test_fetch_cursor_move(self): 151 # Move cursor after fetch 152 self.history.fetch(reverse=True) # initialization 153 self.text.mark_set('insert', 'iomark') 154 self.fetch_test(True, line2, None, None, bell=True) 155 156 def test_fetch_edit(self): 157 # Edit after fetch 158 self.history.fetch(reverse=True) # initialization 159 self.text.delete('iomark', 'insert', ) 160 self.text.insert('iomark', 'a =') 161 self.fetch_test(True, line1, 'a =', 0) # prefix is reset 162 163 def test_history_prev_next(self): 164 # Minimally test functions bound to events 165 self.history.history_prev('dummy event') 166 self.assertEqual(self.history.pointer, 1) 167 self.history.history_next('dummy event') 168 self.assertEqual(self.history.pointer, None) 169 170 171if __name__ == '__main__': 172 unittest.main(verbosity=2, exit=2) 173