061_undo_tree_spec.lua (5816B)
1 -- Tests for undo tree and :earlier and :later. 2 local t = require('test.testutil') 3 local n = require('test.functional.testnvim')() 4 5 local feed_command = n.feed_command 6 local write_file = t.write_file 7 local command = n.command 8 local source = n.source 9 local expect = n.expect 10 local clear = n.clear 11 local feed = n.feed 12 local eval = n.eval 13 local eq = t.eq 14 15 local function expect_empty_buffer() 16 return expect('') 17 end 18 local function expect_line(line) 19 return eq(line, eval('getline(".")')) 20 end 21 22 describe('undo tree:', function() 23 before_each(clear) 24 local fname = 'Xtest_functional_legacy_undotree' 25 teardown(function() 26 os.remove(fname .. '.source') 27 end) 28 29 describe(':earlier and :later', function() 30 before_each(function() 31 os.remove(fname) 32 end) 33 teardown(function() 34 os.remove(fname) 35 end) 36 37 it('time specifications, g- g+', function() 38 -- We write the test text to a file in order to prevent nvim to record 39 -- the inserting of the text into the undo history. 40 write_file(fname, '\n123456789\n') 41 42 -- `:earlier` and `:later` are (obviously) time-sensitive, so this test 43 -- sometimes fails if the system is under load. It is wrapped in a local 44 -- function to allow multiple attempts. 45 local function test_earlier_later() 46 clear() 47 feed_command('e ' .. fname) 48 -- Assert that no undo history is present. 49 eq({}, eval('undotree().entries')) 50 -- Delete three characters and undo. 51 feed('Gxxx') 52 expect_line('456789') 53 feed('g-') 54 expect_line('3456789') 55 feed('g-') 56 expect_line('23456789') 57 feed('g-') 58 expect_line('123456789') 59 feed('g-') 60 expect_line('123456789') 61 62 -- Delete three other characters and go back in time step by step. 63 feed('$xxx') 64 expect_line('123456') 65 command('sleep 1') 66 feed('g-') 67 expect_line('1234567') 68 feed('g-') 69 expect_line('12345678') 70 feed('g-') 71 expect_line('456789') 72 feed('g-') 73 expect_line('3456789') 74 feed('g-') 75 expect_line('23456789') 76 feed('g-') 77 expect_line('123456789') 78 feed('g-') 79 expect_line('123456789') 80 feed('g-') 81 expect_line('123456789') 82 feed('10g+') 83 expect_line('123456') 84 85 -- Delay for two seconds and go some seconds forward and backward. 86 command('sleep 2') 87 feed('Aa<esc>') 88 feed('Ab<esc>') 89 feed('Ac<esc>') 90 expect_line('123456abc') 91 feed_command('earlier 1s') 92 expect_line('123456') 93 feed_command('earlier 3s') 94 expect_line('123456789') 95 feed_command('later 1s') 96 expect_line('123456') 97 feed_command('later 1h') 98 expect_line('123456abc') 99 end 100 101 t.retry(2, nil, test_earlier_later) 102 end) 103 104 it('file-write specifications', function() 105 feed('ione one one<esc>') 106 feed_command('w ' .. fname) 107 feed('otwo<esc>') 108 feed('otwo<esc>') 109 feed_command('w') 110 feed('othree<esc>') 111 feed_command('earlier 1f') 112 expect([[ 113 one one one 114 two 115 two]]) 116 feed_command('earlier 1f') 117 expect('one one one') 118 feed_command('earlier 1f') 119 expect_empty_buffer() 120 feed_command('later 1f') 121 expect('one one one') 122 feed_command('later 1f') 123 expect([[ 124 one one one 125 two 126 two]]) 127 feed_command('later 1f') 128 expect([[ 129 one one one 130 two 131 two 132 three]]) 133 end) 134 end) 135 136 it('scripts produce one undo-block for all changes by default', function() 137 source([[ 138 normal Aaaaa 139 normal obbbb 140 normal occcc 141 ]]) 142 expect([[ 143 aaaa 144 bbbb 145 cccc]]) 146 feed('u') 147 expect_empty_buffer() 148 end) 149 150 it("setting 'undolevel' can break undo-blocks (inside scripts)", function() 151 -- :source is required (because interactive changes are _not_ grouped, 152 -- even with :undojoin). 153 source([[ 154 normal Aaaaa 155 set ul=100 156 normal obbbb 157 set ul=100 158 normal occcc 159 ]]) 160 expect([[ 161 aaaa 162 bbbb 163 cccc]]) 164 feed('u') 165 expect([[ 166 aaaa 167 bbbb]]) 168 feed('u') 169 expect('aaaa') 170 feed('u') 171 expect_empty_buffer() 172 end) 173 174 it(':undojoin can join undo-blocks inside scripts', function() 175 feed('Goaaaa<esc>') 176 feed('obbbb<esc>u') 177 expect_line('aaaa') 178 source([[ 179 normal obbbb 180 set ul=100 181 undojoin 182 normal occcc 183 ]]) 184 feed('u') 185 expect_line('aaaa') 186 end) 187 188 it('undo an expression-register', function() 189 local normal_commands = 'o1\027a2\018=string(123)\n\027' 190 write_file(fname .. '.source', normal_commands) 191 192 feed('oa<esc>') 193 feed('ob<esc>') 194 feed([[o1<esc>a2<C-R>=setline('.','1234')<cr><esc>]]) 195 expect([[ 196 197 a 198 b 199 12034]]) 200 feed('uu') 201 expect([[ 202 203 a 204 b 205 1]]) 206 feed('oc<esc>') 207 feed([[o1<esc>a2<C-R>=setline('.','1234')<cr><esc>]]) 208 expect([[ 209 210 a 211 b 212 1 213 c 214 12034]]) 215 feed('u') 216 expect([[ 217 218 a 219 b 220 1 221 c 222 12]]) 223 feed('od<esc>') 224 feed_command('so! ' .. fname .. '.source') 225 expect([[ 226 227 a 228 b 229 1 230 c 231 12 232 d 233 12123]]) 234 feed('u') 235 expect([[ 236 237 a 238 b 239 1 240 c 241 12 242 d]]) 243 244 -- The above behaviour was tested in the legacy Vim test because the 245 -- legacy tests were executed with ':so!'. The behavior differs for 246 -- interactive use (even in Vim; see ":help :undojoin"): 247 feed(normal_commands) 248 expect([[ 249 250 a 251 b 252 1 253 c 254 12 255 d 256 12123]]) 257 feed('u') 258 expect([[ 259 260 a 261 b 262 1 263 c 264 12 265 d 266 1]]) 267 end) 268 end)