xref: /vim-8.2.3635/src/testdir/test_undo.vim (revision d09a206e)
1" Tests for the undo tree.
2" Since this script is sourced we need to explicitly break changes up in
3" undo-able pieces.  Do that by setting 'undolevels'.
4" Also tests :earlier and :later.
5
6func Test_undotree()
7  exe "normal Aabc\<Esc>"
8  set ul=100
9  exe "normal Adef\<Esc>"
10  set ul=100
11  undo
12  let d = undotree()
13  call assert_true(d.seq_last > 0)
14  call assert_true(d.seq_cur > 0)
15  call assert_true(d.seq_cur < d.seq_last)
16  call assert_true(len(d.entries) > 0)
17  " TODO: check more members of d
18
19  w! Xtest
20  call assert_equal(d.save_last + 1, undotree().save_last)
21  call delete('Xtest')
22  bwipe Xtest
23endfunc
24
25func FillBuffer()
26  for i in range(1,13)
27    put=i
28    " Set 'undolevels' to split undo.
29    exe "setg ul=" . &g:ul
30  endfor
31endfunc
32
33func Test_global_local_undolevels()
34  new one
35  set undolevels=5
36  call FillBuffer()
37  " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
38  earlier 10
39  call assert_equal(5, &g:undolevels)
40  call assert_equal(-123456, &l:undolevels)
41  call assert_equal('7', getline('$'))
42
43  new two
44  setlocal undolevels=2
45  call FillBuffer()
46  " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
47  earlier 10
48  call assert_equal(5, &g:undolevels)
49  call assert_equal(2, &l:undolevels)
50  call assert_equal('10', getline('$'))
51
52  setlocal ul=10
53  call assert_equal(5, &g:undolevels)
54  call assert_equal(10, &l:undolevels)
55
56  " Setting local value in "two" must not change local value in "one"
57  wincmd p
58  call assert_equal(5, &g:undolevels)
59  call assert_equal(-123456, &l:undolevels)
60
61  new three
62  setglobal ul=50
63  call assert_equal(50, &g:undolevels)
64  call assert_equal(-123456, &l:undolevels)
65
66  " Drop created windows
67  set ul&
68  new
69  only!
70endfunc
71
72func BackOne(expected)
73  call feedkeys('g-', 'xt')
74  call assert_equal(a:expected, getline(1))
75endfunc
76
77func Test_undo_del_chars()
78  " Setup a buffer without creating undo entries
79  new
80  set ul=-1
81  call setline(1, ['123-456'])
82  set ul=100
83  1
84  call test_settime(100)
85
86  " Delete three characters and undo with g-
87  call feedkeys('x', 'xt')
88  call feedkeys('x', 'xt')
89  call feedkeys('x', 'xt')
90  call assert_equal('-456', getline(1))
91  call BackOne('3-456')
92  call BackOne('23-456')
93  call BackOne('123-456')
94  call assert_fails("BackOne('123-456')")
95
96  :" Delete three other characters and go back in time with g-
97  call feedkeys('$x', 'xt')
98  call feedkeys('x', 'xt')
99  call feedkeys('x', 'xt')
100  call assert_equal('123-', getline(1))
101  call test_settime(101)
102
103  call BackOne('123-4')
104  call BackOne('123-45')
105  " skips '123-456' because it's older
106  call BackOne('-456')
107  call BackOne('3-456')
108  call BackOne('23-456')
109  call BackOne('123-456')
110  call assert_fails("BackOne('123-456')")
111  normal 10g+
112  call assert_equal('123-', getline(1))
113
114  :" Jump two seconds and go some seconds forward and backward
115  call test_settime(103)
116  call feedkeys("Aa\<Esc>", 'xt')
117  call feedkeys("Ab\<Esc>", 'xt')
118  call feedkeys("Ac\<Esc>", 'xt')
119  call assert_equal('123-abc', getline(1))
120  earlier 1s
121  call assert_equal('123-', getline(1))
122  earlier 3s
123  call assert_equal('123-456', getline(1))
124  later 1s
125  call assert_equal('123-', getline(1))
126  later 1h
127  call assert_equal('123-abc', getline(1))
128
129  close!
130endfunc
131
132func Test_undolist()
133  new
134  set ul=100
135
136  let a=execute('undolist')
137  call assert_equal("\nNothing to undo", a)
138
139  " 1 leaf (2 changes).
140  call feedkeys('achange1', 'xt')
141  call feedkeys('achange2', 'xt')
142  let a=execute('undolist')
143  call assert_match("^\nnumber changes  when  *saved\n *2  *2 .*$", a)
144
145  " 2 leaves.
146  call feedkeys('u', 'xt')
147  call feedkeys('achange3\<Esc>', 'xt')
148  let a=execute('undolist')
149  call assert_match("^\nnumber changes  when  *saved\n *2  *2  *.*\n *3  *2 .*$", a)
150  close!
151endfunc
152
153func Test_U_command()
154  new
155  set ul=100
156  call feedkeys("achange1\<Esc>", 'xt')
157  call feedkeys("achange2\<Esc>", 'xt')
158  norm! U
159  call assert_equal('', getline(1))
160  norm! U
161  call assert_equal('change1change2', getline(1))
162  close!
163endfunc
164
165func Test_undojoin()
166  new
167  call feedkeys("Goaaaa\<Esc>", 'xt')
168  call feedkeys("obbbb\<Esc>", 'xt')
169  call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
170  call feedkeys("u", 'xt')
171  call assert_equal(['aaaa'], getline(2, '$'))
172  call feedkeys("obbbb\<Esc>", 'xt')
173  undojoin
174  " Note: next change must not be as if typed
175  call feedkeys("occcc\<Esc>", 'x')
176  call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
177  call feedkeys("u", 'xt')
178  call assert_equal(['aaaa'], getline(2, '$'))
179  bwipe!
180endfunc
181
182func Test_undojoin_redo()
183  new
184  call setline(1, ['first line', 'second line'])
185  call feedkeys("ixx\<Esc>", 'xt')
186  call feedkeys(":undojoin | redo\<CR>", 'xt')
187  call assert_equal('xxfirst line', getline(1))
188  call assert_equal('second line', getline(2))
189  bwipe!
190endfunc
191
192func Test_undo_write()
193  call delete('Xtest')
194  split Xtest
195  call feedkeys("ione one one\<Esc>", 'xt')
196  w!
197  call feedkeys("otwo\<Esc>", 'xt')
198  call feedkeys("otwo\<Esc>", 'xt')
199  w
200  call feedkeys("othree\<Esc>", 'xt')
201  call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
202  earlier 1f
203  call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
204  earlier 1f
205  call assert_equal(['one one one'], getline(1, '$'))
206  earlier 1f
207  call assert_equal([''], getline(1, '$'))
208  later 1f
209  call assert_equal(['one one one'], getline(1, '$'))
210  later 1f
211  call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
212  later 1f
213  call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
214
215  close!
216  call delete('Xtest')
217  bwipe! Xtest
218endfunc
219
220func Test_insert_expr()
221  new
222  " calling setline() triggers undo sync
223  call feedkeys("oa\<Esc>", 'xt')
224  call feedkeys("ob\<Esc>", 'xt')
225  set ul=100
226  call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
227  call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
228  call feedkeys("u", 'x')
229  call assert_equal(['a', 'b', '12'], getline(2, '$'))
230  call feedkeys("u", 'x')
231  call assert_equal(['a', 'b'], getline(2, '$'))
232
233  call feedkeys("oc\<Esc>", 'xt')
234  set ul=100
235  call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
236  call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
237  call feedkeys("u", 'x')
238  call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
239
240  call feedkeys("od\<Esc>", 'xt')
241  set ul=100
242  call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
243  call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
244  call feedkeys("u", 'x')
245  call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
246
247  close!
248endfunc
249
250func Test_undofile_earlier()
251  " Issue #1254
252  " create undofile with timestamps older than Vim startup time.
253  let t0 = localtime() - 43200
254  call test_settime(t0)
255  new Xfile
256  call feedkeys("ione\<Esc>", 'xt')
257  set ul=100
258  call test_settime(t0 + 1)
259  call feedkeys("otwo\<Esc>", 'xt')
260  set ul=100
261  call test_settime(t0 + 2)
262  call feedkeys("othree\<Esc>", 'xt')
263  set ul=100
264  w
265  wundo Xundofile
266  bwipe!
267  " restore normal timestamps.
268  call test_settime(0)
269  new Xfile
270  rundo Xundofile
271  earlier 1d
272  call assert_equal('', getline(1))
273  bwipe!
274  call delete('Xfile')
275  call delete('Xundofile')
276endfunc
277
278" Test for undo working properly when executing commands from a register.
279" Also test this in an empty buffer.
280func Test_cmd_in_reg_undo()
281  enew!
282  let @a="Ox\<Esc>jAy\<Esc>kdd"
283  edit +/^$ test_undo.vim
284  normal @au
285  call assert_equal(0, &modified)
286  return
287  new
288  normal @au
289  call assert_equal(0, &modified)
290  only!
291  let @a=''
292endfunc
293