diff --git a/test/functional/plugin/pack_spec.lua b/test/functional/plugin/pack_spec.lua index e5fff9c140..0f2e7898dc 100644 --- a/test/functional/plugin/pack_spec.lua +++ b/test/functional/plugin/pack_spec.lua @@ -27,6 +27,13 @@ local function pack_exists(plug_name) return vim.uv.fs_stat(path) ~= nil end +--- Assert content from the main Lua file inside installed plugin. +--- Used as a proxy for checking plugin state on disk. +local function pack_assert_content(plug_name, content) + local full_path = vim.fs.joinpath(pack_get_plug_path(plug_name), 'lua', plug_name .. '.lua') + eq(content, fn.readblob(full_path)) +end + -- Test repos (to be installed) ----------------------------------------------- local repos_dir = vim.fs.abspath('test/functional/lua/pack-test-repos') @@ -251,6 +258,13 @@ end -- Utility -------------------------------------------------------------------- +--- Execute `vim.pack.add()` inside `testnvim` instance +local function vim_pack_add(specs, opts) + exec_lua(function() + vim.pack.add(specs, opts) + end) +end + local function watch_events(event) exec_lua(function() _G.event_log = _G.event_log or {} --- @type table[] @@ -406,15 +420,11 @@ describe('vim.pack', function() describe('add()', function() it('installs only once', function() - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) n.clear() watch_events({ 'PackChanged' }) - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) eq(exec_lua('return #_G.event_log'), 0) -- Should not create redundant stash entry @@ -443,9 +453,7 @@ describe('vim.pack', function() -- Do not confirm installation to see what happens (should not error) mock_confirm(2) - exec_lua(function() - vim.pack.add({ repos_src.basic, { src = repos_src.defbranch, name = 'other-name' } }) - end) + vim_pack_add({ repos_src.basic, { src = repos_src.defbranch, name = 'other-name' } }) eq(false, pack_exists('basic')) eq(false, pack_exists('defbranch')) eq({ plugins = {} }, get_lock_tbl()) @@ -461,9 +469,7 @@ describe('vim.pack', function() -- Should remove lock data if not confirmed during lockfile sync n.clear() - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) eq(true, pack_exists('basic')) eq('table', type(get_lock_tbl().plugins.basic)) @@ -471,9 +477,7 @@ describe('vim.pack', function() n.clear() mock_confirm(2) - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) eq(false, pack_exists('basic')) eq({ plugins = {} }, get_lock_tbl()) @@ -485,9 +489,7 @@ describe('vim.pack', function() it('respects `opts.confirm`', function() mock_confirm(1) - exec_lua(function() - vim.pack.add({ repos_src.basic }, { confirm = false }) - end) + vim_pack_add({ repos_src.basic }, { confirm = false }) eq(0, exec_lua('return #_G.confirm_log')) eq(true, pack_exists('basic')) @@ -499,9 +501,7 @@ describe('vim.pack', function() n.clear() mock_confirm(1) - exec_lua(function() - vim.pack.add({}, { confirm = false }) - end) + vim_pack_add({}, { confirm = false }) eq(0, exec_lua('return #_G.confirm_log')) eq(true, pack_exists('basic')) end) @@ -509,24 +509,18 @@ describe('vim.pack', function() it('can always confirm in current session', function() mock_confirm(3) - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) eq(1, exec_lua('return #_G.confirm_log')) eq('basic main', exec_lua('return require("basic")')) - exec_lua(function() - vim.pack.add({ repos_src.defbranch }) - end) + vim_pack_add({ repos_src.defbranch }) eq(1, exec_lua('return #_G.confirm_log')) eq('defbranch dev', exec_lua('return require("defbranch")')) -- Should still ask in next session n.clear() mock_confirm(3) - exec_lua(function() - vim.pack.add({ repos_src.plugindirs }) - end) + vim_pack_add({ repos_src.plugindirs }) eq(1, exec_lua('return #_G.confirm_log')) eq('plugindirs main', exec_lua('return require("plugindirs")')) end) @@ -597,9 +591,7 @@ describe('vim.pack', function() end) it('updates lockfile', function() - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) local ref_lockfile = { plugins = { basic = { rev = git_get_hash('main', 'basic'), src = repos_src.basic }, @@ -608,21 +600,14 @@ describe('vim.pack', function() eq(ref_lockfile, get_lock_tbl()) n.clear() - exec_lua(function() - vim.pack.add({ { src = repos_src.basic, version = 'main' } }) - end) + vim_pack_add({ { src = repos_src.basic, version = 'main' } }) ref_lockfile.plugins.basic.version = "'main'" eq(ref_lockfile, get_lock_tbl()) end) it('uses lockfile during install', function() - exec_lua(function() - vim.pack.add({ - { src = repos_src.basic, version = 'feat-branch' }, - repos_src.defbranch, - }) - end) + vim_pack_add({ { src = repos_src.basic, version = 'feat-branch' }, repos_src.defbranch }) -- Mock clean initial install, but with lockfile present vim.fs.rm(pack_get_dir(), { force = true, recursive = true }) @@ -639,13 +624,10 @@ describe('vim.pack', function() eq(ref_lockfile, get_lock_tbl()) mock_confirm(1) - exec_lua(function() - -- Should use revision from lockfile (pointing at latest 'feat-branch' - -- commit) and not use latest `main` commit - vim.pack.add({ { src = repos_src.basic, version = 'main' } }) - end) - local basic_lua_file = vim.fs.joinpath(pack_get_plug_path('basic'), 'lua', 'basic.lua') - eq('return "basic feat-branch"', fn.readblob(basic_lua_file)) + -- Should use revision from lockfile (pointing at latest 'feat-branch' + -- commit) and not use latest `main` commit + vim_pack_add({ { src = repos_src.basic, version = 'main' } }) + pack_assert_content('basic', 'return "basic feat-branch"') local confirm_log = exec_lua('return _G.confirm_log') eq(1, #confirm_log) @@ -659,7 +641,7 @@ describe('vim.pack', function() exec_lua(function() vim.pack.update({ 'basic' }, { force = true }) end) - eq('return "basic main"', fn.readblob(basic_lua_file)) + pack_assert_content('basic', 'return "basic main"') ref_lockfile.plugins.basic.rev = git_get_hash('main', 'basic') ref_lockfile.plugins.basic.version = "'main'" @@ -689,12 +671,10 @@ describe('vim.pack', function() end) it('regenerates manually deleted lockfile', function() - exec_lua(function() - vim.pack.add({ - { src = repos_src.basic, name = 'other', version = 'feat-branch' }, - repos_src.defbranch, - }) - end) + vim_pack_add({ + { src = repos_src.basic, name = 'other', version = 'feat-branch' }, + repos_src.defbranch, + }) local lock_path = get_lock_path() eq(true, vim.uv.fs_stat(lock_path) ~= nil) @@ -704,9 +684,7 @@ describe('vim.pack', function() -- Should try its best to regenerate lockfile based on installed plugins fn.delete(get_lock_path()) n.clear() - exec_lua(function() - vim.pack.add({}) - end) + vim_pack_add({}) local ref_lockfile = { plugins = { -- No `version = 'feat-branch'` as there is no way to get that info @@ -721,27 +699,23 @@ describe('vim.pack', function() eq(ref_messages, n.exec_capture('messages')) -- Calling `add()` with `version` should still add it to lockfile - exec_lua(function() - vim.pack.add({ { src = repos_src.basic, name = 'other', version = 'feat-branch' } }) - end) + vim_pack_add({ { src = repos_src.basic, name = 'other', version = 'feat-branch' } }) eq("'feat-branch'", get_lock_tbl().plugins.other.version) end) it('repairs corrupted lock data for installed plugins', function() - exec_lua(function() - vim.pack.add({ - -- Should preserve present `version` - { src = repos_src.basic, version = 'feat-branch' }, - repos_src.defbranch, - repos_src.semver, - repos_src.helptags, - }) - end) + vim_pack_add({ + -- Should preserve present `version` + { src = repos_src.basic, version = 'feat-branch' }, + repos_src.defbranch, + repos_src.semver, + repos_src.helptags, + }) local lock_tbl = get_lock_tbl() local ref_lock_tbl = vim.deepcopy(lock_tbl) local assert = function() - exec_lua('vim.pack.add({})') + vim_pack_add({}) eq(ref_lock_tbl, get_lock_tbl()) eq(true, pack_exists('basic')) eq(true, pack_exists('defbranch')) @@ -777,9 +751,7 @@ describe('vim.pack', function() end) it('removes unrepairable corrupted data and plugins', function() - exec_lua(function() - vim.pack.add({ repos_src.basic, repos_src.defbranch, repos_src.semver, repos_src.helptags }) - end) + vim_pack_add({ repos_src.basic, repos_src.defbranch, repos_src.semver, repos_src.helptags }) local lock_tbl = get_lock_tbl() local ref_lock_tbl = vim.deepcopy(lock_tbl) @@ -803,7 +775,7 @@ describe('vim.pack', function() fn.writefile(vim.split(lockfile_text, '\n'), get_lock_path()) n.clear() - exec_lua('vim.pack.add({})') + vim_pack_add({}) ref_lock_tbl.plugins.basic = nil ref_lock_tbl.plugins.defbranch = nil ref_lock_tbl.plugins.semver = nil @@ -817,10 +789,8 @@ describe('vim.pack', function() it('installs at proper version', function() local out = exec_lua(function() - vim.pack.add({ - { src = repos_src.basic, version = 'feat-branch' }, - }) - -- Should have plugin available immediately after + vim.pack.add({ { src = repos_src.basic, version = 'feat-branch' } }) + -- Should have plugin available immediately (not even on the next loop) return require('basic') end) @@ -836,9 +806,7 @@ describe('vim.pack', function() it('installs with submodules', function() mock_git_file_transport() - exec_lua(function() - vim.pack.add({ repos_src.with_subs }) - end) + vim_pack_add({ repos_src.with_subs }) local sub_lua_file = vim.fs.joinpath(pack_get_plug_path('with_subs'), 'sub', 'sub.lua') eq('return "sub main"', fn.readblob(sub_lua_file)) @@ -854,9 +822,7 @@ describe('vim.pack', function() it('can install from the Internet', function() t.skip(skip_integ, 'NVIM_TEST_INTEG not set: skipping network integration test') - exec_lua(function() - vim.pack.add({ 'https://github.com/neovim/nvim-lspconfig' }) - end) + vim_pack_add({ 'https://github.com/neovim/nvim-lspconfig' }) eq(true, exec_lua('return pcall(require, "lspconfig")')) end) @@ -885,8 +851,9 @@ describe('vim.pack', function() local function assert_works() -- Should auto-install but wait before executing code after it n.clear({ args_rm = { '-u' } }) - vim.uv.sleep(2000) - eq(true, exec_lua('return _G.done')) + t.retry(nil, 2000, function() + eq(true, exec_lua('return _G.done')) + end) assert_loaded() -- Should only `:packadd!`/`:packadd` already installed plugin @@ -916,19 +883,15 @@ describe('vim.pack', function() it('shows progress report during installation', function() track_nvim_echo() - exec_lua(function() - vim.pack.add({ repos_src.basic, repos_src.defbranch }) - end) + vim_pack_add({ repos_src.basic, repos_src.defbranch }) assert_progress_report('Installing plugins', { 'basic', 'defbranch' }) end) it('triggers relevant events', function() watch_events({ 'PackChangedPre', 'PackChanged' }) - exec_lua(function() - -- Should provide event-data respecting manual `version` without inferring default - vim.pack.add({ { src = repos_src.basic, version = 'feat-branch' }, repos_src.defbranch }) - end) + -- Should provide event-data respecting manual `version` without inferring default + vim_pack_add({ { src = repos_src.basic, version = 'feat-branch' }, repos_src.defbranch }) local log = exec_lua('return _G.event_log') local find_event = make_find_packchanged(log) @@ -960,10 +923,9 @@ describe('vim.pack', function() it('respects plugin/ and after/plugin/ scripts', function() local function assert(load, ref) - local opts = { load = load } + vim_pack_add({ { src = repos_src.plugindirs, name = 'plugin % dirs' } }, { load = load }) + -- Should handle bad plugin directory name local out = exec_lua(function() - -- Should handle bad plugin directory name - vim.pack.add({ { src = repos_src.plugindirs, name = 'plugin % dirs' } }, opts) return { vim.g._plugin, vim.g._plugin_vim, @@ -975,7 +937,6 @@ describe('vim.pack', function() vim.g._after_plugin_bad, } end) - eq(ref, out) -- Should add necessary directories to runtimepath regardless of `opts.load` @@ -1036,9 +997,7 @@ describe('vim.pack', function() end) it('generates help tags', function() - exec_lua(function() - vim.pack.add({ { src = repos_src.helptags, name = 'help tags' } }) - end) + vim_pack_add({ { src = repos_src.helptags, name = 'help tags' } }) local target_tags = fn.getcompletion('my-test', 'help') table.sort(target_tags) eq({ 'my-test-help', 'my-test-help-bad', 'my-test-help-sub-bad' }, target_tags) @@ -1090,14 +1049,12 @@ describe('vim.pack', function() end) it('normalizes each spec', function() - exec_lua(function() - vim.pack.add({ - repos_src.basic, -- String should be inferred as `{ src = ... }` - { src = repos_src.defbranch }, -- Default `version` is remote's default branch - { src = repos_src['gitsuffix.git'] }, -- Default `name` comes from `src` repo name - { src = repos_src.plugindirs, name = 'plugin/dirs' }, -- Ensure proper directory name - }) - end) + vim_pack_add({ + repos_src.basic, -- String should be inferred as `{ src = ... }` + { src = repos_src.defbranch }, -- Default `version` is remote's default branch + { src = repos_src['gitsuffix.git'] }, -- Default `name` comes from `src` repo name + { src = repos_src.plugindirs, name = 'plugin/dirs' }, -- Ensure proper directory name + }) eq('basic main', exec_lua('return require("basic")')) eq('defbranch dev', exec_lua('return require("defbranch")')) @@ -1109,9 +1066,7 @@ describe('vim.pack', function() end) it('handles problematic names', function() - exec_lua(function() - vim.pack.add({ { src = repos_src.basic, name = 'bad % name' } }) - end) + vim_pack_add({ { src = repos_src.basic, name = 'bad % name' } }) eq('basic main', exec_lua('return require("basic")')) end) @@ -1120,9 +1075,7 @@ describe('vim.pack', function() fn.setenv('GIT_DIR', vim.fs.joinpath(fn.getcwd(), '.git')) local ref_environ = fn.environ() - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) eq('basic main', exec_lua('return require("basic")')) eq(ref_environ, fn.environ()) @@ -1164,8 +1117,6 @@ describe('vim.pack', function() end) describe('update()', function() - -- Lua source code for the tested plugin named "fetch" - local fetch_lua_file -- Tables with hashes used to test confirmation buffer and log content local hashes --- @type table local short_hashes --- @type table @@ -1180,18 +1131,15 @@ describe('vim.pack', function() repo_write_file('fetch', 'lua/fetch.lua', 'return "fetch main"') git_add_commit('Commit from `main` to be removed', 'fetch') - fetch_lua_file = vim.fs.joinpath(pack_get_plug_path('fetch'), 'lua', 'fetch.lua') hashes = { fetch_head = git_get_hash('HEAD', 'fetch') } short_hashes = { fetch_head = git_get_short_hash('HEAD', 'fetch') } -- Install initial versions of tested plugins - exec_lua(function() - vim.pack.add({ - { src = repos_src.fetch, version = 'main' }, - { src = repos_src.semver, version = 'v0.3.0' }, - repos_src.defbranch, - }) - end) + vim_pack_add({ + { src = repos_src.fetch, version = 'main' }, + { src = repos_src.semver, version = 'v0.3.0' }, + repos_src.defbranch, + }) n.clear() -- Mock remote repo update @@ -1220,14 +1168,12 @@ describe('vim.pack', function() describe('confirmation buffer', function() it('works', function() - exec_lua(function() - vim.pack.add({ - repos_src.fetch, - { src = repos_src.semver, version = 'v0.3.0' }, - { src = repos_src.defbranch, version = 'does-not-exist' }, - }) - end) - eq('return "fetch main"', fn.readblob(fetch_lua_file)) + vim_pack_add({ + repos_src.fetch, + { src = repos_src.semver, version = 'v0.3.0' }, + { src = repos_src.defbranch, version = 'does-not-exist' }, + }) + pack_assert_content('fetch', 'return "fetch main"') exec_lua(function() -- Enable highlighting of special filetype @@ -1269,9 +1215,8 @@ describe('vim.pack', function() local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) -- NOTE: replace path to `vim.pack` in error traceback accounting for -- pcall source truncation and possibly different slashes on Windows - local pack_runtime_pattern = ('%%S.+%s:%%d+'):format( - vim.pesc(pack_runtime):gsub('/', '[\\/]') - ) + local pack_runtime_pesc = vim.pesc(pack_runtime):gsub('/', '[\\/]') + local pack_runtime_pattern = ('%%S.+%s:%%d+'):format(pack_runtime_pesc) for i = 1, #lines do replace_in_line(i, pack_runtime_pattern, 'VIM_PACK_RUNTIME') replace_in_line(i, vim.pesc(fetch_path), 'FETCH_PATH') @@ -1296,54 +1241,52 @@ describe('vim.pack', function() local tab_name = 'n' .. (t.is_os('win') and ':' or '') .. '//confirm#2' - local screen_lines = { - ('{24: [No Name] }{5: %s }{2:%s }{24:X}|'):format( - tab_name, - t.is_os('win') and '' or ' ' - ), - '{19:^# Error ────────────────────────────────────────────────────────────────────────} |', - ' |', - '{19:## defbranch} |', - ' |', - ' VIM_PACK_RUNTIME: `does-not-exist` is not a branch/tag/commit. Available: |', - ' Tags: |', - ' Branches: dev, main |', - ' |', - '{101:# Update ───────────────────────────────────────────────────────────────────────} |', - ' |', - '{101:## fetch} |', - 'Path: {103:FETCH_PATH} |', - 'Source: {103:FETCH_SRC} |', - ('Revision before: {103:%s} |'):format(hashes.fetch_head), - ('Revision after: {103:%s} {102:(main)} |'):format(hashes.fetch_new), - ' |', - 'Pending updates: |', - ('{19:< %s │ Commit from `main` to be removed} |'):format( - short_hashes.fetch_head - ), - ('{104:> %s │ Commit to be added 2} |'):format( - short_hashes.fetch_new - ), - ('{104:> %s │ Commit to be added 1 (tag: dev-tag)} |'):format( - short_hashes.fetch_new_prev - ), - ' |', - '{102:# Same ─────────────────────────────────────────────────────────────────────────} |', - ' |', - '{102:## semver} |', - 'Path: {103:SEMVER_PATH} |', - 'Source: {103:SEMVER_SRC} |', - ('Revision: {103:%s} {102:(v0.3.0)} |'):format( - hashes.semver_head - ), - ' |', - 'Available newer versions: |', - '• {102:v1.0.0} |', - '• {102:v0.4} |', - '• {102:0.3.1} |', - '{1:~ }|', - ' |', - } + local ref_screen_lines = ([[ + {24: [No Name] }{5: %s }{2:%s }{24:X}| + {19:^# Error ────────────────────────────────────────────────────────────────────────} | + | + {19:## defbranch} | + | + VIM_PACK_RUNTIME: `does-not-exist` is not a branch/tag/commit. Available: | + Tags: | + Branches: dev, main | + | + {101:# Update ───────────────────────────────────────────────────────────────────────} | + | + {101:## fetch} | + Path: {103:FETCH_PATH} | + Source: {103:FETCH_SRC} | + Revision before: {103:%s} | + Revision after: {103:%s} {102:(main)} | + | + Pending updates: | + {19:< %s │ Commit from `main` to be removed} | + {104:> %s │ Commit to be added 2} | + {104:> %s │ Commit to be added 1 (tag: dev-tag)} | + | + {102:# Same ─────────────────────────────────────────────────────────────────────────} | + | + {102:## semver} | + Path: {103:SEMVER_PATH} | + Source: {103:SEMVER_SRC} | + Revision: {103:%s} {102:(v0.3.0)} | + | + Available newer versions: | + • {102:v1.0.0} | + • {102:v0.4} | + • {102:0.3.1} | + {1:~ }| + | + ]]):format( + tab_name, + t.is_os('win') and '' or ' ', + hashes.fetch_head, + hashes.fetch_new, + short_hashes.fetch_head, + short_hashes.fetch_new, + short_hashes.fetch_new_prev, + hashes.semver_head + ) screen:add_extra_attr_ids({ [101] = { foreground = Screen.colors.Orange }, @@ -1353,14 +1296,15 @@ describe('vim.pack', function() }) -- NOTE: Non LuaJIT reports errors differently due to 'coxpcall' if is_jit() then - screen:expect(table.concat(screen_lines, '\n')) + local ref_screen = vim.text.indent(0, ref_screen_lines) + screen:expect(ref_screen) end -- `:write` should confirm n.exec('write') -- - Apply changes immediately - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') -- - Clean up buffer+window+tabpage eq(false, api.nvim_buf_is_valid(confirm_bufnr)) @@ -1397,22 +1341,18 @@ describe('vim.pack', function() end) it('can be dismissed with `:quit`', function() - exec_lua(function() - vim.pack.add({ repos_src.fetch }) - vim.pack.update({ 'fetch' }) - end) + vim_pack_add({ repos_src.fetch }) + exec_lua('vim.pack.update({ "fetch" })') eq('nvim-pack', api.nvim_get_option_value('filetype', {})) -- Should not apply updates n.exec('quit') - eq('return "fetch main"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch main"') end) it('closes full tabpage', function() - exec_lua(function() - vim.pack.add({ repos_src.fetch }) - vim.pack.update() - end) + vim_pack_add({ repos_src.fetch }) + exec_lua('vim.pack.update()') -- Confirm with `:write` local confirm_tabpage = api.nvim_get_current_tabpage() @@ -1444,14 +1384,12 @@ describe('vim.pack', function() it('has in-process LSP features', function() t.skip(not is_jit(), "Non LuaJIT reports errors differently due to 'coxpcall'") track_nvim_echo() - exec_lua(function() - vim.pack.add({ - repos_src.fetch, - -- No `semver` to test with non-active plugins - { src = repos_src.defbranch, version = 'does-not-exist' }, - }) - vim.pack.update() - end) + vim_pack_add({ + repos_src.fetch, + -- No `semver` to test with non-active plugins + { src = repos_src.defbranch, version = 'does-not-exist' }, + }) + exec_lua('vim.pack.update()') eq(1, exec_lua('return #vim.lsp.get_clients({ bufnr = 0 })')) @@ -1590,7 +1528,7 @@ describe('vim.pack', function() -- - Skip udating assert_action({ 11, 0 }, fetch_actions, 2) - eq('return "fetch main"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch main"') line_match(9, '^# Update') line_match(10, '^$') line_match(11, '^# Same') @@ -1608,7 +1546,7 @@ describe('vim.pack', function() assert_action({ 3, 0 }, fetch_actions, 1) - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') assert_progress_report('Applying updates', { 'fetch' }) line_match(1, '^# Update') eq(1, api.nvim_buf_line_count(0)) @@ -1623,16 +1561,14 @@ describe('vim.pack', function() it('has buffer-local mappings', function() t.skip(not is_jit(), "Non LuaJIT reports update errors differently due to 'coxpcall'") - exec_lua(function() - vim.pack.add({ - repos_src.fetch, - { src = repos_src.semver, version = 'v0.3.0' }, - { src = repos_src.defbranch, version = 'does-not-exist' }, - }) - -- Enable sourcing filetype script (that creates mappings) - vim.cmd('filetype plugin on') - vim.pack.update() - end) + vim_pack_add({ + repos_src.fetch, + { src = repos_src.semver, version = 'v0.3.0' }, + { src = repos_src.defbranch, version = 'does-not-exist' }, + }) + -- Enable sourcing filetype script (that creates mappings) + n.exec('filetype plugin on') + exec_lua('vim.pack.update()') -- Plugin sections navigation local function assert(keys, ref_cursor) @@ -1657,12 +1593,11 @@ describe('vim.pack', function() it('suggests newer versions when on non-tagged commit', function() local commit = git_get_hash('0.3.1~', 'semver') - exec_lua(function() - -- Make fresh install for cleaner test - vim.pack.del({ 'semver' }) - vim.pack.add({ { src = repos_src.semver, version = commit } }) - vim.pack.update({ 'semver' }) - end) + + -- Make fresh install for cleaner test + exec_lua('vim.pack.del({ "semver" })') + vim_pack_add({ { src = repos_src.semver, version = commit } }) + exec_lua('vim.pack.update({ "semver" })') -- Should correctly infer that 0.3.0 is the latest version and suggest -- versions greater than that @@ -1671,9 +1606,7 @@ describe('vim.pack', function() end) it('updates lockfile', function() - exec_lua(function() - vim.pack.add({ repos_src.fetch }) - end) + vim_pack_add({ repos_src.fetch }) local ref_fetch_lock = { rev = hashes.fetch_head, src = repos_src.fetch } eq(ref_fetch_lock, get_lock_tbl().plugins.fetch) @@ -1714,40 +1647,34 @@ describe('vim.pack', function() -- By default should also include not active plugins vim.pack.update() end) - eq('return "fetch main"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch main"') n.exec('write') - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') end) it('works with submodules', function() mock_git_file_transport() - exec_lua(function() - vim.pack.add({ { src = repos_src.with_subs, version = 'init-commit' } }) - end) + vim_pack_add({ { src = repos_src.with_subs, version = 'init-commit' } }) local sub_lua_file = vim.fs.joinpath(pack_get_plug_path('with_subs'), 'sub', 'sub.lua') eq('return "sub init"', fn.readblob(sub_lua_file)) n.clear() mock_git_file_transport() - exec_lua(function() - vim.pack.add({ repos_src.with_subs }) - vim.pack.update({ 'with_subs' }) - end) + vim_pack_add({ repos_src.with_subs }) + exec_lua('vim.pack.update({ "with_subs" })') n.exec('write') eq('return "sub main"', fn.readblob(sub_lua_file)) end) it('can force update', function() - exec_lua(function() - vim.pack.add({ repos_src.fetch }) - vim.pack.update({ 'fetch' }, { force = true }) - end) + vim_pack_add({ repos_src.fetch }) + exec_lua('vim.pack.update({ "fetch" }, { force = true })') -- Apply changes immediately local fetch_src = repos_src.fetch local fetch_path = pack_get_plug_path('fetch') - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') -- No special buffer/window/tabpage eq(1, #api.nvim_list_tabpages()) @@ -1791,10 +1718,8 @@ describe('vim.pack', function() end) it('can use lockfile revision as a target', function() - exec_lua(function() - vim.pack.add({ repos_src.fetch }) - end) - eq('return "fetch main"', fn.readblob(fetch_lua_file)) + vim_pack_add({ repos_src.fetch }) + pack_assert_content('fetch', 'return "fetch main"') -- Mock "update -> revert lockfile -> revert plugin" local lock_path = get_lock_path() @@ -1803,18 +1728,18 @@ describe('vim.pack', function() -- - Update exec_lua('vim.pack.update({ "fetch" }, { force = true })') - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') -- - Revert lockfile fn.writefile(vim.split(lockfile_before, '\n'), lock_path) n.clear() -- - Revert plugin - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') exec_lua('vim.pack.update({ "fetch" }, { target = "lockfile" })') local confirm_lines = api.nvim_buf_get_lines(0, 0, -1, false) n.exec('write') - eq('return "fetch main"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch main"') eq(hashes.fetch_head, get_lock_tbl().plugins.fetch.rev) -- - Should mention that new revision comes from *lockfile* @@ -1825,9 +1750,7 @@ describe('vim.pack', function() it('can change `src` of installed plugin', function() local basic_src = repos_src.basic local defbranch_src = repos_src.defbranch - exec_lua(function() - vim.pack.add({ basic_src }) - end) + vim_pack_add({ basic_src }) local function assert_origin(ref) -- Should be in sync both on disk and in lockfile @@ -1842,9 +1765,7 @@ describe('vim.pack', function() watch_events({ 'PackChangedPre', 'PackChanged' }) assert_origin(basic_src) - exec_lua(function() - vim.pack.add({ { src = defbranch_src, name = 'basic' } }) - end) + vim_pack_add({ { src = defbranch_src, name = 'basic' } }) -- Should not yet (after `add()`) affect plugin source assert_origin(basic_src) @@ -1861,24 +1782,16 @@ describe('vim.pack', function() -- Should work with forced update n.clear() - exec_lua(function() - vim.pack.add({ basic_src }) - vim.pack.update({ 'basic' }, { force = true }) - end) + vim_pack_add({ basic_src }) + exec_lua('vim.pack.update({ "basic" }, { force = true })') assert_origin(basic_src) end) it('can do offline update', function() - local defbranch_path = pack_get_plug_path('defbranch') - local defbranch_lua_file = vim.fs.joinpath(defbranch_path, 'lua', 'defbranch.lua') - - n.exec_lua(function() - vim.pack.add({ { src = repos_src.defbranch, version = 'main' } }) - end) - + vim_pack_add({ { src = repos_src.defbranch, version = 'main' } }) track_nvim_echo() - eq('return "defbranch dev"', fn.readblob(defbranch_lua_file)) + pack_assert_content('defbranch', 'return "defbranch dev"') n.exec_lua(function() vim.pack.update({ 'defbranch' }, { offline = true }) end) @@ -1887,16 +1800,14 @@ describe('vim.pack', function() assert_progress_report('Computing updates', { 'defbranch' }) n.exec('write') - eq('return "defbranch main"', fn.readblob(defbranch_lua_file)) + pack_assert_content('defbranch', 'return "defbranch main"') end) it('shows progress report', function() track_nvim_echo() - exec_lua(function() - vim.pack.add({ repos_src.fetch, repos_src.defbranch }) - -- Should also include updates from not active plugins - vim.pack.update() - end) + vim_pack_add({ repos_src.fetch, repos_src.defbranch }) + -- Should also include updates from not active plugins + exec_lua('vim.pack.update()') -- During initial download assert_progress_report('Downloading updates', { 'fetch', 'defbranch', 'semver' }) @@ -1912,20 +1823,16 @@ describe('vim.pack', function() repo_write_file('fetch', 'lua/fetch.lua', 'return "fetch new 3"') git_add_commit('Commit to be added 3', 'fetch') - exec_lua(function() - vim.pack.add({ repos_src.fetch, repos_src.defbranch }) - vim.pack.update(nil, { force = true }) - end) + vim_pack_add({ repos_src.fetch, repos_src.defbranch }) + exec_lua('vim.pack.update(nil, { force = true })') assert_progress_report('Updating', { 'fetch', 'defbranch', 'semver' }) end) it('triggers relevant events', function() watch_events({ 'PackChangedPre', 'PackChanged' }) - exec_lua(function() - vim.pack.add({ repos_src.fetch, repos_src.defbranch }) - _G.event_log = {} - vim.pack.update() - end) + vim_pack_add({ repos_src.fetch, repos_src.defbranch }) + exec_lua('_G.event_log = {}') + exec_lua('vim.pack.update()') eq({}, exec_lua('return _G.event_log')) -- Should trigger relevant events only for actually updated plugins @@ -1938,19 +1845,19 @@ describe('vim.pack', function() end) it('stashes before applying changes', function() + local fetch_lua_file = vim.fs.joinpath(pack_get_plug_path('fetch'), 'lua', 'fetch.lua') fn.writefile({ 'A text that will be stashed' }, fetch_lua_file) - exec_lua(function() - vim.pack.add({ repos_src.fetch }) - vim.pack.update() - vim.cmd('write') - end) + + vim_pack_add({ repos_src.fetch }) + exec_lua('vim.pack.update()') + n.exec('write') local fetch_path = pack_get_plug_path('fetch') local stash_list = system_sync({ 'git', 'stash', 'list' }, { cwd = fetch_path }).stdout or '' matches('vim%.pack: %d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d Stash before checkout', stash_list) -- Update should still be applied - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') end) it('is not affected by special environment variables', function() @@ -1958,11 +1865,9 @@ describe('vim.pack', function() fn.setenv('GIT_DIR', vim.fs.joinpath(fn.getcwd(), '.git')) local ref_environ = fn.environ() - exec_lua(function() - vim.pack.add({ repos_src.fetch }) - vim.pack.update({ 'fetch' }, { force = true }) - end) - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + vim_pack_add({ repos_src.fetch }) + exec_lua('vim.pack.update({ "fetch" }, { force = true })') + pack_assert_content('fetch', 'return "fetch new 2"') eq(ref_environ, fn.environ()) end) @@ -1977,7 +1882,7 @@ describe('vim.pack', function() end) eq(1, exec_lua('return #_G.confirm_log')) -- - Should checkout `version='main'` as it says in the lockfile - eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch new 2"') -- Should regenerate absent lockfile (from present plugins) vim.fs.rm(get_lock_path()) @@ -1990,7 +1895,7 @@ describe('vim.pack', function() -- - Should checkout default branch since `version='main'` info is lost -- after lockfile is deleted. eq(nil, lock_plugins.fetch.version) - eq('return "fetch dev"', fn.readblob(fetch_lua_file)) + pack_assert_content('fetch', 'return "fetch dev"') end) it('validates input', function() @@ -2005,9 +1910,7 @@ describe('vim.pack', function() -- Should first check if every plugin name represents installed plugin -- If not - stop early before any update - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) assert('Plugin `ccc` is not installed', { 'ccc', 'basic', 'aaa' }) @@ -2077,13 +1980,11 @@ describe('vim.pack', function() -- Should also list non-active plugins n.clear() - - exec_lua(function() - vim.pack.add({ repos_src.defbranch }) - end) + vim_pack_add({ repos_src.defbranch }) defbranch_data = make_defbranch_data(true, true) basic_data = make_basic_data(false, true) plugindirs_data = make_plugindirs_data(false, true) + -- Should first list active, then non-active (including their latest -- set `version` which is inferred from lockfile) eq({ defbranch_data, basic_data, plugindirs_data }, exec_lua('return vim.pack.get()')) @@ -2109,11 +2010,11 @@ describe('vim.pack', function() end) it('respects `data` field', function() + vim_pack_add({ + { src = repos_src.basic, version = 'feat-branch', data = { test = 'value' } }, + { src = repos_src.defbranch, data = 'value' }, + }) local out = exec_lua(function() - vim.pack.add({ - { src = repos_src.basic, version = 'feat-branch', data = { test = 'value' } }, - { src = repos_src.defbranch, data = 'value' }, - }) local plugs = vim.pack.get() ---@type table return { basic = plugs[1].spec.data.test, defbranch = plugs[2].spec.data } @@ -2122,9 +2023,7 @@ describe('vim.pack', function() end) it('works with `del()`', function() - exec_lua(function() - vim.pack.add({ repos_src.defbranch, { src = repos_src.basic, version = 'feat-branch' } }) - end) + vim_pack_add({ repos_src.defbranch, { src = repos_src.basic, version = 'feat-branch' } }) exec_lua(function() _G.get_log = {} @@ -2144,11 +2043,8 @@ describe('vim.pack', function() end) it('works with out of sync lockfile', function() - exec_lua(function() - vim.pack.add({ repos_src.basic, repos_src.defbranch }) - end) + vim_pack_add({ repos_src.basic, repos_src.defbranch }) eq(2, vim.tbl_count(get_lock_tbl().plugins)) - local basic_lua_file = vim.fs.joinpath(pack_get_plug_path('basic'), 'lua', 'basic.lua') -- Should first autoinstall missing plugin (with confirmation) vim.fs.rm(pack_get_plug_path('basic'), { force = true, recursive = true }) @@ -2157,7 +2053,7 @@ describe('vim.pack', function() eq(2, exec_lua('return #vim.pack.get()')) eq(1, exec_lua('return #_G.confirm_log')) - eq('return "basic main"', fn.readblob(basic_lua_file)) + pack_assert_content('basic', 'return "basic main"') -- Should regenerate absent lockfile (from present plugins) vim.fs.rm(get_lock_path()) @@ -2169,10 +2065,8 @@ describe('vim.pack', function() describe('del()', function() it('works', function() - exec_lua(function() - local basic_spec = { src = repos_src.basic, version = 'feat-branch' } - vim.pack.add({ repos_src.plugindirs, repos_src.defbranch, basic_spec }) - end) + local basic_spec = { src = repos_src.basic, version = 'feat-branch' } + vim_pack_add({ repos_src.plugindirs, repos_src.defbranch, basic_spec }) local assert_on_disk = function(installed_map) local installed = {} @@ -2194,9 +2088,7 @@ describe('vim.pack', function() -- By default should delete only non-active plugins, even if -- there is active one among input plugin names n.clear() - exec_lua(function() - vim.pack.add({ repos_src.defbranch }) - end) + vim_pack_add({ repos_src.defbranch }) watch_events({ 'PackChangedPre', 'PackChanged' }) local err = pcall_err(exec_lua, function() @@ -2237,9 +2129,7 @@ describe('vim.pack', function() end) it('works without prior `add()`', function() - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) n.clear() eq(true, pack_exists('basic')) @@ -2251,9 +2141,7 @@ describe('vim.pack', function() end) it('works with out of sync lockfile', function() - exec_lua(function() - vim.pack.add({ repos_src.basic, repos_src.defbranch, repos_src.plugindirs }) - end) + vim_pack_add({ repos_src.basic, repos_src.defbranch, repos_src.plugindirs }) eq(3, vim.tbl_count(get_lock_tbl().plugins)) -- Should first autoinstall missing plugin (with confirmation) @@ -2287,9 +2175,7 @@ describe('vim.pack', function() -- Should first check if every plugin name represents installed plugin -- If not - stop early before any delete - exec_lua(function() - vim.pack.add({ repos_src.basic }) - end) + vim_pack_add({ repos_src.basic }) assert('Plugin `ccc` is not installed', { 'ccc', 'basic', 'aaa' }) eq(true, pack_exists('basic'))