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