diffs.nvim/spec/fugitive_spec.lua
Barrett Ruth ce8fe3b89b test(fugitive): add unit tests for line parsing
Tests for get_section_at_line() and get_file_at_line() covering:
- Section detection (staged, unstaged, untracked)
- File parsing (modified, added, deleted, renamed, untracked)
- Hunk line walk-back to parent file
- Files appearing in multiple sections
2026-02-04 22:23:25 -05:00

177 lines
5.4 KiB
Lua

require('spec.helpers')
local fugitive = require('diffs.fugitive')
describe('fugitive', function()
describe('get_section_at_line', function()
local function create_status_buffer(lines)
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
return buf
end
it('returns staged for lines in Staged section', function()
local buf = create_status_buffer({
'Head: main',
'',
'Staged (2)',
'M file1.lua',
'A file2.lua',
'',
'Unstaged (1)',
'M file3.lua',
})
assert.equals('staged', fugitive.get_section_at_line(buf, 4))
assert.equals('staged', fugitive.get_section_at_line(buf, 5))
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('returns unstaged for lines in Unstaged section', function()
local buf = create_status_buffer({
'Head: main',
'',
'Staged (1)',
'M file1.lua',
'',
'Unstaged (2)',
'M file2.lua',
'M file3.lua',
})
assert.equals('unstaged', fugitive.get_section_at_line(buf, 7))
assert.equals('unstaged', fugitive.get_section_at_line(buf, 8))
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('returns untracked for lines in Untracked section', function()
local buf = create_status_buffer({
'Head: main',
'',
'Untracked (2)',
'? newfile.lua',
'? another.lua',
})
assert.equals('untracked', fugitive.get_section_at_line(buf, 4))
assert.equals('untracked', fugitive.get_section_at_line(buf, 5))
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('returns nil for lines before any section', function()
local buf = create_status_buffer({
'Head: main',
'Push: origin/main',
'',
'Staged (1)',
'M file1.lua',
})
assert.is_nil(fugitive.get_section_at_line(buf, 1))
assert.is_nil(fugitive.get_section_at_line(buf, 2))
vim.api.nvim_buf_delete(buf, { force = true })
end)
end)
describe('get_file_at_line', function()
local function create_status_buffer(lines)
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
return buf
end
it('parses simple modified file', function()
local buf = create_status_buffer({
'Unstaged (1)',
'M src/foo.lua',
})
local filename, section = fugitive.get_file_at_line(buf, 2)
assert.equals('src/foo.lua', filename)
assert.equals('unstaged', section)
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('parses added file', function()
local buf = create_status_buffer({
'Staged (1)',
'A newfile.lua',
})
local filename, section = fugitive.get_file_at_line(buf, 2)
assert.equals('newfile.lua', filename)
assert.equals('staged', section)
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('parses deleted file', function()
local buf = create_status_buffer({
'Staged (1)',
'D oldfile.lua',
})
local filename, section = fugitive.get_file_at_line(buf, 2)
assert.equals('oldfile.lua', filename)
assert.equals('staged', section)
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('parses renamed file and returns new name', function()
local buf = create_status_buffer({
'Staged (1)',
'R oldname.lua -> newname.lua',
})
local filename, section = fugitive.get_file_at_line(buf, 2)
assert.equals('newname.lua', filename)
assert.equals('staged', section)
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('parses untracked file', function()
local buf = create_status_buffer({
'Untracked (1)',
'? untracked.lua',
})
local filename, section = fugitive.get_file_at_line(buf, 2)
assert.equals('untracked.lua', filename)
assert.equals('untracked', section)
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('returns nil for section header', function()
local buf = create_status_buffer({
'Unstaged (1)',
'M file.lua',
})
local filename, section = fugitive.get_file_at_line(buf, 1)
assert.is_nil(filename)
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('walks back from hunk line to find file', function()
local buf = create_status_buffer({
'Unstaged (1)',
'M file.lua',
'@@ -1,3 +1,4 @@',
' local M = {}',
'+local new = true',
' return M',
})
local filename, section = fugitive.get_file_at_line(buf, 5)
assert.equals('file.lua', filename)
assert.equals('unstaged', section)
vim.api.nvim_buf_delete(buf, { force = true })
end)
it('handles file with both staged and unstaged indicator', function()
local buf = create_status_buffer({
'Staged (1)',
'M both.lua',
'',
'Unstaged (1)',
'M both.lua',
})
local filename1, section1 = fugitive.get_file_at_line(buf, 2)
assert.equals('both.lua', filename1)
assert.equals('staged', section1)
local filename2, section2 = fugitive.get_file_at_line(buf, 5)
assert.equals('both.lua', filename2)
assert.equals('unstaged', section2)
vim.api.nvim_buf_delete(buf, { force = true })
end)
end)
end)