local checksum = require('vimpack.checksum') local config = require('vimpack.config') local manifest = require('vimpack.manifest') describe('manifest', function() it('returns an empty manifest for a missing file', function() local data = manifest.read(tmpdir() .. '/nope.json') assert_eq(1, data.version) assert_eq({}, data.plugins) end) it('round-trips through disk', function() local path = tmpdir() .. '/manifest.json' local data = manifest.empty() manifest.set(data, 'oil.nvim', { version = '2.11.0', sha256 = 'abc', opt = false }) assert_true(manifest.write(path, data)) local read_back = manifest.read(path) assert_eq('2.11.0', manifest.get(read_back, 'oil.nvim').version) assert_eq('abc', read_back.plugins['oil.nvim'].sha256) end) it('survives a corrupt file', function() local path = tmpdir() .. '/manifest.json' vim.fn.writefile({ 'not json {' }, path) local data, err = manifest.read(path) assert_eq({}, data.plugins) assert_match('not valid JSON', err) end) it('removes entries', function() local data = manifest.empty() manifest.set(data, 'a', { version = '1' }) manifest.remove(data, 'a') assert_nil(manifest.get(data, 'a')) end) end) describe('sha256', function() local sha256 = require('vimpack.sha256') it('matches the NIST vectors', function() assert_eq('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', sha256.hash('')) assert_eq('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad', sha256.hash('abc')) assert_eq( '248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1', sha256.hash('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq') ) end) it('handles binary data and multi-block input', function() assert_eq( '79eebf0b2aae05b2490234d0b884581935b2e28127f06a74a5b48e758f86bd25', sha256.hash(string.char(0, 1, 2, 255, 0)) ) assert_eq('541b3e9daa09b20bf85fa273e5cbd3e80185aa4ec298e765db87742b70138a53', sha256.hash(string.rep('\0', 1000))) assert_eq('cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0', sha256.hash(string.rep('a', 1000000))) end) end) describe('checksum', function() local function write(contents) local path = tmpdir() .. '/blob.bin' vim.fn.writefile({ contents }, path, 'b') return path end it('passes when the digest matches', function() local path = write('hello vimpack') local digest = assert(checksum.sha256_file(path)) assert_true(checksum.verify(path, digest)) assert_true(checksum.verify(path, digest:upper())) end) it('skips verification when no digest is configured', function() assert_true(checksum.verify(write('x'), nil)) end) it('names expected and got on mismatch', function() local path = write('hello vimpack') local ok, err = checksum.verify(path, string.rep('0', 64)) assert_true(not ok) assert_match('checksum mismatch', err) assert_match(string.rep('0', 64), err) assert_match(assert(checksum.sha256_file(path)), err) end) it('reports an unreadable file', function() local ok, err = checksum.verify(tmpdir() .. '/missing', string.rep('0', 64)) assert_true(not ok) assert_match('checksum', err) end) end) describe('config', function() local reg = { kind = 'template', url_template = 'https://h/${name}-${version}.tar.gz' } it('normalizes strings and defaults', function() local cfg = assert(config.normalize({ registry = reg, plugins = { { name = 'oil.nvim', version = '2.11.0' } }, })) assert_eq(false, cfg.plugins[1].opt) assert_eq('oil.nvim', cfg.plugins[1].dir_name) assert_eq(reg, cfg.plugins[1].registry) end) it('lets a plugin override the registry', function() local other = { kind = 'template', url_template = 'https://other/${name}' } local cfg = assert(config.normalize({ registry = reg, plugins = { { name = 'a', version = '1', registry = other } }, })) assert_eq('https://other/${name}', cfg.plugins[1].registry.url_template) end) it('requires a version unless a url is given', function() local cfg, err = config.normalize({ registry = reg, plugins = { { name = 'a' } } }) assert_nil(cfg) assert_match('version is required', err) assert_true(config.normalize({ plugins = { { name = 'a', url = 'https://h/a.tar.gz' } } }) ~= nil) end) it('rejects duplicates and literal tokens', function() local _, dup = config.normalize({ registry = reg, plugins = { { name = 'a', version = '1' }, { name = 'a', version = '2' } }, }) assert_match('duplicate', dup) local _, tok = config.normalize({ registry = vim.tbl_extend('force', reg, { auth = { token = 'literal' } }), plugins = {}, }) assert_match('literal token', tok) end) it('rejects a plugin with no registry and no url', function() local cfg, err = config.normalize({ plugins = { { name = 'a', version = '1' } } }) assert_nil(cfg) assert_match('no registry', err) end) end)