1"Test replace, coverage 78%." 2 3from idlelib.replace import ReplaceDialog 4import unittest 5from test.support import requires 6requires('gui') 7from tkinter import Tk, Text 8 9from unittest.mock import Mock 10from idlelib.idle_test.mock_tk import Mbox 11import idlelib.searchengine as se 12 13orig_mbox = se.messagebox 14showerror = Mbox.showerror 15 16 17class ReplaceDialogTest(unittest.TestCase): 18 19 @classmethod 20 def setUpClass(cls): 21 cls.root = Tk() 22 cls.root.withdraw() 23 se.messagebox = Mbox 24 cls.engine = se.SearchEngine(cls.root) 25 cls.dialog = ReplaceDialog(cls.root, cls.engine) 26 cls.dialog.bell = lambda: None 27 cls.dialog.ok = Mock() 28 cls.text = Text(cls.root) 29 cls.text.undo_block_start = Mock() 30 cls.text.undo_block_stop = Mock() 31 cls.dialog.text = cls.text 32 33 @classmethod 34 def tearDownClass(cls): 35 se.messagebox = orig_mbox 36 del cls.text, cls.dialog, cls.engine 37 cls.root.destroy() 38 del cls.root 39 40 def setUp(self): 41 self.text.insert('insert', 'This is a sample sTring') 42 43 def tearDown(self): 44 self.engine.patvar.set('') 45 self.dialog.replvar.set('') 46 self.engine.wordvar.set(False) 47 self.engine.casevar.set(False) 48 self.engine.revar.set(False) 49 self.engine.wrapvar.set(True) 50 self.engine.backvar.set(False) 51 showerror.title = '' 52 showerror.message = '' 53 self.text.delete('1.0', 'end') 54 55 def test_replace_simple(self): 56 # Test replace function with all options at default setting. 57 # Wrap around - True 58 # Regular Expression - False 59 # Match case - False 60 # Match word - False 61 # Direction - Forwards 62 text = self.text 63 equal = self.assertEqual 64 pv = self.engine.patvar 65 rv = self.dialog.replvar 66 replace = self.dialog.replace_it 67 68 # test accessor method 69 self.engine.setpat('asdf') 70 equal(self.engine.getpat(), pv.get()) 71 72 # text found and replaced 73 pv.set('a') 74 rv.set('asdf') 75 replace() 76 equal(text.get('1.8', '1.12'), 'asdf') 77 78 # don't "match word" case 79 text.mark_set('insert', '1.0') 80 pv.set('is') 81 rv.set('hello') 82 replace() 83 equal(text.get('1.2', '1.7'), 'hello') 84 85 # don't "match case" case 86 pv.set('string') 87 rv.set('world') 88 replace() 89 equal(text.get('1.23', '1.28'), 'world') 90 91 # without "regular expression" case 92 text.mark_set('insert', 'end') 93 text.insert('insert', '\nline42:') 94 before_text = text.get('1.0', 'end') 95 pv.set(r'[a-z][\d]+') 96 replace() 97 after_text = text.get('1.0', 'end') 98 equal(before_text, after_text) 99 100 # test with wrap around selected and complete a cycle 101 text.mark_set('insert', '1.9') 102 pv.set('i') 103 rv.set('j') 104 replace() 105 equal(text.get('1.8'), 'i') 106 equal(text.get('2.1'), 'j') 107 replace() 108 equal(text.get('2.1'), 'j') 109 equal(text.get('1.8'), 'j') 110 before_text = text.get('1.0', 'end') 111 replace() 112 after_text = text.get('1.0', 'end') 113 equal(before_text, after_text) 114 115 # text not found 116 before_text = text.get('1.0', 'end') 117 pv.set('foobar') 118 replace() 119 after_text = text.get('1.0', 'end') 120 equal(before_text, after_text) 121 122 # test access method 123 self.dialog.find_it(0) 124 125 def test_replace_wrap_around(self): 126 text = self.text 127 equal = self.assertEqual 128 pv = self.engine.patvar 129 rv = self.dialog.replvar 130 replace = self.dialog.replace_it 131 self.engine.wrapvar.set(False) 132 133 # replace candidate found both after and before 'insert' 134 text.mark_set('insert', '1.4') 135 pv.set('i') 136 rv.set('j') 137 replace() 138 equal(text.get('1.2'), 'i') 139 equal(text.get('1.5'), 'j') 140 replace() 141 equal(text.get('1.2'), 'i') 142 equal(text.get('1.20'), 'j') 143 replace() 144 equal(text.get('1.2'), 'i') 145 146 # replace candidate found only before 'insert' 147 text.mark_set('insert', '1.8') 148 pv.set('is') 149 before_text = text.get('1.0', 'end') 150 replace() 151 after_text = text.get('1.0', 'end') 152 equal(before_text, after_text) 153 154 def test_replace_whole_word(self): 155 text = self.text 156 equal = self.assertEqual 157 pv = self.engine.patvar 158 rv = self.dialog.replvar 159 replace = self.dialog.replace_it 160 self.engine.wordvar.set(True) 161 162 pv.set('is') 163 rv.set('hello') 164 replace() 165 equal(text.get('1.0', '1.4'), 'This') 166 equal(text.get('1.5', '1.10'), 'hello') 167 168 def test_replace_match_case(self): 169 equal = self.assertEqual 170 text = self.text 171 pv = self.engine.patvar 172 rv = self.dialog.replvar 173 replace = self.dialog.replace_it 174 self.engine.casevar.set(True) 175 176 before_text = self.text.get('1.0', 'end') 177 pv.set('this') 178 rv.set('that') 179 replace() 180 after_text = self.text.get('1.0', 'end') 181 equal(before_text, after_text) 182 183 pv.set('This') 184 replace() 185 equal(text.get('1.0', '1.4'), 'that') 186 187 def test_replace_regex(self): 188 equal = self.assertEqual 189 text = self.text 190 pv = self.engine.patvar 191 rv = self.dialog.replvar 192 replace = self.dialog.replace_it 193 self.engine.revar.set(True) 194 195 before_text = text.get('1.0', 'end') 196 pv.set(r'[a-z][\d]+') 197 rv.set('hello') 198 replace() 199 after_text = text.get('1.0', 'end') 200 equal(before_text, after_text) 201 202 text.insert('insert', '\nline42') 203 replace() 204 equal(text.get('2.0', '2.8'), 'linhello') 205 206 pv.set('') 207 replace() 208 self.assertIn('error', showerror.title) 209 self.assertIn('Empty', showerror.message) 210 211 pv.set(r'[\d') 212 replace() 213 self.assertIn('error', showerror.title) 214 self.assertIn('Pattern', showerror.message) 215 216 showerror.title = '' 217 showerror.message = '' 218 pv.set('[a]') 219 rv.set('test\\') 220 replace() 221 self.assertIn('error', showerror.title) 222 self.assertIn('Invalid Replace Expression', showerror.message) 223 224 # test access method 225 self.engine.setcookedpat("?") 226 equal(pv.get(), "\\?") 227 228 def test_replace_backwards(self): 229 equal = self.assertEqual 230 text = self.text 231 pv = self.engine.patvar 232 rv = self.dialog.replvar 233 replace = self.dialog.replace_it 234 self.engine.backvar.set(True) 235 236 text.insert('insert', '\nis as ') 237 238 pv.set('is') 239 rv.set('was') 240 replace() 241 equal(text.get('1.2', '1.4'), 'is') 242 equal(text.get('2.0', '2.3'), 'was') 243 replace() 244 equal(text.get('1.5', '1.8'), 'was') 245 replace() 246 equal(text.get('1.2', '1.5'), 'was') 247 248 def test_replace_all(self): 249 text = self.text 250 pv = self.engine.patvar 251 rv = self.dialog.replvar 252 replace_all = self.dialog.replace_all 253 254 text.insert('insert', '\n') 255 text.insert('insert', text.get('1.0', 'end')*100) 256 pv.set('is') 257 rv.set('was') 258 replace_all() 259 self.assertNotIn('is', text.get('1.0', 'end')) 260 261 self.engine.revar.set(True) 262 pv.set('') 263 replace_all() 264 self.assertIn('error', showerror.title) 265 self.assertIn('Empty', showerror.message) 266 267 pv.set('[s][T]') 268 rv.set('\\') 269 replace_all() 270 271 self.engine.revar.set(False) 272 pv.set('text which is not present') 273 rv.set('foobar') 274 replace_all() 275 276 def test_default_command(self): 277 text = self.text 278 pv = self.engine.patvar 279 rv = self.dialog.replvar 280 replace_find = self.dialog.default_command 281 equal = self.assertEqual 282 283 pv.set('This') 284 rv.set('was') 285 replace_find() 286 equal(text.get('sel.first', 'sel.last'), 'was') 287 288 self.engine.revar.set(True) 289 pv.set('') 290 replace_find() 291 292 293if __name__ == '__main__': 294 unittest.main(verbosity=2) 295