Coverage for core\test_leoUndo.py: 100%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2#@+leo-ver=5-thin
3#@+node:ekr.20210906141410.1: * @file ../unittests/core/test_leoUndo.py
4#@@first
5"""Tests of leoUndo.py"""
7import textwrap
8from leo.core import leoGlobals as g
9from leo.core.leoTest2 import LeoUnitTest
10assert g
12# pylint: disable=no-member
14#@+others
15#@+node:ekr.20210906141410.2: ** class TestUndo (LeoUnitTest)
16class TestUndo(LeoUnitTest):
17 #@+others
18 #@+node:ekr.20210906141410.9: *3* TestUndo.runTest (Test)
19 def runTest(self, before, after, i, j, func):
20 """TestUndo.runTest."""
21 c, p, w = self.c, self.c.p, self.c.frame.body.wrapper
22 # Restore section references.
23 before = before.replace('> >', '>>').replace('< <', '<<')
24 after = after.replace('> >', '>>').replace('< <', '<<')
25 # Check indices.
26 self.assertTrue(0 <= i <= len(before), msg=f"i: {i} len(before): {len(before)}")
27 self.assertTrue(0 <= j <= len(before), msg=f"j: {j} len(before): {len(before)}")
28 # Set the text and selection range.
29 p.b = before
30 self.assertEqual(p.b, w.getAllText())
31 w.setSelectionRange(i, j, insert=i)
32 # Test.
33 self.assertNotEqual(before, after)
34 func()
35 result = p.b
36 self.assertEqual(result, after, msg='before undo1')
37 c.undoer.undo()
38 result = w.getAllText()
39 self.assertEqual(result, before, msg='after undo1')
40 c.undoer.redo()
41 result = w.getAllText()
42 self.assertEqual(result, after, msg='after redo1')
43 c.undoer.undo()
44 result = w.getAllText()
45 self.assertEqual(result, before, msg='after undo2')
46 #@+node:ekr.20210906172626.2: *3* TestUndo.test_addComments
47 def test_addComments(self):
48 c = self.c
49 before = textwrap.dedent("""\
50 @language python
52 def addCommentTest():
54 if 1:
55 a = 2
56 b = 3
58 pass
59 """)
60 after = textwrap.dedent("""\
61 @language python
63 def addCommentTest():
65 # if 1:
66 # a = 2
67 # b = 3
69 pass
70 """)
71 i = before.find('if 1')
72 j = before.find('b = 3')
73 func = c.addComments
74 self.runTest(before, after, i, j, func)
75 #@+node:ekr.20210906172626.3: *3* TestUndo.test_convertAllBlanks
76 def test_convertAllBlanks(self):
77 c = self.c
78 before = textwrap.dedent("""\
79 @tabwidth -4
81 line 1
82 line 2
83 line 3
84 line4
85 """)
86 after = textwrap.dedent("""\
87 @tabwidth -4
89 line 1
90 line 2
91 line 3
92 line4
93 """)
94 i, j = 13, len(before)
95 func = c.convertAllBlanks
96 self.runTest(before, after, i, j, func)
97 #@+node:ekr.20210906172626.4: *3* TestUndo.test_convertAllTabs
98 def test_convertAllTabs(self):
99 c = self.c
100 before = textwrap.dedent("""\
101 @tabwidth -4
103 line 1
104 line 2
105 line 3
106 line4
107 """)
108 after = textwrap.dedent("""\
109 @tabwidth -4
111 line 1
112 line 2
113 line 3
114 line4
115 """)
116 i, j = 13, 45
117 func = c.convertAllTabs
118 self.runTest(before, after, i, j, func)
119 #@+node:ekr.20210906172626.5: *3* TestUndo.test_convertBlanks
120 def test_convertBlanks(self):
121 c = self.c
122 before = textwrap.dedent("""\
123 @tabwidth -4
125 line 1
126 line 2
127 line 3
128 line4
129 """)
130 after = textwrap.dedent("""\
131 @tabwidth -4
133 line 1
134 line 2
135 line 3
136 line4
137 """)
138 i, j = 13, 51
139 func = c.convertBlanks
140 self.runTest(before, after, i, j, func)
141 #@+node:ekr.20210906172626.6: *3* TestUndo.test_convertTabs
142 def test_convertTabs(self):
143 c = self.c
144 before = textwrap.dedent("""\
145 @tabwidth -4
147 line 1
148 line 2
149 line 3
150 line4
151 """)
152 after = textwrap.dedent("""\
153 @tabwidth -4
155 line 1
156 line 2
157 line 3
158 line4
159 """)
160 i, j = 13, 45
161 func = c.convertTabs
162 self.runTest(before, after, i, j, func)
163 #@+node:ekr.20210906172626.7: *3* TestUndo.test_dedentBody
164 def test_dedentBody(self):
165 c = self.c
166 before = textwrap.dedent("""\
167 line 1
168 line 2
169 line 3
170 line 4
171 """)
172 after = textwrap.dedent("""\
173 line 1
174 line 2
175 line 3
176 line 4
177 """)
178 i = before.find('line 2')
179 j = before.find('3')
180 func = c.dedentBody
181 self.runTest(before, after, i, j, func)
182 #@+node:ekr.20210906172626.8: *3* TestUndo.test_deleteComments
183 def test_deleteComments(self):
184 c = self.c
185 before = textwrap.dedent("""\
186 @language python
188 def deleteCommentTest():
190 # if 1:
191 # a = 2
192 # b = 3
194 pass
195 """)
196 after = textwrap.dedent("""\
197 @language python
199 def deleteCommentTest():
201 if 1:
202 a = 2
203 b = 3
205 pass
206 """)
207 i = before.find('if 1')
208 j = before.find('b = 3')
209 func = c.deleteComments
210 self.runTest(before, after, i, j, func)
211 #@+node:ekr.20210906172626.9: *3* TestUndo.test_deleteComments 2
212 def test_deleteComments_2(self):
213 c = self.c
214 before = textwrap.dedent("""\
215 @language python
217 def deleteCommentTest():
219 # if 1:
220 # a = 2
221 # b = 3
223 # if 1:
224 # a = 2
225 # b = 3
227 pass
228 """)
229 after = textwrap.dedent("""\
230 @language python
232 def deleteCommentTest():
234 if 1:
235 a = 2
236 b = 3
238 if 1:
239 a = 2
240 b = 3
242 pass
243 """)
244 i = before.find('if 1')
245 j = before.find('# b = 3')
246 func = c.deleteComments
247 self.runTest(before, after, i, j, func)
248 #@+node:ekr.20210906172626.16: *3* TestUndo.test_edit_headline
249 def test_edit_headline(self):
250 # Brian Theado.
251 c, p = self.c, self.c.p
252 node1 = p.insertAsLastChild()
253 node2 = node1.insertAfter()
254 node3 = node2.insertAfter()
255 node1.h = 'node 1'
256 node2.h = 'node 2'
257 node3.h = 'node 3'
258 self.assertEqual([p.h for p in p.subtree()], ['node 1', 'node 2', 'node 3'])
259 # Select 'node 1' and modify the headline as if a user did it
260 c.undoer.clearUndoState()
261 node1 = p.copy().moveToFirstChild()
262 c.selectPosition(node1)
263 c.editHeadline()
264 w = c.frame.tree.edit_widget(node1)
265 w.insert('1.0', 'changed - ')
266 c.endEditing()
267 self.assertEqual([p.h for p in p.subtree()], ['changed - node 1', 'node 2', 'node 3'])
268 # Move the selection and undo the headline change
269 c.selectPosition(node1.copy().moveToNext())
270 c.undoer.undo()
271 # The undo should restore the 'node 1' headline string
272 self.assertEqual([p.h for p in p.subtree()], ['node 1', 'node 2', 'node 3'])
273 # The undo should select the edited headline.
274 self.assertEqual(c.p, node1)
275 #@+node:ekr.20210906172626.10: *3* TestUndo.test_extract_test
276 def test_extract_test(self):
277 c = self.c
278 before = textwrap.dedent("""\
279 before
280 < < section > >
281 sec line 1
282 sec line 2 indented
283 sec line 3
284 after
285 """)
286 after = textwrap.dedent("""\
287 before
288 < < section > >
289 after
290 """)
291 i = before.find('< <')
292 j = before.find('line 3')
293 func = c.extract
294 self.runTest(before, after, i, j, func)
295 #@+node:ekr.20210906172626.14: *3* TestUndo.test_line_to_headline
296 def test_line_to_headline(self):
297 c = self.c
298 before = textwrap.dedent("""\
299 before
300 headline
301 after
302 """)
303 after = textwrap.dedent("""\
304 before
305 after
306 """)
307 i, j = 10, 10
308 func = c.line_to_headline
309 self.runTest(before, after, i, j, func)
310 #@+node:ekr.20210906172626.15: *3* TestUndo.test_restore_marked_bits
311 def test_restore_marked_bits(self):
312 c, p = self.c, self.c.p
313 # Test of #1694.
314 u, w = c.undoer, c.frame.body.wrapper
315 oldText = p.b
316 newText = p.b + '\n#changed'
317 for marked in (True, False):
318 c.undoer.clearUndoState() # Required.
319 if marked:
320 p.setMarked()
321 else:
322 p.clearMarked()
323 oldMarked = p.isMarked()
324 w.setAllText(newText) # For the new assert in w.updateAfterTyping.
325 u.setUndoTypingParams(p,
326 undo_type='typing',
327 oldText=oldText,
328 newText=newText,
329 )
330 u.undo()
331 self.assertEqual(p.b, oldText)
332 self.assertEqual(p.isMarked(), oldMarked)
333 u.redo()
334 self.assertEqual(p.b, newText)
335 self.assertEqual(p.isMarked(), oldMarked)
336 #@+node:ekr.20210906172626.17: *3* TestUndo.test_undo_group
337 def test_undo_group(self):
338 # Test an off-by-one error in c.undoer.bead.
339 # The buggy redoGroup code worked if the undo group was the first item on the undo stack.
340 c, p = self.c, self.c.p
341 original = p.insertAfter()
342 original_s = original.b = textwrap.dedent("""\
343 @tabwidth -4
345 line 1
346 line 2
347 line 3
348 line4
349 """)
350 c.undoer.clearUndoState()
351 c.selectPosition(original)
352 c.copyOutline() # Add state to the undo stack!
353 c.pasteOutline()
354 c.convertAllBlanks() # Uses undoGroup.
355 c.undoer.undo()
356 self.assertEqual(original.b, original_s)
357 c.pasteOutline()
358 c.convertAllBlanks()
359 c.pasteOutline()
360 c.convertAllBlanks()
361 c.undoer.undo()
362 c.undoer.redo()
363 self.assertEqual(original.b, original_s)
364 #@-others
365#@-others
366#@-leo