test_replace.py 8.1 KB

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