Files
nvim/test/git/object_test.lua

189 lines
6.6 KiB
Lua

local Revision = require("git.core.revision")
local h = require("test.git.helpers")
local object = require("git.object")
local t = require("test")
---@return integer? buf
local function find_git_buf()
for _, b in ipairs(vim.api.nvim_list_bufs()) do
if vim.api.nvim_buf_get_name(b):match("^git://") then
return b
end
end
end
---@param buf integer
---@param prefix string
---@return integer? lnum
local function find_line(buf, prefix)
for i, l in ipairs(vim.api.nvim_buf_get_lines(buf, 0, -1, false)) do
if l:sub(1, #prefix) == prefix then
return i
end
end
end
t.test("parse_uri / format_uri round-trip for base", function()
local uri = "git://HEAD"
local rev = assert(object.parse_uri(uri))
t.eq(object.format_uri(rev), uri)
end)
t.test("parse_uri / format_uri round-trip for base + path", function()
local uri = "git://HEAD:lua/foo.lua"
local rev = assert(object.parse_uri(uri))
t.eq(object.format_uri(rev), uri)
end)
t.test("parse_uri / format_uri round-trip for stage + path", function()
local uri = "git://:2:lua/foo.lua"
local rev = assert(object.parse_uri(uri))
t.eq(object.format_uri(rev), uri)
end)
t.test("parse_uri normalizes bare :path to stage 0", function()
local rev = assert(object.parse_uri("git://:foo"))
t.eq(rev.stage, 0)
t.eq(rev.path, "foo")
t.eq(object.format_uri(rev), "git://:0:foo")
end)
t.test("parse_uri returns nil for non-git URIs", function()
t.falsy(object.parse_uri("file:///tmp/x"))
t.falsy(object.parse_uri("/tmp/x"))
end)
t.test("M.open(HEAD) names buffer with full sha", function()
local dir = h.make_repo({ a = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
local sha = h.git(dir, "rev-parse", "HEAD").stdout
object.open(r, "HEAD", { split = false })
t.eq(vim.api.nvim_buf_get_name(0), "git://" .. sha)
end)
t.test("M.open(<short sha>) canonicalizes to full sha", function()
local dir = h.make_repo({ a = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
local sha = h.git(dir, "rev-parse", "HEAD").stdout
local short = h.git(dir, "rev-parse", "--short", "HEAD").stdout
t.truthy(#short < #sha, "short sha must be shorter than full")
object.open(r, short, { split = false })
t.eq(vim.api.nvim_buf_get_name(0), "git://" .. sha)
end)
t.test("M.open(HEAD:<path>) loads file content at HEAD", function()
local dir = h.make_repo({ ["a.txt"] = "first\nsecond\n" })
local r = assert(require("git.core.repo").resolve(dir))
local sha = h.git(dir, "rev-parse", "HEAD").stdout
object.open(r, "HEAD:a.txt", { split = false })
t.eq(vim.api.nvim_buf_get_name(0), "git://" .. sha .. ":a.txt")
t.eq(
vim.api.nvim_buf_get_lines(0, 0, -1, false),
{ "first", "second" }
)
end)
t.test("M.open on a merge commit diffs against the first parent only", function()
local dir = h.make_repo({ ["a.txt"] = "one\n" })
t.write(dir, "a.txt", "two\n")
h.git(dir, "stash")
local stash = h.git(dir, "rev-parse", "stash@{0}").stdout
local r = assert(require("git.core.repo").resolve(dir))
object.open(r, stash, { split = false })
local count = 0
for _, l in ipairs(vim.api.nvim_buf_get_lines(0, 0, -1, false)) do
if l:match("^diff %-%-git ") then
count = count + 1
end
end
t.eq(count, 1, "the stashed file's diff appears once, not per-parent")
end)
t.test("M.open errors on a bogus base, no buffer is opened", function()
local dir = h.make_repo({ a = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
t.quietly(function()
object.open(r, "deadbeefdeadbeef", { split = false })
end)
t.falsy(find_git_buf(), "no git:// buffer should exist")
end)
t.test("M.open errors on a missing path, no buffer is opened", function()
local dir = h.make_repo({ a = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
t.quietly(function()
object.open(r, "HEAD:does-not-exist", { split = false })
end)
t.falsy(find_git_buf(), "no git:// buffer should exist")
end)
t.test("read_uri opens stage-0 entry as a writable index buffer", function()
local dir = h.make_repo({ ["a.txt"] = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
local rev = Revision.new({ stage = 0, path = "a.txt" })
local buf = object.buf_for(r, rev)
t.eq(vim.bo[buf].buftype, "acwrite")
t.truthy(vim.bo[buf].modifiable)
t.eq(vim.api.nvim_buf_get_lines(buf, 0, -1, false), { "first" })
end)
t.test("open_under_cursor on a 'tree <sha>' line opens the tree", function()
local dir = h.make_repo({ a = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
local tree_sha = h.git(dir, "rev-parse", "HEAD^{tree}").stdout
object.open(r, "HEAD", { split = false })
local lnum = assert(find_line(0, "tree "), "expected a tree line")
vim.api.nvim_win_set_cursor(0, { lnum, 0 })
t.truthy(object.open_under_cursor())
t.eq(vim.api.nvim_buf_get_name(0), "git://" .. tree_sha)
end)
t.test("open_under_cursor on a 'parent <sha>' line opens the parent", function()
local dir = h.make_repo({ a = "first\n" })
t.write(dir, "a", "second\n")
h.git(dir, "add", "a")
h.git(dir, "commit", "-q", "-m", "second")
local r = assert(require("git.core.repo").resolve(dir))
local parent_sha = h.git(dir, "rev-parse", "HEAD~").stdout
object.open(r, "HEAD", { split = false })
local lnum = assert(find_line(0, "parent "), "expected a parent line")
vim.api.nvim_win_set_cursor(0, { lnum, 0 })
t.truthy(object.open_under_cursor())
t.eq(vim.api.nvim_buf_get_name(0), "git://" .. parent_sha)
end)
t.test("open_under_cursor on a '+++ b/<path>' line loads the blob", function()
local dir = h.make_repo({ ["a.txt"] = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
local blob_sha = h.git(dir, "rev-parse", "HEAD:a.txt").stdout
object.open(r, "HEAD", { split = false })
local lnum = assert(find_line(0, "+++ b/a.txt"), "expected a +++ line")
vim.api.nvim_win_set_cursor(0, { lnum, 0 })
t.truthy(object.open_under_cursor())
t.eq(vim.api.nvim_buf_get_name(0), "git://" .. blob_sha)
end)
t.test("open_under_cursor returns false on a non-dispatchable line", function()
local dir = h.make_repo({ a = "first\n" })
local r = assert(require("git.core.repo").resolve(dir))
object.open(r, "HEAD", { split = false })
local lnum = assert(find_line(0, "author "), "expected an author line")
vim.api.nvim_win_set_cursor(0, { lnum, 0 })
t.falsy(object.open_under_cursor())
end)