mirror of
https://github.com/lewis6991/gitsigns.nvim
synced 2025-02-14 19:26:56 +00:00
- When staging files, convert the text into a string before passing to system() to ensure EOL is respected. - When setting lines. If text doesn't end with an empty line then set 'eol=false'. Fixes #1145
360 lines
8.8 KiB
Lua
360 lines
8.8 KiB
Lua
local helpers = require('test.gs_helpers')
|
|
|
|
local setup_gitsigns = helpers.setup_gitsigns
|
|
local feed = helpers.feed
|
|
local test_file = helpers.test_file
|
|
local edit = helpers.edit
|
|
local check = helpers.check
|
|
local exec_lua = helpers.exec_lua
|
|
local fn = helpers.fn
|
|
local system = fn.system
|
|
local test_config = helpers.test_config
|
|
local clear = helpers.clear
|
|
local setup_test_repo = helpers.setup_test_repo
|
|
local eq = helpers.eq
|
|
local expectf = helpers.expectf
|
|
|
|
helpers.env()
|
|
|
|
--- @param exp_hunks string[]
|
|
local function expect_hunks(exp_hunks)
|
|
expectf(function()
|
|
--- @type table[]
|
|
local hunks = exec_lua("return require('gitsigns').get_hunks()")
|
|
if #exp_hunks ~= #hunks then
|
|
local msg = {} --- @type string[]
|
|
msg[#msg + 1] = ''
|
|
msg[#msg + 1] = string.format(
|
|
'Number of hunks do not match. Expected: %d, passed in: %d',
|
|
#exp_hunks,
|
|
#hunks
|
|
)
|
|
|
|
msg[#msg + 1] = '\nExpected hunks:'
|
|
for _, h in ipairs(exp_hunks) do
|
|
msg[#msg + 1] = h
|
|
end
|
|
|
|
msg[#msg + 1] = '\nPassed in hunks:'
|
|
for _, h in ipairs(hunks) do
|
|
msg[#msg + 1] = h.head
|
|
end
|
|
|
|
error(table.concat(msg, '\n'))
|
|
end
|
|
|
|
for i, hunk in ipairs(hunks) do
|
|
eq(exp_hunks[i], hunk.head)
|
|
end
|
|
end)
|
|
end
|
|
|
|
local delay = 10
|
|
|
|
local function command(cmd)
|
|
helpers.sleep(delay)
|
|
helpers.api.nvim_command(cmd)
|
|
|
|
-- Flaky tests, add a large delay between commands.
|
|
-- Flakyness is due to actions being async and problems occur when an action
|
|
-- is run while another action or update is running.
|
|
-- Must wait for actions and updates to finish.
|
|
helpers.sleep(delay)
|
|
end
|
|
|
|
local function retry(f)
|
|
local orig_delay = delay
|
|
local ok, err
|
|
|
|
for _ = 1, 20 do
|
|
ok, err = pcall(f)
|
|
if ok then
|
|
return
|
|
end
|
|
delay = delay * 1.6
|
|
print('failed, retrying with delay', delay)
|
|
end
|
|
|
|
if err then
|
|
delay = orig_delay
|
|
error(err)
|
|
end
|
|
end
|
|
|
|
describe('actions', function()
|
|
local orig_it = it
|
|
local function it(desc, f)
|
|
orig_it(desc, function()
|
|
retry(f)
|
|
end)
|
|
end
|
|
|
|
local config --- @type Gitsigns.Config
|
|
|
|
before_each(function()
|
|
clear()
|
|
-- Make gitisigns available
|
|
exec_lua('package.path = ...', package.path)
|
|
config = vim.deepcopy(test_config)
|
|
command('cd ' .. system({ 'dirname', os.tmpname() }))
|
|
setup_gitsigns(config)
|
|
end)
|
|
|
|
it('works with commands', function()
|
|
setup_test_repo()
|
|
edit(test_file)
|
|
|
|
feed('jjjccEDIT<esc>')
|
|
check({
|
|
status = { head = 'master', added = 0, changed = 1, removed = 0 },
|
|
signs = { changed = 1 },
|
|
})
|
|
|
|
command('Gitsigns stage_hunk')
|
|
check({
|
|
status = { head = 'master', added = 0, changed = 0, removed = 0 },
|
|
signs = {},
|
|
})
|
|
|
|
command('Gitsigns undo_stage_hunk')
|
|
check({
|
|
status = { head = 'master', added = 0, changed = 1, removed = 0 },
|
|
signs = { changed = 1 },
|
|
})
|
|
|
|
-- Add multiple edits
|
|
feed('ggccThat<esc>')
|
|
|
|
check({
|
|
status = { head = 'master', added = 0, changed = 2, removed = 0 },
|
|
signs = { changed = 2 },
|
|
})
|
|
|
|
command('Gitsigns stage_buffer')
|
|
check({
|
|
status = { head = 'master', added = 0, changed = 0, removed = 0 },
|
|
signs = {},
|
|
})
|
|
|
|
command('Gitsigns reset_buffer_index')
|
|
check({
|
|
status = { head = 'master', added = 0, changed = 2, removed = 0 },
|
|
signs = { changed = 2 },
|
|
})
|
|
|
|
command('Gitsigns reset_hunk')
|
|
check({
|
|
status = { head = 'master', added = 0, changed = 1, removed = 0 },
|
|
signs = { changed = 1 },
|
|
})
|
|
end)
|
|
|
|
describe('staging partial hunks', function()
|
|
setup(function()
|
|
clear()
|
|
setup_test_repo({ test_file_text = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } })
|
|
end)
|
|
|
|
before_each(function()
|
|
helpers.git({ 'reset', '--hard' })
|
|
edit(test_file)
|
|
end)
|
|
|
|
local function set_lines(start, dend, lines)
|
|
helpers.api.nvim_buf_set_lines(0, start, dend, false, lines)
|
|
end
|
|
|
|
describe('can stage add hunks', function()
|
|
before_each(function()
|
|
set_lines(2, 2, { 'c1', 'c2', 'c3', 'c4' })
|
|
expect_hunks({ '@@ -2 +3,4 @@' })
|
|
end)
|
|
|
|
it('contained in range', function()
|
|
command([[1,7 Gitsigns stage_hunk]])
|
|
expect_hunks({})
|
|
end)
|
|
|
|
it('containing range', function()
|
|
command([[4,5 Gitsigns stage_hunk]])
|
|
expect_hunks({
|
|
'@@ -2 +3,1 @@',
|
|
'@@ -4 +6,1 @@',
|
|
})
|
|
end)
|
|
|
|
it('from top range', function()
|
|
command([[1,4 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -4 +5,2 @@' })
|
|
end)
|
|
|
|
it('from bottom range', function()
|
|
command([[4,7 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -2 +3,1 @@' })
|
|
|
|
command([[Gitsigns reset_buffer_index]])
|
|
expect_hunks({ '@@ -2 +3,4 @@' })
|
|
|
|
command([[4,10 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -2 +3,1 @@' })
|
|
end)
|
|
end)
|
|
|
|
describe('can stage modified-add hunks', function()
|
|
before_each(function()
|
|
set_lines(2, 4, { 'c1', 'c2', 'c3', 'c4', 'c5' })
|
|
expect_hunks({ '@@ -3,2 +3,5 @@' })
|
|
end)
|
|
|
|
it('from top range containing mod', function()
|
|
command([[2,3 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -4,1 +4,4 @@' })
|
|
end)
|
|
|
|
it('from top range containing mod-add', function()
|
|
command([[2,5 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -5 +6,2 @@' })
|
|
end)
|
|
|
|
it('from bottom range containing add', function()
|
|
command([[6,8 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -3,2 +3,3 @@' })
|
|
end)
|
|
|
|
it('containing range containing add', function()
|
|
command('write')
|
|
command([[5,6 Gitsigns stage_hunk]])
|
|
expect_hunks({
|
|
'@@ -3,2 +3,2 @@',
|
|
'@@ -6 +7,1 @@',
|
|
})
|
|
end)
|
|
end)
|
|
|
|
describe('can stage modified-remove hunks', function()
|
|
before_each(function()
|
|
set_lines(2, 7, { 'c1', 'c2', 'c3' })
|
|
command('write')
|
|
expect_hunks({ '@@ -3,5 +3,3 @@' })
|
|
end)
|
|
|
|
it('from top range', function()
|
|
expect_hunks({ '@@ -3,5 +3,3 @@' })
|
|
|
|
command([[2,3 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -4,4 +4,2 @@' })
|
|
|
|
command([[2,3 Gitsigns reset_buffer_index]])
|
|
expect_hunks({ '@@ -3,5 +3,3 @@' })
|
|
|
|
command([[2,4 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -5,3 +5,1 @@' })
|
|
end)
|
|
|
|
it('from bottom range', function()
|
|
expect_hunks({ '@@ -3,5 +3,3 @@' })
|
|
|
|
command([[4,6 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -3,1 +3,1 @@' })
|
|
|
|
command([[2,3 Gitsigns reset_buffer_index]])
|
|
expect_hunks({ '@@ -3,5 +3,3 @@' })
|
|
|
|
command([[5,6 Gitsigns stage_hunk]])
|
|
expect_hunks({ '@@ -3,2 +3,2 @@' })
|
|
end)
|
|
end)
|
|
|
|
it('can stage remove hunks', function()
|
|
set_lines(2, 5, {})
|
|
expect_hunks({ '@@ -3,3 +2 @@' })
|
|
|
|
command([[2 Gitsigns stage_hunk]])
|
|
expect_hunks({})
|
|
end)
|
|
end)
|
|
|
|
local function check_cursor(pos)
|
|
eq(pos, helpers.api.nvim_win_get_cursor(0))
|
|
end
|
|
|
|
it('can navigate hunks', function()
|
|
setup_test_repo()
|
|
edit(test_file)
|
|
|
|
feed('dd')
|
|
feed('4Gx')
|
|
feed('6Gx')
|
|
|
|
expect_hunks({
|
|
'@@ -1,1 +0 @@',
|
|
'@@ -5,1 +4,1 @@',
|
|
'@@ -7,1 +6,1 @@',
|
|
})
|
|
|
|
check_cursor({ 6, 0 })
|
|
command('Gitsigns next_hunk') -- Wrap
|
|
check_cursor({ 1, 0 })
|
|
command('Gitsigns next_hunk')
|
|
check_cursor({ 4, 0 })
|
|
command('Gitsigns next_hunk')
|
|
check_cursor({ 6, 0 })
|
|
|
|
command('Gitsigns prev_hunk')
|
|
check_cursor({ 4, 0 })
|
|
command('Gitsigns prev_hunk')
|
|
check_cursor({ 1, 0 })
|
|
command('Gitsigns prev_hunk') -- Wrap
|
|
check_cursor({ 6, 0 })
|
|
end)
|
|
|
|
it('can navigate hunks (nowrap)', function()
|
|
setup_test_repo()
|
|
edit(test_file)
|
|
|
|
feed('4Gx')
|
|
feed('6Gx')
|
|
feed('gg')
|
|
|
|
expect_hunks({
|
|
'@@ -4,1 +4,1 @@',
|
|
'@@ -6,1 +6,1 @@',
|
|
})
|
|
|
|
command('set nowrapscan')
|
|
|
|
check_cursor({ 1, 0 })
|
|
command('Gitsigns next_hunk')
|
|
check_cursor({ 4, 0 })
|
|
command('Gitsigns next_hunk')
|
|
check_cursor({ 6, 0 })
|
|
command('Gitsigns next_hunk')
|
|
check_cursor({ 6, 0 })
|
|
|
|
feed('G')
|
|
check_cursor({ 18, 0 })
|
|
command('Gitsigns prev_hunk')
|
|
check_cursor({ 6, 0 })
|
|
command('Gitsigns prev_hunk')
|
|
check_cursor({ 4, 0 })
|
|
command('Gitsigns prev_hunk')
|
|
check_cursor({ 4, 0 })
|
|
end)
|
|
|
|
it('can stage hunks with no NL at EOF', function()
|
|
setup_test_repo()
|
|
local newfile = helpers.newfile
|
|
exec_lua([[vim.g.editorconfig = false]])
|
|
system("printf 'This is a file with no nl at eof' > " .. newfile)
|
|
helpers.git({ 'add', newfile })
|
|
helpers.git({ 'commit', '-m', 'commit on main' })
|
|
|
|
edit(newfile)
|
|
check({ status = { head = 'master', added = 0, changed = 0, removed = 0 } })
|
|
feed('x')
|
|
check({ status = { head = 'master', added = 0, changed = 1, removed = 0 } })
|
|
command('Gitsigns stage_hunk')
|
|
check({ status = { head = 'master', added = 0, changed = 0, removed = 0 } })
|
|
end)
|
|
end)
|