blob: bda7a442f1e1d759d298483ee50f33edd7107643 [file] [log] [blame]
Bram Moolenaar170b10b2016-07-29 16:15:27 +02001" 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
Bram Moolenaarc628fdc2016-08-31 20:33:27 +0200132func 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
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200165func 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, '$'))
Bram Moolenaar5e4e1b12017-01-17 22:09:45 +0100179 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!
Bram Moolenaar170b10b2016-07-29 16:15:27 +0200190endfunc
191
192func Test_undo_write()
193 split Xtest
194 call feedkeys("ione one one\<Esc>", 'xt')
195 w!
196 call feedkeys("otwo\<Esc>", 'xt')
197 call feedkeys("otwo\<Esc>", 'xt')
198 w
199 call feedkeys("othree\<Esc>", 'xt')
200 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
201 earlier 1f
202 call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
203 earlier 1f
204 call assert_equal(['one one one'], getline(1, '$'))
205 earlier 1f
206 call assert_equal([''], getline(1, '$'))
207 later 1f
208 call assert_equal(['one one one'], getline(1, '$'))
209 later 1f
210 call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
211 later 1f
212 call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
213
214 close!
215 call delete('Xtest')
216 bwipe! Xtest
217endfunc
218
219func Test_insert_expr()
220 new
221 " calling setline() triggers undo sync
222 call feedkeys("oa\<Esc>", 'xt')
223 call feedkeys("ob\<Esc>", 'xt')
224 set ul=100
225 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
226 call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
227 call feedkeys("u", 'x')
228 call assert_equal(['a', 'b', '12'], getline(2, '$'))
229 call feedkeys("u", 'x')
230 call assert_equal(['a', 'b'], getline(2, '$'))
231
232 call feedkeys("oc\<Esc>", 'xt')
233 set ul=100
234 call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
235 call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
236 call feedkeys("u", 'x')
237 call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
238
239 call feedkeys("od\<Esc>", 'xt')
240 set ul=100
241 call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
242 call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
243 call feedkeys("u", 'x')
244 call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
245
246 close!
247endfunc
Bram Moolenaarcbd4de42017-01-07 16:14:57 +0100248
249func Test_undofile_earlier()
250 " Issue #1254
251 " create undofile with timestamps older than Vim startup time.
252 let t0 = localtime() - 43200
253 call test_settime(t0)
254 new Xfile
255 call feedkeys("ione\<Esc>", 'xt')
256 set ul=100
257 call test_settime(t0 + 1)
258 call feedkeys("otwo\<Esc>", 'xt')
259 set ul=100
260 call test_settime(t0 + 2)
261 call feedkeys("othree\<Esc>", 'xt')
262 set ul=100
263 w
264 wundo Xundofile
265 bwipe!
266 " restore normal timestamps.
267 call test_settime(0)
268 new Xfile
269 rundo Xundofile
270 earlier 1d
271 call assert_equal('', getline(1))
272 bwipe!
273 call delete('Xfile')
274 call delete('Xundofile')
275endfunc
Bram Moolenaar15993ce2017-10-26 20:21:44 +0200276
277" Test for undo working properly when executing commands from a register.
278" Also test this in an empty buffer.
279func Test_cmd_in_reg_undo()
280 enew!
281 let @a="Ox\<Esc>jAy\<Esc>kdd"
282 edit +/^$ test_undo.vim
283 normal @au
284 call assert_equal(0, &modified)
285 return
286 new
287 normal @au
288 call assert_equal(0, &modified)
289 only!
290 let @a=''
291endfunc