211 lines
6.0 KiB
Lua
211 lines
6.0 KiB
Lua
local h = require("helpers")
|
|
|
|
require("git").init()
|
|
|
|
---Run the cursor-restore autocmd that was responsible for the original
|
|
---cursor-jump bug. Replicating it lets the regression test exercise the
|
|
---same interaction the user had in their config.
|
|
local function install_cursor_restore_autocmd()
|
|
vim.api.nvim_create_autocmd("BufReadPost", {
|
|
pattern = "*",
|
|
command = 'silent! normal! g`"zv',
|
|
})
|
|
end
|
|
|
|
---@param sidebar_buf integer
|
|
---@param needle string
|
|
---@return integer?
|
|
local function find_line(sidebar_buf, needle)
|
|
for i, l in
|
|
ipairs(vim.api.nvim_buf_get_lines(sidebar_buf, 0, -1, false))
|
|
do
|
|
if l:match(needle) then
|
|
return i
|
|
end
|
|
end
|
|
end
|
|
|
|
---@return integer? sidebar_buf, integer? sidebar_win
|
|
local function find_sidebar()
|
|
local buf, win
|
|
for _, b in ipairs(vim.api.nvim_list_bufs()) do
|
|
if vim.bo[b].filetype == "gitstatus" then
|
|
buf = b
|
|
end
|
|
end
|
|
for _, w in ipairs(vim.api.nvim_list_wins()) do
|
|
if vim.api.nvim_win_get_buf(w) == buf then
|
|
win = w
|
|
end
|
|
end
|
|
return buf, win
|
|
end
|
|
|
|
---@param role string
|
|
---@return integer?
|
|
local function find_diff_win(role)
|
|
for _, w in ipairs(vim.api.nvim_list_wins()) do
|
|
if vim.w[w].git_diff_role == role then
|
|
return w
|
|
end
|
|
end
|
|
end
|
|
|
|
---Set up a repo with one tracked-and-modified file, open the sidebar, and
|
|
---return the sidebar window plus the line of the file's entry.
|
|
---@param file_path string
|
|
---@param committed_content string
|
|
---@param worktree_content string
|
|
---@return integer sidebar_win
|
|
---@return integer entry_line
|
|
local function setup_sidebar_with_unstaged_file(
|
|
file_path,
|
|
committed_content,
|
|
worktree_content
|
|
)
|
|
local repo = h.make_repo({ [file_path] = committed_content })
|
|
h.write(repo, file_path, worktree_content)
|
|
vim.cmd("cd " .. repo)
|
|
|
|
require("git.status_view").open({ placement = "sidebar" })
|
|
local sidebar_buf, sidebar_win = find_sidebar()
|
|
assert(sidebar_buf, "sidebar buffer should exist")
|
|
assert(sidebar_win, "sidebar window should exist")
|
|
|
|
local r = assert(
|
|
require("git.repo").find(vim.fn.getcwd()),
|
|
"repo should resolve for the test worktree"
|
|
)
|
|
r:refresh()
|
|
vim.wait(1000, function()
|
|
return r.status and #r.status:by_kind("unstaged") > 0
|
|
end)
|
|
|
|
local entry_line = assert(
|
|
find_line(sidebar_buf, vim.pesc(file_path) .. "$"),
|
|
file_path .. " should appear in sidebar"
|
|
)
|
|
return sidebar_win, entry_line
|
|
end
|
|
|
|
local function press(keys)
|
|
local rhs = vim.api.nvim_replace_termcodes(keys, true, false, true)
|
|
vim.api.nvim_feedkeys(rhs, "x", false)
|
|
end
|
|
|
|
---@param cond fun(): boolean
|
|
---@param msg string
|
|
local function wait_for(cond, msg)
|
|
h.truthy(vim.wait(1000, cond), "timed out waiting for: " .. msg)
|
|
end
|
|
|
|
h.test(
|
|
"stage with diff open: sidebar cursor stays put",
|
|
function()
|
|
install_cursor_restore_autocmd()
|
|
local sidebar_win, line = setup_sidebar_with_unstaged_file(
|
|
"zsh/rc",
|
|
"ZSH=true\n",
|
|
"ZSH=true\nmodified\n"
|
|
)
|
|
|
|
vim.api.nvim_set_current_win(sidebar_win)
|
|
vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 })
|
|
|
|
press("<Tab>")
|
|
wait_for(function()
|
|
return find_diff_win("left") ~= nil
|
|
end, "diff windows to appear")
|
|
|
|
local r = assert(require("git.repo").find(vim.fn.getcwd()))
|
|
vim.api.nvim_set_current_win(sidebar_win)
|
|
press("s")
|
|
wait_for(function()
|
|
return #r.status:by_kind("staged") > 0
|
|
end, "stage to propagate to repo state")
|
|
|
|
h.eq(
|
|
vim.api.nvim_win_get_cursor(sidebar_win),
|
|
{ line, 0 },
|
|
"sidebar cursor should remain at the entry's original line"
|
|
)
|
|
end
|
|
)
|
|
|
|
h.test(
|
|
"stage with diff open: diff foldmethod is preserved on refresh",
|
|
function()
|
|
local sidebar_win, line = setup_sidebar_with_unstaged_file(
|
|
"zsh/rc",
|
|
"# vim: set ft=zsh nowrap:\nZSH=true\n",
|
|
"# vim: set ft=zsh nowrap:\nZSH=true\nmodified\n"
|
|
)
|
|
|
|
vim.api.nvim_set_current_win(sidebar_win)
|
|
vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 })
|
|
|
|
press("<Tab>")
|
|
wait_for(function()
|
|
return find_diff_win("left") ~= nil
|
|
end, "diff windows to appear")
|
|
local left_win = assert(find_diff_win("left"))
|
|
h.eq(
|
|
vim.wo[left_win].foldmethod,
|
|
"diff",
|
|
"left diff foldmethod should be 'diff' after Tab"
|
|
)
|
|
|
|
local r = assert(require("git.repo").find(vim.fn.getcwd()))
|
|
vim.api.nvim_set_current_win(sidebar_win)
|
|
press("s")
|
|
wait_for(function()
|
|
return #r.status:by_kind("staged") > 0
|
|
end, "stage to propagate to repo state")
|
|
|
|
h.eq(
|
|
vim.wo[left_win].foldmethod,
|
|
"diff",
|
|
"left diff foldmethod should still be 'diff' after stage refresh"
|
|
)
|
|
end
|
|
)
|
|
|
|
h.test("refresh on stage updates the index URI buffer's content", function()
|
|
local sidebar_win, line = setup_sidebar_with_unstaged_file(
|
|
"foo.txt",
|
|
"v1\n",
|
|
"v2\n"
|
|
)
|
|
|
|
vim.api.nvim_set_current_win(sidebar_win)
|
|
vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 })
|
|
press("<Tab>")
|
|
wait_for(function()
|
|
return find_diff_win("left") ~= nil
|
|
end, "diff windows to appear")
|
|
|
|
local left_win = assert(find_diff_win("left"))
|
|
local index_buf = vim.api.nvim_win_get_buf(left_win)
|
|
h.eq(
|
|
vim.api.nvim_buf_get_lines(index_buf, 0, -1, false),
|
|
{ "v1" },
|
|
"index pane should initially show committed content"
|
|
)
|
|
|
|
vim.api.nvim_set_current_win(sidebar_win)
|
|
press("s")
|
|
wait_for(function()
|
|
local first =
|
|
vim.api.nvim_buf_get_lines(index_buf, 0, -1, false)[1]
|
|
return first == "v2"
|
|
end, "index pane to refresh to staged content")
|
|
|
|
h.eq(
|
|
vim.api.nvim_buf_get_lines(index_buf, 0, -1, false),
|
|
{ "v2" },
|
|
"index pane should reflect staged content after refresh"
|
|
)
|
|
end)
|
|
|
|
h.report()
|