xref: /vim-8.2.3635/src/testdir/test_undo.vim (revision c3c766ea)
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
6set belloff=all
7func Test_undotree()
8  exe "normal Aabc\<Esc>"
9  set ul=100
10  exe "normal Adef\<Esc>"
11  set ul=100
12  undo
13  let d = undotree()
14  call assert_true(d.seq_last > 0)
15  call assert_true(d.seq_cur > 0)
16  call assert_true(d.seq_cur < d.seq_last)
17  call assert_true(len(d.entries) > 0)
18  " TODO: check more members of d
19
20  w! Xtest
21  call assert_equal(d.save_last + 1, undotree().save_last)
22  call delete('Xtest')
23  bwipe Xtest
24endfunc
25
26func FillBuffer()
27  for i in range(1,13)
28    put=i
29    " Set 'undolevels' to split undo.
30    exe "setg ul=" . &g:ul
31  endfor
32endfunc
33
34func Test_global_local_undolevels()
35  new one
36  set undolevels=5
37  call FillBuffer()
38  " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
39  earlier 10
40  call assert_equal(5, &g:undolevels)
41  call assert_equal(-123456, &l:undolevels)
42  call assert_equal('7', getline('$'))
43
44  new two
45  setlocal undolevels=2
46  call FillBuffer()
47  " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
48  earlier 10
49  call assert_equal(5, &g:undolevels)
50  call assert_equal(2, &l:undolevels)
51  call assert_equal('10', getline('$'))
52
53  setlocal ul=10
54  call assert_equal(5, &g:undolevels)
55  call assert_equal(10, &l:undolevels)
56
57  " Setting local value in "two" must not change local value in "one"
58  wincmd p
59  call assert_equal(5, &g:undolevels)
60  call assert_equal(-123456, &l:undolevels)
61
62  new three
63  setglobal ul=50
64  call assert_equal(50, &g:undolevels)
65  call assert_equal(-123456, &l:undolevels)
66
67  " Drop created windows
68  set ul&
69  new
70  only!
71endfunc
72
73func BackOne(expected)
74  call feedkeys('g-', 'xt')
75  call assert_equal(a:expected, getline(1))
76endfunc
77
78func Test_undo_del_chars()
79  " Setup a buffer without creating undo entries
80  new
81  set ul=-1
82  call setline(1, ['123-456'])
83  set ul=100
84  1
85  call test_settime(100)
86
87  " Delete three characters and undo with g-
88  call feedkeys('x', 'xt')
89  call feedkeys('x', 'xt')
90  call feedkeys('x', 'xt')
91  call assert_equal('-456', getline(1))
92  call BackOne('3-456')
93  call BackOne('23-456')
94  call BackOne('123-456')
95  call assert_fails("BackOne('123-456')")
96
97  :" Delete three other characters and go back in time with g-
98  call feedkeys('$x', 'xt')
99  call feedkeys('x', 'xt')
100  call feedkeys('x', 'xt')
101  call assert_equal('123-', getline(1))
102  call test_settime(101)
103
104  call BackOne('123-4')
105  call BackOne('123-45')
106  " skips '123-456' because it's older
107  call BackOne('-456')
108  call BackOne('3-456')
109  call BackOne('23-456')
110  call BackOne('123-456')
111  call assert_fails("BackOne('123-456')")
112  normal 10g+
113  call assert_equal('123-', getline(1))
114
115  :" Jump two seconds and go some seconds forward and backward
116  call test_settime(103)
117  call feedkeys("Aa\<Esc>", 'xt')
118  call feedkeys("Ab\<Esc>", 'xt')
119  call feedkeys("Ac\<Esc>", 'xt')
120  call assert_equal('123-abc', getline(1))
121  earlier 1s
122  call assert_equal('123-', getline(1))
123  earlier 3s
124  call assert_equal('123-456', getline(1))
125  later 1s
126  call assert_equal('123-', getline(1))
127  later 1h
128  call assert_equal('123-abc', getline(1))
129
130  close!
131endfunc
132
133func Test_undolist()
134  new
135  set ul=100
136
137  let a=execute('undolist')
138  call assert_equal("\nNothing to undo", a)
139
140  " 1 leaf (2 changes).
141  call feedkeys('achange1', 'xt')
142  call feedkeys('achange2', 'xt')
143  let a=execute('undolist')
144  call assert_match("^\nnumber changes  when  *saved\n *2  *2 .*$", a)
145
146  " 2 leaves.
147  call feedkeys('u', 'xt')
148  call feedkeys('achange3\<Esc>', 'xt')
149  let a=execute('undolist')
150  call assert_match("^\nnumber changes  when  *saved\n *2  *2  *.*\n *3  *2 .*$", a)
151  close!
152endfunc
153
154func Test_U_command()
155  new
156  set ul=100
157  call feedkeys("achange1\<Esc>", 'xt')
158  call feedkeys("achange2\<Esc>", 'xt')
159  norm! U
160  call assert_equal('', getline(1))
161  norm! U
162  call assert_equal('change1change2', getline(1))
163  close!
164endfunc
165
166func Test_undojoin()
167  new
168  call feedkeys("Goaaaa\<Esc>", 'xt')
169  call feedkeys("obbbb\<Esc>", 'xt')
170  call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
171  call feedkeys("u", 'xt')
172  call assert_equal(['aaaa'], getline(2, '$'))
173  call feedkeys("obbbb\<Esc>", 'xt')
174  undojoin
175  " Note: next change must not be as if typed
176  call feedkeys("occcc\<Esc>", 'x')
177  call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
178  call feedkeys("u", 'xt')
179  call assert_equal(['aaaa'], getline(2, '$'))
180  bwipe!
181endfunc
182
183func Test_undojoin_redo()
184  new
185  call setline(1, ['first line', 'second line'])
186  call feedkeys("ixx\<Esc>", 'xt')
187  call feedkeys(":undojoin | redo\<CR>", 'xt')
188  call assert_equal('xxfirst line', getline(1))
189  call assert_equal('second line', getline(2))
190  bwipe!
191endfunc
192
193func Test_undo_write()
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