neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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)