local fsmod = require('vimpack.fs') describe('scan', function() it('maps directories to their bucket', function() local root = tmpdir() vim.fn.mkdir(root .. '/start/a/lua', 'p') vim.fn.mkdir(root .. '/opt/b', 'p') vim.fn.writefile({ '' }, root .. '/start/loose.txt') local found = fsmod.scan(root) assert_eq(false, found.a.opt) assert_eq(true, found.b.opt) assert_nil(found['loose.txt']) end) it('returns nothing for a missing root', function() assert_eq({}, fsmod.scan(tmpdir() .. '/absent')) end) end) describe('target_dir', function() it('splits start and opt', function() assert_eq('/r/start/a', fsmod.target_dir({ name = 'a', dir_name = 'a', opt = false }, '/r')) assert_eq('/r/opt/a', fsmod.target_dir({ name = 'a', dir_name = 'a', opt = true }, '/r')) end) end) describe('strip_top_level', function() it('hoists a single wrapper directory', function() local root = tmpdir() vim.fn.mkdir(root .. '/oil.nvim-2.11.0/lua', 'p') assert_eq(root .. '/oil.nvim-2.11.0', fsmod.strip_top_level(root)) end) it('leaves a flat archive alone', function() local root = tmpdir() vim.fn.mkdir(root .. '/lua', 'p') vim.fn.mkdir(root .. '/plugin', 'p') assert_eq(root, fsmod.strip_top_level(root)) end) end) describe('swap', function() it('replaces an existing install', function() local root = tmpdir() vim.fn.mkdir(root .. '/target', 'p') vim.fn.writefile({ 'old' }, root .. '/target/marker') vim.fn.mkdir(root .. '/staged', 'p') vim.fn.writefile({ 'new' }, root .. '/staged/marker') assert_true(fsmod.swap(root .. '/staged', root .. '/target')) assert_eq({ 'new' }, vim.fn.readfile(root .. '/target/marker')) assert_true(not fsmod.exists(root .. '/target.vimpack-old')) end) it('keeps the previous install when the staged tree is missing', function() local root = tmpdir() vim.fn.mkdir(root .. '/target', 'p') vim.fn.writefile({ 'old' }, root .. '/target/marker') local ok, err = fsmod.swap(root .. '/absent', root .. '/target') assert_true(not ok) assert_match('cannot move new install into place', err) assert_eq({ 'old' }, vim.fn.readfile(root .. '/target/marker')) end) end) describe('extract', function() local function wait_extract(archive, dest) local result fsmod.extract(archive, dest, function(ok, err) result = { ok = ok, err = err } end) vim.wait(10000, function() return result ~= nil end) return result end it('unpacks a tarball', function() local root = tmpdir() vim.fn.mkdir(root .. '/src/plug/lua', 'p') vim.fn.writefile({ 'return {}' }, root .. '/src/plug/lua/plug.lua') vim.fn.system({ 'tar', '-czf', root .. '/plug.tar.gz', '-C', root .. '/src', 'plug' }) local result = wait_extract(root .. '/plug.tar.gz', root .. '/dest') assert_true(result.ok, tostring(result.err)) assert_true(fsmod.exists(root .. '/dest/plug/lua/plug.lua')) assert_eq(root .. '/dest/plug', fsmod.strip_top_level(root .. '/dest')) end) it('rejects an unknown archive type', function() local result = wait_extract(tmpdir() .. '/thing.rpm', tmpdir() .. '/dest') assert_true(not result.ok) assert_match('unsupported archive type', result.err) end) it('reports a corrupt tarball', function() local root = tmpdir() vim.fn.writefile({ 'definitely not a tarball' }, root .. '/bad.tar.gz') local result = wait_extract(root .. '/bad.tar.gz', root .. '/dest') assert_true(not result.ok) assert_match('extraction failed', result.err) end) end)