commit 75114fe7bb88fc4c8c729916af724832fbe1630d
parent babdab2f704e28950d968e4c4c606509f960d132
Author: Justin M. Keyes <justinkz@gmail.com>
Date: Wed, 28 Jan 2026 06:48:57 -0500
Merge #37428 vim.pack tests
Diffstat:
1 file changed, 213 insertions(+), 327 deletions(-)
diff --git 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<string,string>
local short_hashes --- @type table<string,string>
@@ -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<string,string>
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'))