undotree_spec.lua (4213B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 4 local clear = n.clear 5 local eq = t.eq 6 local exec = n.exec 7 local api = n.api 8 local dedent = t.dedent 9 local Screen = require('test.functional.ui.screen') 10 11 ---@param reverse_tree {[integer]:integer} 12 local function generate_undo_tree_from_rev(reverse_tree) 13 for k, v in ipairs(reverse_tree) do 14 exec('undo ' .. v) 15 api.nvim_buf_set_lines(0, 0, -1, true, { tostring(k) }) 16 end 17 end 18 ---@param buf integer 19 ---@return string 20 local function buf_get_lines_and_extmark(buf) 21 local lines = api.nvim_buf_get_lines(buf, 0, -1, true) 22 local ns = api.nvim_create_namespace('nvim.undotree') 23 local extmarks = api.nvim_buf_get_extmarks(buf, ns, 0, -1, { details = true }) 24 for i = #extmarks, 1, -1 do 25 local extmark = extmarks[i] 26 ---@type nil,integer,nil,vim.api.keyset.extmark_details 27 local _, row, _, opts = unpack(extmark) 28 local virt_lines = assert(opts.virt_lines) 29 for _, v in ipairs(virt_lines) do 30 local virt_line = v[1][1] 31 table.insert(lines, row + 2, virt_line) 32 end 33 end 34 return table.concat(lines, '\n') 35 end 36 37 local function strip_time(text) 38 return text:gsub('%s-%(.-%)', '') 39 end 40 41 describe(':Undotree', function() 42 before_each(function() 43 clear({ args = { '--clean' } }) 44 exec 'packadd nvim.undotree' 45 end) 46 47 it('works', function() 48 api.nvim_set_current_line('foo') 49 exec 'Undotree' 50 local buf = api.nvim_get_current_buf() 51 local win = api.nvim_get_current_win() 52 eq( 53 dedent [[ 54 * 0 55 * 1]], 56 strip_time(buf_get_lines_and_extmark(buf)) 57 ) 58 eq(2, api.nvim_win_get_cursor(win)[1]) 59 exec 'wincmd w' 60 61 -- Doing changes moves cursor in undotree 62 exec 'undo' 63 eq(1, api.nvim_win_get_cursor(win)[1]) 64 api.nvim_set_current_line('bar') 65 eq(3, api.nvim_win_get_cursor(win)[1]) 66 67 eq( 68 dedent [[ 69 * 0 70 |\ 71 | * 1 72 * 2]], 73 strip_time(buf_get_lines_and_extmark(buf)) 74 ) 75 76 -- Moving the cursor in undotree changes the buffer 77 eq('bar', api.nvim_get_current_line()) 78 exec 'wincmd w' 79 exec '2' 80 exec 'wincmd w' 81 eq('foo', api.nvim_get_current_line()) 82 end) 83 84 it('sync scroll pos when undo', function() 85 local screen = Screen.new(30, 10) 86 for _ = 1, n.api.nvim_get_option_value('lines', {}) do 87 api.nvim_set_current_line('foo') 88 end 89 exec 'Undotree' 90 exec 'wincmd w' 91 exec 'silent undo' 92 screen:expect([[ 93 * 3 │^foo | 94 * 4 │{1:~ }| 95 * 5 │{1:~ }| 96 * 6 │{1:~ }| 97 * 7 │{1:~ }| 98 * 8 │{1:~ }| 99 {21:* 9 }│{1:~ }| 100 * 10 │{1:~ }| 101 {2:<or [-] }{3:[No Name] [+] }| 102 | 103 ]]) 104 end) 105 106 describe('branch+remove is correctly graphed', function() 107 it('when branching left', function() 108 generate_undo_tree_from_rev({ 0, 1, 2, 3, 1, 3, 4, 3, 2, 0 }) 109 exec 'Undotree' 110 eq( 111 dedent([[ 112 * 0 113 |\ 114 | * 1 115 | |\ 116 | | * 2 117 | | |\ 118 | | | * 3 119 | | | |\ 120 | | | | * 4 121 | * | | | 5 122 | / /| |]] --[[This is the line being tested, e.g. remove&branch left]] .. '\n' .. [[ 123 | | | * | 6 124 | | | / 125 | | | * 7 126 | | * 8 127 | * 9 128 * 10]]), 129 strip_time(buf_get_lines_and_extmark(0)) 130 ) 131 end) 132 133 it('when branching right', function() 134 generate_undo_tree_from_rev({ 0, 1, 2, 3, 3, 1, 4, 2, 1, 0 }) 135 exec 'Undotree' 136 eq( 137 dedent([[ 138 * 0 139 |\ 140 | * 1 141 | |\ 142 | | * 2 143 | | |\ 144 | | | * 3 145 | | | |\ 146 | | | | * 4 147 | | | * | 5 148 | |\ \ |]] --[[This is the line being tested, e.g. remove&branch right]] .. '\n' .. [[ 149 | | * | | 6 150 | | / / 151 | | | * 7 152 | | * 8 153 | * 9 154 * 10]]), 155 strip_time(buf_get_lines_and_extmark(0)) 156 ) 157 end) 158 end) 159 end)