Files
vimpack/tests/minimal.lua
T
unkin-agent 949fe00f6a Validate archive entries and stage inside the pack root
- Reject archive members that are absolute, escape via .., are special files or link outside the destination, before anything is written

- Stage under the pack root so the swap is a same-filesystem rename, with an EXDEV copy fallback; propagate auth errors, validate dir_name
2026-09-05 16:25:49 +10:00

113 lines
3.1 KiB
Lua

-- Minimal busted-flavoured harness: no rocks, no vendored plugins.
-- Run with: nvim --headless --clean -l tests/minimal.lua tests/*_spec.lua
local root = vim.fn.fnamemodify(debug.getinfo(1, 'S').source:sub(2), ':p:h:h')
vim.opt.runtimepath:prepend(root)
package.path = table.concat({ root .. '/lua/?.lua', root .. '/lua/?/init.lua', package.path }, ';')
local M = { passed = 0, failed = 0, failures = {} }
local stack = {}
local function describe(name, fn)
stack[#stack + 1] = name
fn()
stack[#stack] = nil
end
local function it(name, fn)
local label = table.concat(stack, ' ') .. ' ' .. name
local ok, err = pcall(fn)
if ok then
M.passed = M.passed + 1
io.write('ok ' .. label .. '\n')
else
M.failed = M.failed + 1
M.failures[#M.failures + 1] = label .. '\n ' .. tostring(err)
io.write('FAIL ' .. label .. '\n ' .. tostring(err) .. '\n')
end
end
local assert_eq = function(expected, got, msg)
if not vim.deep_equal(expected, got) then
error(
string.format('%sexpected %s, got %s', msg and (msg .. ': ') or '', vim.inspect(expected), vim.inspect(got)),
2
)
end
end
local assert_true = function(value, msg)
if not value then
error(msg or ('expected truthy, got ' .. vim.inspect(value)), 2)
end
end
local assert_nil = function(value, msg)
if value ~= nil then
error(msg or ('expected nil, got ' .. vim.inspect(value)), 2)
end
end
local assert_match = function(pattern, str, msg)
if type(str) ~= 'string' or not str:find(pattern, 1, true) then
error(string.format('%sexpected %s to contain %q', msg and (msg .. ': ') or '', vim.inspect(str), pattern), 2)
end
end
_G.describe = describe
_G.it = it
_G.assert_eq = assert_eq
_G.assert_true = assert_true
_G.assert_nil = assert_nil
_G.assert_match = assert_match
_G.tmpdir = function()
local dir = vim.fs.joinpath(vim.fn.tempname(), 'vimpack-test')
vim.fn.mkdir(dir, 'p')
return dir
end
-- A writable directory on a filesystem other than `reference`, so the EXDEV
-- paths can be exercised for real. nil when the box has no second mount.
_G.otherfs_dir = function(reference)
local uv = vim.uv or vim.loop
local ref = uv.fs_stat(reference)
if not ref then
return nil
end
for _, base in ipairs({ '/dev/shm', '/run/user/' .. tostring(uv.getuid and uv.getuid() or 0), '/var/tmp', '/tmp' }) do
local stat = uv.fs_stat(base)
if stat and stat.dev ~= ref.dev then
local dir = vim.fs.joinpath(base, 'vimpack-xdev-' .. tostring(uv.hrtime()))
if vim.fn.mkdir(dir, 'p') == 1 then
return dir
end
end
end
return nil
end
local files = {}
for i = 1, #_G.arg do
files[#files + 1] = _G.arg[i]
end
if #files == 0 then
for name, kind in vim.fs.dir(root .. '/tests') do
if kind == 'file' and name:match('_spec%.lua$') then
files[#files + 1] = root .. '/tests/' .. name
end
end
table.sort(files)
end
for _, file in ipairs(files) do
dofile(file)
end
io.write(string.format('\n%d passed, %d failed\n', M.passed, M.failed))
if M.failed > 0 then
for _, failure in ipairs(M.failures) do
io.write('\n' .. failure .. '\n')
end
vim.cmd('cquit 1')
end
vim.cmd('quit')