local t = require('tests.harness') local Lock = require('arti-pack.lock') local spec = require('arti-pack.spec') local function tmpdir() local dir = vim.fn.tempname() vim.fn.mkdir(dir, 'p') return dir end local function write(path, contents) local fd = assert(io.open(path, 'w')) fd:write(contents) fd:close() end t.describe('lock', function() t.it('round-trips entries through the state file', function() local path = tmpdir() .. '/nested/lock.json' local lock = Lock.new(path) lock:set('plenary.nvim', { tag = 'v0.1.4', opt = false }) t.truthy(lock:save()) local reloaded = Lock.new(path):load() t.eq({ tag = 'v0.1.4', opt = false }, reloaded:get('plenary.nvim')) end) t.it('starts empty when the state file does not exist', function() local lock = Lock.new(tmpdir() .. '/absent.json'):load() t.eq({}, lock:names()) end) t.it('starts empty when the state file is corrupt', function() local path = tmpdir() .. '/lock.json' write(path, 'not json at all') t.eq({}, Lock.new(path):load():names()) end) t.it('starts empty when the state file has no plugins table', function() local path = tmpdir() .. '/lock.json' write(path, '{"version":1}') t.eq({}, Lock.new(path):load():names()) end) t.it('leaves no temporary file beside the state file', function() local dir = tmpdir() local lock = Lock.new(dir .. '/lock.json') lock:set('plenary.nvim', { tag = 'v0.1.4' }) t.truthy(lock:save()) local names = {} for _, entry in ipairs(vim.fn.readdir(dir)) do table.insert(names, entry) end t.eq({ 'lock.json' }, names) end) t.it('lists names in sorted order', function() local lock = Lock.new(tmpdir() .. '/lock.json') lock:set('zebra', { tag = 'v1' }) lock:set('alpha', { tag = 'v1' }) t.eq({ 'alpha', 'zebra' }, lock:names()) end) t.it('drops removed entries from a saved file', function() local path = tmpdir() .. '/lock.json' local lock = Lock.new(path) lock:set('gone', { tag = 'v1' }) lock:set('kept', { tag = 'v1' }) lock:remove('gone') lock:save() t.eq({ 'kept' }, Lock.new(path):load():names()) end) end) t.describe('lock.is_current', function() local function make(entry) local lock = Lock.new(tmpdir() .. '/lock.json') if entry then lock:set('repo', entry) end return lock end t.it('is false for a plugin that was never installed', function() local s = assert(spec.parse({ 'owner/repo', tag = 'v1' })) t.falsy(make(nil):is_current(s)) end) t.it('is true when the tag and load style both match', function() local s = assert(spec.parse({ 'owner/repo', tag = 'v1' })) t.truthy(make({ tag = 'v1', opt = false }):is_current(s)) end) t.it('is false when the tag changed', function() local s = assert(spec.parse({ 'owner/repo', tag = 'v2' })) t.falsy(make({ tag = 'v1', opt = false }):is_current(s)) end) t.it('is false when the plugin moved between start and opt', function() local s = assert(spec.parse({ 'owner/repo', tag = 'v1', opt = true })) t.falsy(make({ tag = 'v1', opt = false }):is_current(s)) end) end)