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