neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit c732133efead31f2ff23d5f4ceac639505add6e8
parent 459cffc55f7651a33b638028680255a775dded3d
Author: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
Date:   Thu, 23 Oct 2025 17:07:00 +0300

test(pack): refactor 'pack_spec.lua' with better code

Problem: 'pack_spec.lua' test file's code can be improved.

Solution: Refactor some aspects. In particular:
  - Rewrite `find_in_log` for finding event data in event log into a
    generator function that from log list returns a finder function.
    This allows it to take less arguments and be more concise.

  - Consistently use `local function f()` instead of
    `local f = function()`.

  - Prefer to use `fn.readblob()` instead of `fn.readfile()` to assert
    text from a file.

  - Use `([[...]]):format()` approach to testing file content (instead
    of array of strings). Should improve readability.

  - Universally prefer using "assert" to mean "check if certain
    expectation about the process holds up" (instead of occasional
    "validate").

Diffstat:
Mtest/functional/plugin/pack_spec.lua | 417++++++++++++++++++++++++++++++++++++++++++-------------------------------------
1 file changed, 224 insertions(+), 193 deletions(-)

diff --git a/test/functional/plugin/pack_spec.lua b/test/functional/plugin/pack_spec.lua @@ -195,7 +195,7 @@ end function repos_setup.semver() init_test_repo('semver') - local add_tag = function(name) + local function add_tag(name) repo_write_file('semver', 'lua/semver.lua', 'return "semver ' .. name .. '"') git_add_commit('Add version ' .. name, 'semver') git_cmd({ 'tag', name }, 'semver') @@ -231,22 +231,25 @@ local function watch_events(event) end --- @param log table[] -local function find_in_log(log, event, kind, repo_name, version) - local path = pack_get_plug_path(repo_name) - local spec = { name = repo_name, src = repos_src[repo_name], version = version } - local data = { kind = kind, path = path, spec = spec } - local entry = { event = event, match = vim.fs.abspath(path), data = data } - - local res = 0 - for i, tbl in ipairs(log) do - if vim.deep_equal(tbl, entry) then - res = i - break +local function make_find_packchanged(log) + --- @param suffix string + return function(suffix, kind, repo_name, version) + local path = pack_get_plug_path(repo_name) + local spec = { name = repo_name, src = repos_src[repo_name], version = version } + local data = { kind = kind, path = path, spec = spec } + local entry = { event = 'PackChanged' .. suffix, match = vim.fs.abspath(path), data = data } + + local res = 0 + for i, tbl in ipairs(log) do + if vim.deep_equal(tbl, entry) then + res = i + break + end end - end - eq(true, res > 0) + eq(true, res > 0) - return res + return res + end end local function track_nvim_echo() @@ -261,7 +264,7 @@ local function track_nvim_echo() end) end -local function validate_progress_report(action, step_names) +local function assert_progress_report(action, step_names) -- NOTE: Assume that `nvim_echo` mocked log has only progress report messages local echo_log = exec_lua('return _G.echo_log') ---@type table[] local n_steps = #step_names @@ -366,7 +369,7 @@ describe('vim.pack', function() it('passes `data` field through to `opts.load`', function() local out = exec_lua(function() local map = {} ---@type table<string,boolean> - local load = function(p) + local function load(p) local name = p.spec.name ---@type string map[name] = name == 'basic' and (p.spec.data.test == 'value') or (p.spec.data == 'value') end @@ -447,41 +450,52 @@ describe('vim.pack', function() local plugindirs_rev = git_get_hash('HEAD', 'plugindirs') local semver_rev = git_get_hash('v1.0.0', 'semver') - -- Should properly format as indented JSON - local ref_lockfile_lines = { - '{', - ' "plugins": {', - ' "basic": {', - ' "rev": "' .. basic_rev .. '",', - ' "src": "' .. repos_src.basic .. '",', - -- Branch, tag, and commit should be serialized like `'value'` to be - -- distinguishable from version ranges - ' "version": "\'some-tag\'"', - ' },', - ' "defbranch": {', - ' "rev": "' .. defbranch_rev .. '",', - ' "src": "' .. repos_src.defbranch .. '",', - ' "version": "\'main\'"', - ' },', - ' "helptags": {', - ' "rev": "' .. helptags_rev .. '",', - ' "src": "' .. repos_src.helptags .. '",', - ' "version": "\'' .. helptags_rev .. '\'"', - ' },', - ' "plugindirs": {', - ' "rev": "' .. plugindirs_rev .. '",', - ' "src": "' .. repos_src.plugindirs .. '"', - -- Absent `version` should be missing and not autoresolved - ' },', - ' "semver": {', - ' "rev": "' .. semver_rev .. '",', - ' "src": "' .. repos_src.semver .. '",', - ' "version": ">=0.0.0"', - ' }', - ' }', - '}', - } - eq(ref_lockfile_lines, fn.readfile(get_lock_path())) + -- Should properly format as indented JSON. Notes: + -- - Branch, tag, and commit should be serialized like `'value'` to be + -- distinguishable from version ranges. + -- - Absent `version` should be missing and not autoresolved. + local ref_lockfile_lines = ([[ + { + "plugins": { + "basic": { + "rev": "%s", + "src": "%s", + "version": "'some-tag'" + }, + "defbranch": { + "rev": "%s", + "src": "%s", + "version": "'main'" + }, + "helptags": { + "rev": "%s", + "src": "%s", + "version": "'%s'" + }, + "plugindirs": { + "rev": "%s", + "src": "%s" + }, + "semver": { + "rev": "%s", + "src": "%s", + "version": ">=0.0.0" + } + } + }]]):format( + basic_rev, + repos_src.basic, + defbranch_rev, + repos_src.defbranch, + helptags_rev, + repos_src.helptags, + helptags_rev, + plugindirs_rev, + repos_src.plugindirs, + semver_rev, + repos_src.semver + ) + eq(vim.text.indent(0, ref_lockfile_lines), fn.readblob(get_lock_path())) end) it('updates lockfile', function() @@ -528,13 +542,13 @@ describe('vim.pack', function() 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.readfile(basic_lua_file)) + eq('return "basic feat-branch"', fn.readblob(basic_lua_file)) -- Running `update()` should still update to use `main` exec_lua(function() vim.pack.update(nil, { force = true }) end) - eq({ 'return "basic main"' }, fn.readfile(basic_lua_file)) + eq('return "basic main"', fn.readblob(basic_lua_file)) ref_lockfile.plugins.basic.rev = git_get_hash('main', 'basic') ref_lockfile.plugins.basic.version = "'main'" @@ -615,7 +629,7 @@ describe('vim.pack', function() local pack_add_cmd = ('vim.pack.add({ %s })'):format(vim.inspect(repos_src.plugindirs)) fn.writefile({ pack_add_cmd, '_G.done = true' }, init_lua) - local validate_loaded = function() + local function assert_loaded() eq('plugindirs main', exec_lua('return require("plugindirs")')) -- Should source 'plugin/' and 'after/plugin/' exactly once @@ -626,11 +640,11 @@ describe('vim.pack', function() -- Should auto-install but wait before executing code after it n.clear({ args_rm = { '-u' } }) n.exec_lua('vim.wait(500, function() return _G.done end, 50)') - validate_loaded() + assert_loaded() -- Should only `:packadd!` already installed plugin n.clear({ args_rm = { '-u' } }) - validate_loaded() + assert_loaded() -- Should not load plugins if `--noplugin`, only adjust 'runtimepath' n.clear({ args = { '--noplugin' }, args_rm = { '-u' } }) @@ -645,7 +659,7 @@ describe('vim.pack', function() exec_lua(function() vim.pack.add({ repos_src.basic, repos_src.defbranch }) end) - validate_progress_report('Installing plugins', { 'basic', 'defbranch' }) + assert_progress_report('Installing plugins', { 'basic', 'defbranch' }) end) it('triggers relevant events', function() @@ -657,14 +671,15 @@ describe('vim.pack', function() end) local log = exec_lua('return _G.event_log') - local installpre_basic = find_in_log(log, 'PackChangedPre', 'install', 'basic', 'feat-branch') - local installpre_defbranch = find_in_log(log, 'PackChangedPre', 'install', 'defbranch', nil) - local updatepre_basic = find_in_log(log, 'PackChangedPre', 'update', 'basic', 'feat-branch') - local updatepre_defbranch = find_in_log(log, 'PackChangedPre', 'update', 'defbranch', nil) - local update_basic = find_in_log(log, 'PackChanged', 'update', 'basic', 'feat-branch') - local update_defbranch = find_in_log(log, 'PackChanged', 'update', 'defbranch', nil) - local install_basic = find_in_log(log, 'PackChanged', 'install', 'basic', 'feat-branch') - local install_defbranch = find_in_log(log, 'PackChanged', 'install', 'defbranch', nil) + local find_event = make_find_packchanged(log) + local installpre_basic = find_event('Pre', 'install', 'basic', 'feat-branch') + local installpre_defbranch = find_event('Pre', 'install', 'defbranch', nil) + local updatepre_basic = find_event('Pre', 'update', 'basic', 'feat-branch') + local updatepre_defbranch = find_event('Pre', 'update', 'defbranch', nil) + local update_basic = find_event('', 'update', 'basic', 'feat-branch') + local update_defbranch = find_event('', 'update', 'defbranch', nil) + local install_basic = find_event('', 'install', 'basic', 'feat-branch') + local install_defbranch = find_event('', 'install', 'defbranch', nil) eq(8, #log) -- NOTE: There is no guaranteed installation order among separate plugins (as it is async) @@ -694,7 +709,7 @@ describe('vim.pack', function() end) it('respects plugin/ and after/plugin/ scripts', function() - local function validate(load, ref) + local function assert(load, ref) local opts = { load = load } local out = exec_lua(function() -- Should handle bad plugin directory name @@ -721,17 +736,17 @@ describe('vim.pack', function() eq(true, vim.tbl_contains(rtp, after_dir)) end - validate(nil, { true, true, true, true, true, true, true, true }) + assert(nil, { true, true, true, true, true, true, true, true }) n.clear() - validate(false, {}) + assert(false, {}) end) it('can use function `opts.load`', function() - local validate = function() + local function assert() n.exec_lua(function() _G.load_log = {} - local load = function(...) + local function load(...) table.insert(_G.load_log, { ... }) end vim.pack.add({ repos_src.plugindirs, repos_src.basic }, { load = load }) @@ -763,11 +778,11 @@ describe('vim.pack', function() end -- Works on initial install - validate() + assert() -- Works when loading already installed plugin n.clear() - validate() + assert() end) it('generates help tags', function() @@ -781,7 +796,7 @@ describe('vim.pack', function() it('reports install/load errors after loading all input', function() t.skip(not is_jit(), "Non LuaJIT reports errors differently due to 'coxpcall'") - local validate = function(err_pat) + local function assert(err_pat) local err = pcall_err(exec_lua, function() vim.pack.add({ { src = repos_src.basic, version = 'wrong-version' }, -- Error during initial checkout @@ -815,13 +830,13 @@ describe('vim.pack', function() '`pluginerr`:\n', 'Wow, an error', } - validate(table.concat(err_pat_parts, '.*')) + assert(table.concat(err_pat_parts, '.*')) -- During loading already installed plugin. n.clear() -- NOTE: There is no error for wrong `version`, because there is no check -- for already installed plugins. Might change in the future. - validate('vim%.pack.*`pluginerr`:\n.*Wow, an error') + assert('vim%.pack.*`pluginerr`:\n.*Wow, an error') end) it('normalizes each spec', function() @@ -864,21 +879,21 @@ describe('vim.pack', function() end) it('validates input', function() - local validate = function(err_pat, input) - local add_input = function() + local function assert(err_pat, input) + local function add_input() vim.pack.add(input) end matches(err_pat, pcall_err(exec_lua, add_input)) end -- Separate spec entries - validate('list', repos_src.basic) - validate('spec:.*table', { 1 }) - validate('spec%.src:.*string', { { src = 1 } }) - validate('spec%.src:.*non%-empty string', { { src = '' } }) - validate('spec%.name:.*string', { { src = repos_src.basic, name = 1 } }) - validate('spec%.name:.*non%-empty string', { { src = repos_src.basic, name = '' } }) - validate( + assert('list', repos_src.basic) + assert('spec:.*table', { 1 }) + assert('spec%.src:.*string', { { src = 1 } }) + assert('spec%.src:.*non%-empty string', { { src = '' } }) + assert('spec%.name:.*string', { { src = repos_src.basic, name = 1 } }) + assert('spec%.name:.*non%-empty string', { { src = repos_src.basic, name = '' } }) + assert( 'spec%.version:.*string or vim%.VersionRange', { { src = repos_src.basic, version = 1 } } ) @@ -888,13 +903,13 @@ describe('vim.pack', function() { src = repos_src.basic, version = 'feat-branch' }, { src = repos_src.basic, version = 'main' }, } - validate('Conflicting `version` for `basic`.*feat%-branch.*main', version_conflict) + assert('Conflicting `version` for `basic`.*feat%-branch.*main', version_conflict) local src_conflict = { { src = repos_src.basic, name = 'my-plugin' }, { src = repos_src.semver, name = 'my-plugin' }, } - validate('Conflicting `src` for `my%-plugin`.*basic.*semver', src_conflict) + assert('Conflicting `src` for `my%-plugin`.*basic.*semver', src_conflict) end) end) @@ -959,7 +974,7 @@ describe('vim.pack', function() { src = repos_src.defbranch, version = 'does-not-exist' }, }) end) - eq({ 'return "fetch main"' }, fn.readfile(fetch_lua_file)) + eq('return "fetch main"', fn.readblob(fetch_lua_file)) exec_lua(function() -- Enable highlighting of special filetype @@ -1095,7 +1110,7 @@ describe('vim.pack', function() n.exec('write') -- - Apply changes immediately - eq({ 'return "fetch new 2"' }, fn.readfile(fetch_lua_file)) + eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) -- - Clean up buffer+window+tabpage eq(false, api.nvim_buf_is_valid(confirm_bufnr)) @@ -1104,24 +1119,31 @@ describe('vim.pack', function() -- - Write to log file local log_path = vim.fs.joinpath(fn.stdpath('log'), 'nvim-pack.log') - local log_lines = fn.readfile(log_path) - matches('========== Update %d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d ==========', log_lines[1]) - local ref_log_lines = { - '# Update ───────────────────────────────────────────────────────────────────────', - '', - '## fetch', - 'Path: ' .. fetch_path, - 'Source: ' .. fetch_src, - 'State before: ' .. hashes.fetch_head, - 'State after: ' .. hashes.fetch_new .. ' (main)', - '', - 'Pending updates:', - '< ' .. hashes.fetch_head .. ' │ Commit from `main` to be removed', - '> ' .. hashes.fetch_new .. ' │ Commit to be added 2', - '> ' .. hashes.fetch_new_prev .. ' │ Commit to be added 1 (tag: dev-tag)', - '', - } - eq(ref_log_lines, vim.list_slice(log_lines, 2)) + local log_text = fn.readblob(log_path) + local log_1, log_rest = log_text:match('^(.-)\n(.*)$') --- @type string, string + matches('========== Update %d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d ==========', log_1) + local ref_log_lines = ([[ + # Update ─────────────────────────────────────────────────────────────────────── + + ## fetch + Path: %s + Source: %s + State before: %s + State after: %s (main) + + Pending updates: + < %s │ Commit from `main` to be removed + > %s │ Commit to be added 2 + > %s │ Commit to be added 1 (tag: dev-tag)]]):format( + fetch_path, + fetch_src, + hashes.fetch_head, + hashes.fetch_new, + hashes.fetch_head, + hashes.fetch_new, + hashes.fetch_new_prev + ) + eq(vim.text.indent(0, ref_log_lines), vim.trim(log_rest)) end) it('can be dismissed with `:quit`', function() @@ -1133,7 +1155,7 @@ describe('vim.pack', function() -- Should not apply updates n.exec('quit') - eq({ 'return "fetch main"' }, fn.readfile(fetch_lua_file)) + eq('return "fetch main"', fn.readblob(fetch_lua_file)) end) it('closes full tabpage', function() @@ -1208,7 +1230,7 @@ describe('vim.pack', function() -- textDocument/hover local confirm_winnr = api.nvim_get_current_win() - local validate_hover = function(pos, commit_msg) + local function assert_hover(pos, commit_msg) api.nvim_win_set_cursor(0, pos) exec_lua(function() vim.lsp.buf.hover() @@ -1230,15 +1252,15 @@ describe('vim.pack', function() matches(ref_pattern, text) end - validate_hover({ 14, 0 }, 'Commit from `main` to be removed') - validate_hover({ 15, 0 }, 'Commit to be added 2') - validate_hover({ 18, 0 }, 'Commit from `main` to be removed') - validate_hover({ 19, 0 }, 'Commit to be added 2') - validate_hover({ 20, 0 }, 'Commit to be added 1') - validate_hover({ 27, 0 }, 'Add version v0.3.0') - validate_hover({ 30, 0 }, 'Add version v1.0.0') - validate_hover({ 31, 0 }, 'Add version v0.4') - validate_hover({ 32, 0 }, 'Add version 0.3.1') + assert_hover({ 14, 0 }, 'Commit from `main` to be removed') + assert_hover({ 15, 0 }, 'Commit to be added 2') + assert_hover({ 18, 0 }, 'Commit from `main` to be removed') + assert_hover({ 19, 0 }, 'Commit to be added 2') + assert_hover({ 20, 0 }, 'Commit to be added 1') + assert_hover({ 27, 0 }, 'Add version v0.3.0') + assert_hover({ 30, 0 }, 'Add version v1.0.0') + assert_hover({ 31, 0 }, 'Add version v0.4') + assert_hover({ 32, 0 }, 'Add version 0.3.1') -- textDocument/codeAction n.exec_lua(function() @@ -1259,7 +1281,7 @@ describe('vim.pack', function() local ref_lockfile = get_lock_tbl() --- @type vim.pack.Lock - local function validate_action(pos, action_titles, select_idx) + local function assert_action(pos, action_titles, select_idx) api.nvim_win_set_cursor(0, pos) local lines = api.nvim_buf_get_lines(0, 0, -1, false) @@ -1280,27 +1302,27 @@ describe('vim.pack', function() end -- - Should not include "namespace" header as "plugin at cursor" - validate_action({ 1, 1 }, {}, 0) - validate_action({ 2, 0 }, {}, 0) + assert_action({ 1, 1 }, {}, 0) + assert_action({ 2, 0 }, {}, 0) -- - Only deletion should be available on errored plugin - validate_action({ 3, 1 }, { 'Delete `defbranch`' }, 0) - validate_action({ 7, 0 }, { 'Delete `defbranch`' }, 0) + assert_action({ 3, 1 }, { 'Delete `defbranch`' }, 0) + assert_action({ 7, 0 }, { 'Delete `defbranch`' }, 0) -- - Should not include separator blank line as "plugin at cursor" - validate_action({ 8, 0 }, {}, 0) - validate_action({ 9, 0 }, {}, 0) - validate_action({ 10, 0 }, {}, 0) + assert_action({ 8, 0 }, {}, 0) + assert_action({ 9, 0 }, {}, 0) + assert_action({ 10, 0 }, {}, 0) -- - Should also suggest updating related actions if updates available local fetch_actions = { 'Update `fetch`', 'Skip updating `fetch`', 'Delete `fetch`' } - validate_action({ 11, 0 }, fetch_actions, 0) - validate_action({ 14, 0 }, fetch_actions, 0) - validate_action({ 20, 0 }, fetch_actions, 0) - validate_action({ 21, 0 }, {}, 0) - validate_action({ 22, 0 }, {}, 0) - validate_action({ 23, 0 }, {}, 0) + assert_action({ 11, 0 }, fetch_actions, 0) + assert_action({ 14, 0 }, fetch_actions, 0) + assert_action({ 20, 0 }, fetch_actions, 0) + assert_action({ 21, 0 }, {}, 0) + assert_action({ 22, 0 }, {}, 0) + assert_action({ 23, 0 }, {}, 0) -- - Only deletion should be available on plugins without update - validate_action({ 24, 0 }, { 'Delete `semver`' }, 0) - validate_action({ 28, 0 }, { 'Delete `semver`' }, 0) - validate_action({ 32, 0 }, { 'Delete `semver`' }, 0) + assert_action({ 24, 0 }, { 'Delete `semver`' }, 0) + assert_action({ 28, 0 }, { 'Delete `semver`' }, 0) + assert_action({ 32, 0 }, { 'Delete `semver`' }, 0) -- - Should correctly perform action and remove plugin's lines local function line_match(lnum, pattern) @@ -1308,7 +1330,7 @@ describe('vim.pack', function() end -- - Delete. Should remove from disk and update lockfile. - validate_action({ 3, 0 }, { 'Delete `defbranch`' }, 1) + assert_action({ 3, 0 }, { 'Delete `defbranch`' }, 1) eq(false, pack_exists('defbranch')) line_match(1, '^# Error') line_match(2, '^$') @@ -1318,8 +1340,8 @@ describe('vim.pack', function() eq(ref_lockfile, get_lock_tbl()) -- - Skip udating - validate_action({ 5, 0 }, fetch_actions, 2) - eq({ 'return "fetch main"' }, fn.readfile(fetch_lua_file)) + assert_action({ 5, 0 }, fetch_actions, 2) + eq('return "fetch main"', fn.readblob(fetch_lua_file)) line_match(3, '^# Update') line_match(4, '^$') line_match(5, '^# Same') @@ -1335,10 +1357,10 @@ describe('vim.pack', function() repo_write_file('fetch', 'lua/fetch.lua', 'return "fetch new 3"') git_add_commit('Commit to be added 3', 'fetch') - validate_action({ 3, 0 }, fetch_actions, 1) + assert_action({ 3, 0 }, fetch_actions, 1) - eq({ 'return "fetch new 2"' }, fn.readfile(fetch_lua_file)) - validate_progress_report('Applying updates', { 'fetch' }) + eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) + assert_progress_report('Applying updates', { 'fetch' }) line_match(1, '^# Update') line_match(2, '^$') line_match(3, '^# Same') @@ -1365,24 +1387,24 @@ describe('vim.pack', function() end) -- Plugin sections navigation - local validate = function(keys, ref_cursor) + local function assert(keys, ref_cursor) n.feed(keys) eq(ref_cursor, api.nvim_win_get_cursor(0)) end api.nvim_win_set_cursor(0, { 1, 1 }) - validate(']]', { 3, 0 }) - validate(']]', { 11, 0 }) - validate(']]', { 24, 0 }) + assert(']]', { 3, 0 }) + assert(']]', { 11, 0 }) + assert(']]', { 24, 0 }) -- - Should not wrap around the edge - validate(']]', { 24, 0 }) + assert(']]', { 24, 0 }) api.nvim_win_set_cursor(0, { 32, 1 }) - validate('[[', { 24, 0 }) - validate('[[', { 11, 0 }) - validate('[[', { 3, 0 }) + assert('[[', { 24, 0 }) + assert('[[', { 11, 0 }) + assert('[[', { 3, 0 }) -- - Should not wrap around the edge - validate('[[', { 3, 0 }) + assert('[[', { 3, 0 }) end) it('suggests newer versions when on non-tagged commit', function() @@ -1421,9 +1443,9 @@ describe('vim.pack', function() -- By default should also include not active plugins vim.pack.update() end) - eq({ 'return "fetch main"' }, fn.readfile(fetch_lua_file)) + eq('return "fetch main"', fn.readblob(fetch_lua_file)) n.exec('write') - eq({ 'return "fetch new 2"' }, fn.readfile(fetch_lua_file)) + eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) end) it('can force update', function() @@ -1435,7 +1457,7 @@ describe('vim.pack', function() -- Apply changes immediately local fetch_src = repos_src.fetch local fetch_path = pack_get_plug_path('fetch') - eq({ 'return "fetch new 2"' }, fn.readfile(fetch_lua_file)) + eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) -- No special buffer/window/tabpage eq(1, #api.nvim_list_tabpages()) @@ -1447,24 +1469,31 @@ describe('vim.pack', function() hashes.fetch_new_prev = git_get_hash('main~', 'fetch') local log_path = vim.fs.joinpath(fn.stdpath('log'), 'nvim-pack.log') - local log_lines = fn.readfile(log_path) - matches('========== Update %d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d ==========', log_lines[1]) - local ref_log_lines = { - '# Update ───────────────────────────────────────────────────────────────────────', - '', - '## fetch', - 'Path: ' .. fetch_path, - 'Source: ' .. fetch_src, - 'State before: ' .. hashes.fetch_head, - 'State after: ' .. hashes.fetch_new .. ' (main)', - '', - 'Pending updates:', - '< ' .. hashes.fetch_head .. ' │ Commit from `main` to be removed', - '> ' .. hashes.fetch_new .. ' │ Commit to be added 2', - '> ' .. hashes.fetch_new_prev .. ' │ Commit to be added 1 (tag: dev-tag)', - '', - } - eq(ref_log_lines, vim.list_slice(log_lines, 2)) + local log_text = fn.readblob(log_path) + local log_1, log_rest = log_text:match('^(.-)\n(.*)$') --- @type string, string + matches('========== Update %d%d%d%d%-%d%d%-%d%d %d%d:%d%d:%d%d ==========', log_1) + local ref_log_lines = ([[ + # Update ─────────────────────────────────────────────────────────────────────── + + ## fetch + Path: %s + Source: %s + State before: %s + State after: %s (main) + + Pending updates: + < %s │ Commit from `main` to be removed + > %s │ Commit to be added 2 + > %s │ Commit to be added 1 (tag: dev-tag)]]):format( + fetch_path, + fetch_src, + hashes.fetch_head, + hashes.fetch_new, + hashes.fetch_head, + hashes.fetch_new, + hashes.fetch_new_prev + ) + eq(vim.text.indent(0, ref_log_lines), vim.trim(log_rest)) -- Should update lockfile eq(hashes.fetch_new, get_lock_tbl().plugins.fetch.rev) @@ -1479,12 +1508,12 @@ describe('vim.pack', function() end) -- During initial download - validate_progress_report('Downloading updates', { 'fetch', 'defbranch', 'semver' }) + assert_progress_report('Downloading updates', { 'fetch', 'defbranch', 'semver' }) exec_lua('_G.echo_log = {}') -- During application (only for plugins that have updates) n.exec('write') - validate_progress_report('Applying updates', { 'fetch' }) + assert_progress_report('Applying updates', { 'fetch' }) -- During force update n.clear() @@ -1496,7 +1525,7 @@ describe('vim.pack', function() vim.pack.add({ repos_src.fetch, repos_src.defbranch }) vim.pack.update(nil, { force = true }) end) - validate_progress_report('Updating', { 'fetch', 'defbranch', 'semver' }) + assert_progress_report('Updating', { 'fetch', 'defbranch', 'semver' }) end) it('triggers relevant events', function() @@ -1511,8 +1540,9 @@ describe('vim.pack', function() -- Should trigger relevant events only for actually updated plugins n.exec('write') local log = exec_lua('return _G.event_log') - eq(1, find_in_log(log, 'PackChangedPre', 'update', 'fetch', nil)) - eq(2, find_in_log(log, 'PackChanged', 'update', 'fetch', nil)) + local find_event = make_find_packchanged(log) + eq(1, find_event('Pre', 'update', 'fetch', nil)) + eq(2, find_event('', 'update', 'fetch', nil)) eq(2, #log) end) @@ -1529,7 +1559,7 @@ describe('vim.pack', function() 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.readfile(fetch_lua_file)) + eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) end) it('is not affected by special environment variables', function() @@ -1541,20 +1571,20 @@ describe('vim.pack', function() vim.pack.add({ repos_src.fetch }) vim.pack.update({ 'fetch' }, { force = true }) end) - eq({ 'return "fetch new 2"' }, fn.readfile(fetch_lua_file)) + eq('return "fetch new 2"', fn.readblob(fetch_lua_file)) eq(ref_environ, fn.environ()) end) it('validates input', function() - local validate = function(err_pat, input) - local update_input = function() + local function assert(err_pat, input) + local function update_input() vim.pack.update(input) end matches(err_pat, pcall_err(exec_lua, update_input)) end - validate('list', 1) + assert('list', 1) -- Should first check if every plugin name represents installed plugin -- If not - stop early before any update @@ -1562,7 +1592,7 @@ describe('vim.pack', function() vim.pack.add({ repos_src.basic }) end) - validate('Plugin `ccc` is not installed', { 'ccc', 'basic', 'aaa' }) + assert('Plugin `ccc` is not installed', { 'ccc', 'basic', 'aaa' }) -- Empty list is allowed with warning n.exec('messages clear') @@ -1574,7 +1604,7 @@ describe('vim.pack', function() end) describe('get()', function() - local make_basic_data = function(active, info) + local function make_basic_data(active, info) local spec = { name = 'basic', src = repos_src.basic, version = 'feat-branch' } local path = pack_get_plug_path('basic') local rev = git_get_hash('feat-branch', 'basic') @@ -1586,7 +1616,7 @@ describe('vim.pack', function() return res end - local make_defbranch_data = function(active, info) + local function make_defbranch_data(active, info) local spec = { name = 'defbranch', src = repos_src.defbranch } local path = pack_get_plug_path('defbranch') local rev = git_get_hash('dev', 'defbranch') @@ -1598,7 +1628,7 @@ describe('vim.pack', function() return res end - local make_plugindirs_data = function(active, info) + local function make_plugindirs_data(active, info) local spec = { name = 'plugindirs', src = repos_src.plugindirs, version = vim.version.range('*') } local path = pack_get_plug_path('plugindirs') @@ -1725,10 +1755,11 @@ describe('vim.pack', function() -- Should trigger relevant events in order as specified in `vim.pack.add()` local log = exec_lua('return _G.event_log') - eq(1, find_in_log(log, 'PackChangedPre', 'delete', 'basic', 'feat-branch')) - eq(2, find_in_log(log, 'PackChanged', 'delete', 'basic', 'feat-branch')) - eq(3, find_in_log(log, 'PackChangedPre', 'delete', 'plugindirs', nil)) - eq(4, find_in_log(log, 'PackChanged', 'delete', 'plugindirs', nil)) + local find_event = make_find_packchanged(log) + eq(1, find_event('Pre', 'delete', 'basic', 'feat-branch')) + eq(2, find_event('', 'delete', 'basic', 'feat-branch')) + eq(3, find_event('Pre', 'delete', 'plugindirs', nil)) + eq(4, find_event('', 'delete', 'plugindirs', nil)) eq(4, #log) -- Should update lockfile @@ -1750,14 +1781,14 @@ describe('vim.pack', function() end) it('validates input', function() - local validate = function(err_pat, input) - local del_input = function() + local function assert(err_pat, input) + local function del_input() vim.pack.del(input) end matches(err_pat, pcall_err(exec_lua, del_input)) end - validate('list', nil) + assert('list', nil) -- Should first check if every plugin name represents installed plugin -- If not - stop early before any delete @@ -1765,7 +1796,7 @@ describe('vim.pack', function() vim.pack.add({ repos_src.basic }) end) - validate('Plugin `ccc` is not installed', { 'ccc', 'basic', 'aaa' }) + assert('Plugin `ccc` is not installed', { 'ccc', 'basic', 'aaa' }) eq(true, pack_exists('basic')) -- Empty list is allowed with warning