Hide keyboard shortcuts

Hot-keys on this page

r m x p   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""" 

6 

7import textwrap 

8from leo.core import leoGlobals as g 

9from leo.core.leoTest2 import LeoUnitTest 

10assert g 

11 

12# pylint: disable=no-member 

13 

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 

51 

52 def addCommentTest(): 

53 

54 if 1: 

55 a = 2 

56 b = 3 

57 

58 pass 

59 """) 

60 after = textwrap.dedent("""\ 

61 @language python 

62 

63 def addCommentTest(): 

64 

65 # if 1: 

66 # a = 2 

67 # b = 3 

68 

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 

80 

81 line 1 

82 line 2 

83 line 3 

84 line4 

85 """) 

86 after = textwrap.dedent("""\ 

87 @tabwidth -4 

88 

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 

102 

103 line 1 

104 line 2 

105 line 3 

106 line4 

107 """) 

108 after = textwrap.dedent("""\ 

109 @tabwidth -4 

110 

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 

124 

125 line 1 

126 line 2 

127 line 3 

128 line4 

129 """) 

130 after = textwrap.dedent("""\ 

131 @tabwidth -4 

132 

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 

146 

147 line 1 

148 line 2 

149 line 3 

150 line4 

151 """) 

152 after = textwrap.dedent("""\ 

153 @tabwidth -4 

154 

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 

187 

188 def deleteCommentTest(): 

189 

190 # if 1: 

191 # a = 2 

192 # b = 3 

193 

194 pass 

195 """) 

196 after = textwrap.dedent("""\ 

197 @language python 

198 

199 def deleteCommentTest(): 

200 

201 if 1: 

202 a = 2 

203 b = 3 

204 

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 

216 

217 def deleteCommentTest(): 

218 

219 # if 1: 

220 # a = 2 

221 # b = 3 

222 

223 # if 1: 

224 # a = 2 

225 # b = 3 

226 

227 pass 

228 """) 

229 after = textwrap.dedent("""\ 

230 @language python 

231 

232 def deleteCommentTest(): 

233 

234 if 1: 

235 a = 2 

236 b = 3 

237 

238 if 1: 

239 a = 2 

240 b = 3 

241 

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 

344 

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