refactor(lua): "module" => "M" #28426

Most of the codebase uses the `M` convention for Lua module.
Update the last remaining cases.
This commit is contained in:
Justin M. Keyes 2024-04-20 09:06:49 -07:00 committed by GitHub
parent f190f758ac
commit 8886b1807c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 233 additions and 233 deletions

View File

@ -1,6 +1,6 @@
local bit = require 'bit' local bit = require 'bit'
local module = {} local M = {}
-- Description of the values below is contained in ex_cmds_defs.h file. -- Description of the values below is contained in ex_cmds_defs.h file.
-- "EX_" prefix is omitted. -- "EX_" prefix is omitted.
@ -32,14 +32,14 @@ local FILES = bit.bor(XFILE, EXTRA)
local WORD1 = bit.bor(EXTRA, NOSPC) local WORD1 = bit.bor(EXTRA, NOSPC)
local FILE1 = bit.bor(FILES, NOSPC) local FILE1 = bit.bor(FILES, NOSPC)
module.flags = { M.flags = {
RANGE = RANGE, RANGE = RANGE,
DFLALL = DFLALL, DFLALL = DFLALL,
PREVIEW = PREVIEW, PREVIEW = PREVIEW,
} }
-- The following table is described in ex_cmds_defs.h file. -- The following table is described in ex_cmds_defs.h file.
module.cmds = { M.cmds = {
{ {
command = 'append', command = 'append',
flags = bit.bor(BANG, RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK, MODIFY), flags = bit.bor(BANG, RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK, MODIFY),
@ -3359,4 +3359,4 @@ module.cmds = {
}, },
} }
return module return M

View File

@ -1,22 +1,22 @@
local module = {} local M = {}
module.include_paths = {} M.include_paths = {}
for p in ("${TEST_INCLUDE_DIRS}" .. ";"):gmatch("[^;]+") do for p in ("${TEST_INCLUDE_DIRS}" .. ";"):gmatch("[^;]+") do
table.insert(module.include_paths, p) table.insert(M.include_paths, p)
end end
module.test_build_dir = "${CMAKE_BINARY_DIR}" M.test_build_dir = "${CMAKE_BINARY_DIR}"
module.test_source_path = "${CMAKE_SOURCE_DIR}" M.test_source_path = "${CMAKE_SOURCE_DIR}"
module.test_lua_prg = "${LUA_PRG}" M.test_lua_prg = "${LUA_PRG}"
module.test_luajit_prg = "" M.test_luajit_prg = ""
if module.test_luajit_prg == '' then if M.test_luajit_prg == '' then
if module.test_lua_prg:sub(-6) == 'luajit' then if M.test_lua_prg:sub(-6) == 'luajit' then
module.test_luajit_prg = module.test_lua_prg M.test_luajit_prg = M.test_lua_prg
else else
module.test_luajit_prg = nil M.test_luajit_prg = nil
end end
end end
table.insert(module.include_paths, "${CMAKE_BINARY_DIR}/include") table.insert(M.include_paths, "${CMAKE_BINARY_DIR}/include")
table.insert(module.include_paths, "${CMAKE_BINARY_DIR}/src/nvim/auto") table.insert(M.include_paths, "${CMAKE_BINARY_DIR}/src/nvim/auto")
return module return M

View File

@ -16,18 +16,18 @@ local sleep = uv.sleep
local fail = t_global.fail local fail = t_global.fail
--- @class test.functional.testutil: test.testutil --- @class test.functional.testutil: test.testutil
local module = vim.deepcopy(t_global) local M = vim.deepcopy(t_global)
local runtime_set = 'set runtimepath^=./build/lib/nvim/' local runtime_set = 'set runtimepath^=./build/lib/nvim/'
module.nvim_prog = (os.getenv('NVIM_PRG') or t_global.paths.test_build_dir .. '/bin/nvim') M.nvim_prog = (os.getenv('NVIM_PRG') or t_global.paths.test_build_dir .. '/bin/nvim')
-- Default settings for the test session. -- Default settings for the test session.
module.nvim_set = ( M.nvim_set = (
'set shortmess+=IS background=light termguicolors noswapfile noautoindent startofline' 'set shortmess+=IS background=light termguicolors noswapfile noautoindent startofline'
.. ' laststatus=1 undodir=. directory=. viewdir=. backupdir=.' .. ' laststatus=1 undodir=. directory=. viewdir=. backupdir=.'
.. ' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid' .. ' belloff= wildoptions-=pum joinspaces noshowcmd noruler nomore redrawdebug=invalid'
) )
module.nvim_argv = { M.nvim_argv = {
module.nvim_prog, M.nvim_prog,
'-u', '-u',
'NONE', 'NONE',
'-i', '-i',
@ -36,7 +36,7 @@ module.nvim_argv = {
'--cmd', '--cmd',
runtime_set, runtime_set,
'--cmd', '--cmd',
module.nvim_set, M.nvim_set,
-- Remove default user commands and mappings. -- Remove default user commands and mappings.
'--cmd', '--cmd',
'comclear | mapclear | mapclear!', 'comclear | mapclear | mapclear!',
@ -51,9 +51,9 @@ module.nvim_argv = {
} }
-- Directory containing nvim. -- Directory containing nvim.
module.nvim_dir = module.nvim_prog:gsub('[/\\][^/\\]+$', '') M.nvim_dir = M.nvim_prog:gsub('[/\\][^/\\]+$', '')
if module.nvim_dir == module.nvim_prog then if M.nvim_dir == M.nvim_prog then
module.nvim_dir = '.' M.nvim_dir = '.'
end end
local prepend_argv --- @type string[]? local prepend_argv --- @type string[]?
@ -85,11 +85,11 @@ if prepend_argv then
for i = 1, len do for i = 1, len do
new_nvim_argv[i] = prepend_argv[i] new_nvim_argv[i] = prepend_argv[i]
end end
for i = 1, #module.nvim_argv do for i = 1, #M.nvim_argv do
new_nvim_argv[i + len] = module.nvim_argv[i] new_nvim_argv[i + len] = M.nvim_argv[i]
end end
module.nvim_argv = new_nvim_argv M.nvim_argv = new_nvim_argv
module.prepend_argv = prepend_argv M.prepend_argv = prepend_argv
end end
local session --- @type test.Session? local session --- @type test.Session?
@ -104,18 +104,18 @@ if not is_os('win') then
end) end)
end end
function module.get_session() function M.get_session()
return session return session
end end
function module.set_session(s) function M.set_session(s)
session = s session = s
end end
--- @param method string --- @param method string
--- @param ... any --- @param ... any
--- @return any --- @return any
function module.request(method, ...) function M.request(method, ...)
assert(session) assert(session)
local status, rv = session:request(method, ...) local status, rv = session:request(method, ...)
if not status then if not status then
@ -133,21 +133,21 @@ end
--- @param method string --- @param method string
--- @param ... any --- @param ... any
--- @return any --- @return any
function module.request_lua(method, ...) function M.request_lua(method, ...)
return module.exec_lua([[return vim.api[...](select(2, ...))]], method, ...) return M.exec_lua([[return vim.api[...](select(2, ...))]], method, ...)
end end
--- @param timeout? integer --- @param timeout? integer
--- @return string? --- @return string?
function module.next_msg(timeout) function M.next_msg(timeout)
assert(session) assert(session)
return session:next_message(timeout or 10000) return session:next_message(timeout or 10000)
end end
function module.expect_twostreams(msgs1, msgs2) function M.expect_twostreams(msgs1, msgs2)
local pos1, pos2 = 1, 1 local pos1, pos2 = 1, 1
while pos1 <= #msgs1 or pos2 <= #msgs2 do while pos1 <= #msgs1 or pos2 <= #msgs2 do
local msg = module.next_msg() local msg = M.next_msg()
if pos1 <= #msgs1 and pcall(eq, msgs1[pos1], msg) then if pos1 <= #msgs1 and pcall(eq, msgs1[pos1], msg) then
pos1 = pos1 + 1 pos1 = pos1 + 1
elseif pos2 <= #msgs2 then elseif pos2 <= #msgs2 then
@ -170,7 +170,7 @@ end
-- --
-- ignore: List of ignored event names. -- ignore: List of ignored event names.
-- seqs: List of one or more potential event sequences. -- seqs: List of one or more potential event sequences.
function module.expect_msg_seq(...) function M.expect_msg_seq(...)
if select('#', ...) < 1 then if select('#', ...) < 1 then
error('need at least 1 argument') error('need at least 1 argument')
end end
@ -197,12 +197,12 @@ function module.expect_msg_seq(...)
end end
return string.format('%s\n%s\n%s', err1, string.rep('=', 78), err2) return string.format('%s\n%s\n%s', err1, string.rep('=', 78), err2)
end end
local msg_timeout = module.load_adjust(10000) -- Big timeout for ASAN/valgrind. local msg_timeout = M.load_adjust(10000) -- Big timeout for ASAN/valgrind.
for anum = 1, #seqs do for anum = 1, #seqs do
local expected_seq = seqs[anum] local expected_seq = seqs[anum]
-- Collect enough messages to compare the next expected sequence. -- Collect enough messages to compare the next expected sequence.
while #actual_seq < #expected_seq do while #actual_seq < #expected_seq do
local msg = module.next_msg(msg_timeout) local msg = M.next_msg(msg_timeout)
local msg_type = msg and msg[2] or nil local msg_type = msg and msg[2] or nil
if msg == nil then if msg == nil then
error( error(
@ -247,7 +247,7 @@ local function call_and_stop_on_error(lsession, ...)
return result return result
end end
function module.set_method_error(err) function M.set_method_error(err)
method_error = err method_error = err
end end
@ -257,7 +257,7 @@ end
--- @param setup_cb function? --- @param setup_cb function?
--- @param timeout integer --- @param timeout integer
--- @return {[1]: integer, [2]: string} --- @return {[1]: integer, [2]: string}
function module.run_session(lsession, request_cb, notification_cb, setup_cb, timeout) function M.run_session(lsession, request_cb, notification_cb, setup_cb, timeout)
local on_request --- @type function? local on_request --- @type function?
local on_notification --- @type function? local on_notification --- @type function?
local on_setup --- @type function? local on_setup --- @type function?
@ -297,35 +297,35 @@ function module.run_session(lsession, request_cb, notification_cb, setup_cb, tim
return lsession.eof_err return lsession.eof_err
end end
function module.run(request_cb, notification_cb, setup_cb, timeout) function M.run(request_cb, notification_cb, setup_cb, timeout)
assert(session) assert(session)
return module.run_session(session, request_cb, notification_cb, setup_cb, timeout) return M.run_session(session, request_cb, notification_cb, setup_cb, timeout)
end end
function module.stop() function M.stop()
assert(session):stop() assert(session):stop()
end end
function module.nvim_prog_abs() function M.nvim_prog_abs()
-- system(['build/bin/nvim']) does not work for whatever reason. It must -- system(['build/bin/nvim']) does not work for whatever reason. It must
-- be executable searched in $PATH or something starting with / or ./. -- be executable searched in $PATH or something starting with / or ./.
if module.nvim_prog:match('[/\\]') then if M.nvim_prog:match('[/\\]') then
return module.request('nvim_call_function', 'fnamemodify', { module.nvim_prog, ':p' }) return M.request('nvim_call_function', 'fnamemodify', { M.nvim_prog, ':p' })
else else
return module.nvim_prog return M.nvim_prog
end end
end end
-- Use for commands which expect nvim to quit. -- Use for commands which expect nvim to quit.
-- The first argument can also be a timeout. -- The first argument can also be a timeout.
function module.expect_exit(fn_or_timeout, ...) function M.expect_exit(fn_or_timeout, ...)
local eof_err_msg = 'EOF was received from Nvim. Likely the Nvim process crashed.' local eof_err_msg = 'EOF was received from Nvim. Likely the Nvim process crashed.'
if type(fn_or_timeout) == 'function' then if type(fn_or_timeout) == 'function' then
eq(eof_err_msg, module.pcall_err(fn_or_timeout, ...)) eq(eof_err_msg, M.pcall_err(fn_or_timeout, ...))
else else
eq( eq(
eof_err_msg, eof_err_msg,
module.pcall_err(function(timeout, fn, ...) M.pcall_err(function(timeout, fn, ...)
fn(...) fn(...)
assert(session) assert(session)
while session:next_message(timeout) do while session:next_message(timeout) do
@ -343,8 +343,8 @@ end
--- @param name string --- @param name string
--- @param ... any --- @param ... any
--- @return any --- @return any
function module.call_lua(name, ...) function M.call_lua(name, ...)
return module.exec_lua([[return vim.call(...)]], name, ...) return M.exec_lua([[return vim.call(...)]], name, ...)
end end
--- Sends user input to Nvim. --- Sends user input to Nvim.
@ -352,9 +352,9 @@ end
--- @param input string --- @param input string
local function nvim_feed(input) local function nvim_feed(input)
while #input > 0 do while #input > 0 do
local written = module.request('nvim_input', input) local written = M.request('nvim_input', input)
if written == nil then if written == nil then
module.assert_alive() M.assert_alive()
error('crash? (nvim_input returned nil)') error('crash? (nvim_input returned nil)')
end end
input = input:sub(written + 1) input = input:sub(written + 1)
@ -362,7 +362,7 @@ local function nvim_feed(input)
end end
--- @param ... string --- @param ... string
function module.feed(...) function M.feed(...)
for _, v in ipairs({ ... }) do for _, v in ipairs({ ... }) do
nvim_feed(dedent(v)) nvim_feed(dedent(v))
end end
@ -370,7 +370,7 @@ end
---@param ... string[]? ---@param ... string[]?
---@return string[] ---@return string[]
function module.merge_args(...) function M.merge_args(...)
local i = 1 local i = 1
local argv = {} --- @type string[] local argv = {} --- @type string[]
for anum = 1, select('#', ...) do for anum = 1, select('#', ...) do
@ -432,7 +432,7 @@ local function remove_args(args, args_rm)
return new_args return new_args
end end
function module.check_close() function M.check_close()
if not session then if not session then
return return
end end
@ -459,18 +459,18 @@ end
--- @param keep boolean --- @param keep boolean
--- @param io_extra uv.uv_pipe_t? used for stdin_fd, see :help ui-option --- @param io_extra uv.uv_pipe_t? used for stdin_fd, see :help ui-option
--- @return test.Session --- @return test.Session
function module.spawn(argv, merge, env, keep, io_extra) function M.spawn(argv, merge, env, keep, io_extra)
if not keep then if not keep then
module.check_close() M.check_close()
end end
local child_stream = local child_stream =
ChildProcessStream.spawn(merge and module.merge_args(prepend_argv, argv) or argv, env, io_extra) ChildProcessStream.spawn(merge and M.merge_args(prepend_argv, argv) or argv, env, io_extra)
return Session.new(child_stream) return Session.new(child_stream)
end end
-- Creates a new Session connected by domain socket (named pipe) or TCP. -- Creates a new Session connected by domain socket (named pipe) or TCP.
function module.connect(file_or_address) function M.connect(file_or_address)
local addr, port = string.match(file_or_address, '(.*):(%d+)') local addr, port = string.match(file_or_address, '(.*):(%d+)')
local stream = (addr and port) and SocketStream.connect(addr, port) local stream = (addr and port) and SocketStream.connect(addr, port)
or SocketStream.open(file_or_address) or SocketStream.open(file_or_address)
@ -489,17 +489,17 @@ end
-- Example: -- Example:
-- clear('-e') -- clear('-e')
-- clear{args={'-e'}, args_rm={'-i'}, env={TERM=term}} -- clear{args={'-e'}, args_rm={'-i'}, env={TERM=term}}
function module.clear(...) function M.clear(...)
module.set_session(module.spawn_argv(false, ...)) M.set_session(M.spawn_argv(false, ...))
return module.get_session() return M.get_session()
end end
--- same params as clear, but does returns the session instead --- same params as clear, but does returns the session instead
--- of replacing the default session --- of replacing the default session
--- @return test.Session --- @return test.Session
function module.spawn_argv(keep, ...) function M.spawn_argv(keep, ...)
local argv, env, io_extra = module.new_argv(...) local argv, env, io_extra = M.new_argv(...)
return module.spawn(argv, nil, env, keep, io_extra) return M.spawn(argv, nil, env, keep, io_extra)
end end
--- @class test.new_argv.Opts --- @class test.new_argv.Opts
@ -515,8 +515,8 @@ end
--- @return string[] --- @return string[]
--- @return string[]? --- @return string[]?
--- @return uv.uv_pipe_t? --- @return uv.uv_pipe_t?
function module.new_argv(...) function M.new_argv(...)
local args = { unpack(module.nvim_argv) } local args = { unpack(M.nvim_argv) }
table.insert(args, '--headless') table.insert(args, '--headless')
if _G._nvim_test_id then if _G._nvim_test_id then
-- Set the server name to the test-id for logging. #8519 -- Set the server name to the test-id for logging. #8519
@ -573,11 +573,11 @@ function module.new_argv(...)
end end
--- @param ... string --- @param ... string
function module.insert(...) function M.insert(...)
nvim_feed('i') nvim_feed('i')
for _, v in ipairs({ ... }) do for _, v in ipairs({ ... }) do
local escaped = v:gsub('<', '<lt>') local escaped = v:gsub('<', '<lt>')
module.feed(escaped) M.feed(escaped)
end end
nvim_feed('<ESC>') nvim_feed('<ESC>')
end end
@ -585,7 +585,7 @@ end
--- Executes an ex-command by user input. Because nvim_input() is used, Vimscript --- Executes an ex-command by user input. Because nvim_input() is used, Vimscript
--- errors will not manifest as client (lua) errors. Use command() for that. --- errors will not manifest as client (lua) errors. Use command() for that.
--- @param ... string --- @param ... string
function module.feed_command(...) function M.feed_command(...)
for _, v in ipairs({ ... }) do for _, v in ipairs({ ... }) do
if v:sub(1, 1) ~= '/' then if v:sub(1, 1) ~= '/' then
-- not a search command, prefix with colon -- not a search command, prefix with colon
@ -597,12 +597,12 @@ function module.feed_command(...)
end end
-- @deprecated use nvim_exec2() -- @deprecated use nvim_exec2()
function module.source(code) function M.source(code)
module.exec(dedent(code)) M.exec(dedent(code))
end end
function module.has_powershell() function M.has_powershell()
return module.eval('executable("' .. (is_os('win') and 'powershell' or 'pwsh') .. '")') == 1 return M.eval('executable("' .. (is_os('win') and 'powershell' or 'pwsh') .. '")') == 1
end end
--- Sets Nvim shell to powershell. --- Sets Nvim shell to powershell.
@ -610,12 +610,12 @@ end
--- @param fake (boolean) If true, a fake will be used if powershell is not --- @param fake (boolean) If true, a fake will be used if powershell is not
--- found on the system. --- found on the system.
--- @returns true if powershell was found on the system, else false. --- @returns true if powershell was found on the system, else false.
function module.set_shell_powershell(fake) function M.set_shell_powershell(fake)
local found = module.has_powershell() local found = M.has_powershell()
if not fake then if not fake then
assert(found) assert(found)
end end
local shell = found and (is_os('win') and 'powershell' or 'pwsh') or module.testprg('pwsh-test') local shell = found and (is_os('win') and 'powershell' or 'pwsh') or M.testprg('pwsh-test')
local cmd = 'Remove-Item -Force ' local cmd = 'Remove-Item -Force '
.. table.concat( .. table.concat(
is_os('win') and { 'alias:cat', 'alias:echo', 'alias:sleep', 'alias:sort', 'alias:tee' } is_os('win') and { 'alias:cat', 'alias:echo', 'alias:sleep', 'alias:sort', 'alias:tee' }
@ -623,7 +623,7 @@ function module.set_shell_powershell(fake)
',' ','
) )
.. ';' .. ';'
module.exec([[ M.exec([[
let &shell = ']] .. shell .. [[' let &shell = ']] .. shell .. [['
set shellquote= shellxquote= set shellquote= shellxquote=
let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ' let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command '
@ -638,7 +638,7 @@ end
---@param func function ---@param func function
---@return table<string,function> ---@return table<string,function>
function module.create_callindex(func) function M.create_callindex(func)
return setmetatable({}, { return setmetatable({}, {
--- @param tbl table<any,function> --- @param tbl table<any,function>
--- @param arg1 string --- @param arg1 string
@ -655,7 +655,7 @@ end
--- @param method string --- @param method string
--- @param ... any --- @param ... any
function module.nvim_async(method, ...) function M.nvim_async(method, ...)
assert(session):notify(method, ...) assert(session):notify(method, ...)
end end
@ -664,27 +664,27 @@ end
--- @param name string --- @param name string
--- @param ... any --- @param ... any
--- @return any --- @return any
function module.call(name, ...) function M.call(name, ...)
return module.request('nvim_call_function', name, { ... }) return M.request('nvim_call_function', name, { ... })
end end
module.async_meths = module.create_callindex(module.nvim_async) M.async_meths = M.create_callindex(M.nvim_async)
module.rpc = { M.rpc = {
fn = module.create_callindex(module.call), fn = M.create_callindex(M.call),
api = module.create_callindex(module.request), api = M.create_callindex(M.request),
} }
module.lua = { M.lua = {
fn = module.create_callindex(module.call_lua), fn = M.create_callindex(M.call_lua),
api = module.create_callindex(module.request_lua), api = M.create_callindex(M.request_lua),
} }
module.describe_lua_and_rpc = function(describe) M.describe_lua_and_rpc = function(describe)
return function(what, tests) return function(what, tests)
local function d(flavour) local function d(flavour)
describe(string.format('%s (%s)', what, flavour), function(...) describe(string.format('%s (%s)', what, flavour), function(...)
return tests(module[flavour].api, ...) return tests(M[flavour].api, ...)
end) end)
end end
@ -694,52 +694,52 @@ module.describe_lua_and_rpc = function(describe)
end end
--- add for typing. The for loop after will overwrite this --- add for typing. The for loop after will overwrite this
module.api = vim.api M.api = vim.api
module.fn = vim.fn M.fn = vim.fn
for name, fns in pairs(module.rpc) do for name, fns in pairs(M.rpc) do
--- @diagnostic disable-next-line:no-unknown --- @diagnostic disable-next-line:no-unknown
module[name] = fns M[name] = fns
end end
-- Executes an ex-command. Vimscript errors manifest as client (lua) errors, but -- Executes an ex-command. Vimscript errors manifest as client (lua) errors, but
-- v:errmsg will not be updated. -- v:errmsg will not be updated.
module.command = module.api.nvim_command M.command = M.api.nvim_command
-- Evaluates a Vimscript expression. -- Evaluates a Vimscript expression.
-- Fails on Vimscript error, but does not update v:errmsg. -- Fails on Vimscript error, but does not update v:errmsg.
module.eval = module.api.nvim_eval M.eval = M.api.nvim_eval
function module.poke_eventloop() function M.poke_eventloop()
-- Execute 'nvim_eval' (a deferred function) to -- Execute 'nvim_eval' (a deferred function) to
-- force at least one main_loop iteration -- force at least one main_loop iteration
module.api.nvim_eval('1') M.api.nvim_eval('1')
end end
function module.buf_lines(bufnr) function M.buf_lines(bufnr)
return module.exec_lua('return vim.api.nvim_buf_get_lines((...), 0, -1, false)', bufnr) return M.exec_lua('return vim.api.nvim_buf_get_lines((...), 0, -1, false)', bufnr)
end end
---@see buf_lines() ---@see buf_lines()
function module.curbuf_contents() function M.curbuf_contents()
module.poke_eventloop() -- Before inspecting the buffer, do whatever. M.poke_eventloop() -- Before inspecting the buffer, do whatever.
return table.concat(module.api.nvim_buf_get_lines(0, 0, -1, true), '\n') return table.concat(M.api.nvim_buf_get_lines(0, 0, -1, true), '\n')
end end
function module.expect(contents) function M.expect(contents)
return eq(dedent(contents), module.curbuf_contents()) return eq(dedent(contents), M.curbuf_contents())
end end
function module.expect_any(contents) function M.expect_any(contents)
contents = dedent(contents) contents = dedent(contents)
return ok(nil ~= string.find(module.curbuf_contents(), contents, 1, true)) return ok(nil ~= string.find(M.curbuf_contents(), contents, 1, true))
end end
--- @param expected any[] --- @param expected any[]
--- @param received any[] --- @param received any[]
--- @param kind string --- @param kind string
--- @return any --- @return any
function module.expect_events(expected, received, kind) function M.expect_events(expected, received, kind)
if not pcall(eq, expected, received) then if not pcall(eq, expected, received) then
local msg = 'unexpected ' .. kind .. ' received.\n\n' local msg = 'unexpected ' .. kind .. ' received.\n\n'
@ -757,22 +757,22 @@ function module.expect_events(expected, received, kind)
end end
-- Checks that the Nvim session did not terminate. -- Checks that the Nvim session did not terminate.
function module.assert_alive() function M.assert_alive()
assert(2 == module.eval('1+1'), 'crash? request failed') assert(2 == M.eval('1+1'), 'crash? request failed')
end end
-- Asserts that buffer is loaded and visible in the current tabpage. -- Asserts that buffer is loaded and visible in the current tabpage.
function module.assert_visible(bufnr, visible) function M.assert_visible(bufnr, visible)
assert(type(visible) == 'boolean') assert(type(visible) == 'boolean')
eq(visible, module.api.nvim_buf_is_loaded(bufnr)) eq(visible, M.api.nvim_buf_is_loaded(bufnr))
if visible then if visible then
assert( assert(
-1 ~= module.fn.bufwinnr(bufnr), -1 ~= M.fn.bufwinnr(bufnr),
'expected buffer to be visible in current tabpage: ' .. tostring(bufnr) 'expected buffer to be visible in current tabpage: ' .. tostring(bufnr)
) )
else else
assert( assert(
-1 == module.fn.bufwinnr(bufnr), -1 == M.fn.bufwinnr(bufnr),
'expected buffer NOT visible in current tabpage: ' .. tostring(bufnr) 'expected buffer NOT visible in current tabpage: ' .. tostring(bufnr)
) )
end end
@ -800,7 +800,7 @@ local function do_rmdir(path)
else else
-- Try Nvim delete(): it handles `readonly` attribute on Windows, -- Try Nvim delete(): it handles `readonly` attribute on Windows,
-- and avoids Lua cross-version/platform incompatibilities. -- and avoids Lua cross-version/platform incompatibilities.
if -1 == module.call('delete', abspath) then if -1 == M.call('delete', abspath) then
local hint = (is_os('win') and ' (hint: try :%bwipeout! before rmdir())' or '') local hint = (is_os('win') and ' (hint: try :%bwipeout! before rmdir())' or '')
error('delete() failed' .. hint .. ': ' .. abspath) error('delete() failed' .. hint .. ': ' .. abspath)
end end
@ -817,12 +817,12 @@ end
local start_dir = uv.cwd() local start_dir = uv.cwd()
function module.rmdir(path) function M.rmdir(path)
local ret, _ = pcall(do_rmdir, path) local ret, _ = pcall(do_rmdir, path)
if not ret and is_os('win') then if not ret and is_os('win') then
-- Maybe "Permission denied"; try again after changing the nvim -- Maybe "Permission denied"; try again after changing the nvim
-- process to the top-level directory. -- process to the top-level directory.
module.command([[exe 'cd '.fnameescape(']] .. start_dir .. "')") M.command([[exe 'cd '.fnameescape(']] .. start_dir .. "')")
ret, _ = pcall(do_rmdir, path) ret, _ = pcall(do_rmdir, path)
end end
-- During teardown, the nvim process may not exit quickly enough, then rmdir() -- During teardown, the nvim process may not exit quickly enough, then rmdir()
@ -833,23 +833,23 @@ function module.rmdir(path)
end end
end end
function module.exc_exec(cmd) function M.exc_exec(cmd)
module.command(([[ M.command(([[
try try
execute "%s" execute "%s"
catch catch
let g:__exception = v:exception let g:__exception = v:exception
endtry endtry
]]):format(cmd:gsub('\n', '\\n'):gsub('[\\"]', '\\%0'))) ]]):format(cmd:gsub('\n', '\\n'):gsub('[\\"]', '\\%0')))
local ret = module.eval('get(g:, "__exception", 0)') local ret = M.eval('get(g:, "__exception", 0)')
module.command('unlet! g:__exception') M.command('unlet! g:__exception')
return ret return ret
end end
--- @param cond boolean --- @param cond boolean
--- @param reason? string --- @param reason? string
--- @return boolean --- @return boolean
function module.skip(cond, reason) function M.skip(cond, reason)
if cond then if cond then
--- @type fun(reason: string) --- @type fun(reason: string)
local pending = getfenv(2).pending local pending = getfenv(2).pending
@ -861,7 +861,7 @@ end
-- Calls pending() and returns `true` if the system is too slow to -- Calls pending() and returns `true` if the system is too slow to
-- run fragile or expensive tests. Else returns `false`. -- run fragile or expensive tests. Else returns `false`.
function module.skip_fragile(pending_fn, cond) function M.skip_fragile(pending_fn, cond)
if pending_fn == nil or type(pending_fn) ~= type(function() end) then if pending_fn == nil or type(pending_fn) ~= type(function() end) then
error('invalid pending_fn') error('invalid pending_fn')
end end
@ -875,52 +875,52 @@ function module.skip_fragile(pending_fn, cond)
return false return false
end end
function module.exec(code) function M.exec(code)
module.api.nvim_exec2(code, {}) M.api.nvim_exec2(code, {})
end end
--- @param code string --- @param code string
--- @return string --- @return string
function module.exec_capture(code) function M.exec_capture(code)
return module.api.nvim_exec2(code, { output = true }).output return M.api.nvim_exec2(code, { output = true }).output
end end
--- @param code string --- @param code string
--- @return any --- @return any
function module.exec_lua(code, ...) function M.exec_lua(code, ...)
return module.api.nvim_exec_lua(code, { ... }) return M.api.nvim_exec_lua(code, { ... })
end end
function module.get_pathsep() function M.get_pathsep()
return is_os('win') and '\\' or '/' return is_os('win') and '\\' or '/'
end end
--- Gets the filesystem root dir, namely "/" or "C:/". --- Gets the filesystem root dir, namely "/" or "C:/".
function module.pathroot() function M.pathroot()
local pathsep = package.config:sub(1, 1) local pathsep = package.config:sub(1, 1)
return is_os('win') and (module.nvim_dir:sub(1, 2) .. pathsep) or '/' return is_os('win') and (M.nvim_dir:sub(1, 2) .. pathsep) or '/'
end end
--- Gets the full `…/build/bin/{name}` path of a test program produced by --- Gets the full `…/build/bin/{name}` path of a test program produced by
--- `test/functional/fixtures/CMakeLists.txt`. --- `test/functional/fixtures/CMakeLists.txt`.
--- ---
--- @param name (string) Name of the test program. --- @param name (string) Name of the test program.
function module.testprg(name) function M.testprg(name)
local ext = module.is_os('win') and '.exe' or '' local ext = M.is_os('win') and '.exe' or ''
return ('%s/%s%s'):format(module.nvim_dir, name, ext) return ('%s/%s%s'):format(M.nvim_dir, name, ext)
end end
function module.is_asan() function M.is_asan()
local version = module.eval('execute("verbose version")') local version = M.eval('execute("verbose version")')
return version:match('-fsanitize=[a-z,]*address') return version:match('-fsanitize=[a-z,]*address')
end end
-- Returns a valid, platform-independent Nvim listen address. -- Returns a valid, platform-independent Nvim listen address.
-- Useful for communicating with child instances. -- Useful for communicating with child instances.
function module.new_pipename() function M.new_pipename()
-- HACK: Start a server temporarily, get the name, then stop it. -- HACK: Start a server temporarily, get the name, then stop it.
local pipename = module.eval('serverstart()') local pipename = M.eval('serverstart()')
module.fn.serverstop(pipename) M.fn.serverstop(pipename)
-- Remove the pipe so that trying to connect to it without a server listening -- Remove the pipe so that trying to connect to it without a server listening
-- will be an error instead of a hang. -- will be an error instead of a hang.
os.remove(pipename) os.remove(pipename)
@ -929,24 +929,24 @@ end
--- @param provider string --- @param provider string
--- @return string|boolean? --- @return string|boolean?
function module.missing_provider(provider) function M.missing_provider(provider)
if provider == 'ruby' or provider == 'perl' then if provider == 'ruby' or provider == 'perl' then
--- @type string? --- @type string?
local e = module.exec_lua("return {require('vim.provider." .. provider .. "').detect()}")[2] local e = M.exec_lua("return {require('vim.provider." .. provider .. "').detect()}")[2]
return e ~= '' and e or false return e ~= '' and e or false
elseif provider == 'node' then elseif provider == 'node' then
--- @type string? --- @type string?
local e = module.fn['provider#node#Detect']()[2] local e = M.fn['provider#node#Detect']()[2]
return e ~= '' and e or false return e ~= '' and e or false
elseif provider == 'python' then elseif provider == 'python' then
return module.exec_lua([[return {require('vim.provider.python').detect_by_module('neovim')}]])[2] return M.exec_lua([[return {require('vim.provider.python').detect_by_module('neovim')}]])[2]
end end
assert(false, 'Unknown provider: ' .. provider) assert(false, 'Unknown provider: ' .. provider)
end end
--- @param obj string|table --- @param obj string|table
--- @return any --- @return any
function module.alter_slashes(obj) function M.alter_slashes(obj)
if not is_os('win') then if not is_os('win') then
return obj return obj
end end
@ -957,7 +957,7 @@ function module.alter_slashes(obj)
--- @cast obj table<any,any> --- @cast obj table<any,any>
local ret = {} --- @type table<any,any> local ret = {} --- @type table<any,any>
for k, v in pairs(obj) do for k, v in pairs(obj) do
ret[k] = module.alter_slashes(v) ret[k] = M.alter_slashes(v)
end end
return ret return ret
end end
@ -967,26 +967,26 @@ end
local load_factor = 1 local load_factor = 1
if t_global.is_ci() then if t_global.is_ci() then
-- Compute load factor only once (but outside of any tests). -- Compute load factor only once (but outside of any tests).
module.clear() M.clear()
module.request('nvim_command', 'source test/old/testdir/load.vim') M.request('nvim_command', 'source test/old/testdir/load.vim')
load_factor = module.request('nvim_eval', 'g:test_load_factor') load_factor = M.request('nvim_eval', 'g:test_load_factor')
end end
--- @param num number --- @param num number
--- @return number --- @return number
function module.load_adjust(num) function M.load_adjust(num)
return math.ceil(num * load_factor) return math.ceil(num * load_factor)
end end
--- @param ctx table<string,any> --- @param ctx table<string,any>
--- @return table --- @return table
function module.parse_context(ctx) function M.parse_context(ctx)
local parsed = {} --- @type table<string,any> local parsed = {} --- @type table<string,any>
for _, item in ipairs({ 'regs', 'jumps', 'bufs', 'gvars' }) do for _, item in ipairs({ 'regs', 'jumps', 'bufs', 'gvars' }) do
--- @param v any --- @param v any
parsed[item] = vim.tbl_filter(function(v) parsed[item] = vim.tbl_filter(function(v)
return type(v) == 'table' return type(v) == 'table'
end, module.call('msgpackparse', ctx[item])) end, M.call('msgpackparse', ctx[item]))
end end
parsed['bufs'] = parsed['bufs'][1] parsed['bufs'] = parsed['bufs'][1]
--- @param v any --- @param v any
@ -998,15 +998,15 @@ function module.parse_context(ctx)
end, parsed) end, parsed)
end end
function module.add_builddir_to_rtp() function M.add_builddir_to_rtp()
-- Add runtime from build dir for doc/tags (used with :help). -- Add runtime from build dir for doc/tags (used with :help).
module.command(string.format([[set rtp+=%s/runtime]], module.paths.test_build_dir)) M.command(string.format([[set rtp+=%s/runtime]], M.paths.test_build_dir))
end end
--- Kill (reap) a process by PID. --- Kill (reap) a process by PID.
--- @param pid string --- @param pid string
--- @return boolean? --- @return boolean?
function module.os_kill(pid) function M.os_kill(pid)
return os.execute( return os.execute(
( (
is_os('win') and 'taskkill /f /t /pid ' .. pid .. ' > nul' is_os('win') and 'taskkill /f /t /pid ' .. pid .. ' > nul'
@ -1018,7 +1018,7 @@ end
--- Create folder with non existing parents --- Create folder with non existing parents
--- @param path string --- @param path string
--- @return boolean? --- @return boolean?
function module.mkdir_p(path) function M.mkdir_p(path)
return os.execute((is_os('win') and 'mkdir ' .. path or 'mkdir -p ' .. path)) return os.execute((is_os('win') and 'mkdir ' .. path or 'mkdir -p ' .. path))
end end
@ -1059,5 +1059,5 @@ return function()
end end
end) end)
end end
return module return M
end end

View File

@ -17,7 +17,7 @@ local function shell_quote(str)
end end
--- @class test.testutil --- @class test.testutil
local module = { local M = {
paths = Paths, paths = Paths,
} }
@ -30,7 +30,7 @@ end
--- @param path string --- @param path string
--- @return boolean --- @return boolean
function module.isdir(path) function M.isdir(path)
if not path then if not path then
return false return false
end end
@ -43,7 +43,7 @@ end
--- @param ... string|string[] --- @param ... string|string[]
--- @return string --- @return string
function module.argss_to_cmd(...) function M.argss_to_cmd(...)
local cmd = {} --- @type string[] local cmd = {} --- @type string[]
for i = 1, select('#', ...) do for i = 1, select('#', ...) do
local arg = select(i, ...) local arg = select(i, ...)
@ -59,8 +59,8 @@ function module.argss_to_cmd(...)
return table.concat(cmd, ' ') return table.concat(cmd, ' ')
end end
function module.popen_r(...) function M.popen_r(...)
return io.popen(module.argss_to_cmd(...), 'r') return io.popen(M.argss_to_cmd(...), 'r')
end end
--- Calls fn() until it succeeds, up to `max` times or until `max_ms` --- Calls fn() until it succeeds, up to `max` times or until `max_ms`
@ -69,7 +69,7 @@ end
--- @param max_ms integer? --- @param max_ms integer?
--- @param fn function --- @param fn function
--- @return any --- @return any
function module.retry(max, max_ms, fn) function M.retry(max, max_ms, fn)
luaassert(max == nil or max > 0) luaassert(max == nil or max > 0)
luaassert(max_ms == nil or max_ms > 0) luaassert(max_ms == nil or max_ms > 0)
local tries = 1 local tries = 1
@ -96,10 +96,10 @@ local check_logs_useless_lines = {
['See README_MISSING_SYSCALL_OR_IOCTL for guidance'] = 3, ['See README_MISSING_SYSCALL_OR_IOCTL for guidance'] = 3,
} }
function module.eq(expected, actual, context) function M.eq(expected, actual, context)
return luaassert.are.same(expected, actual, context) return luaassert.are.same(expected, actual, context)
end end
function module.neq(expected, actual, context) function M.neq(expected, actual, context)
return luaassert.are_not.same(expected, actual, context) return luaassert.are_not.same(expected, actual, context)
end end
@ -108,7 +108,7 @@ end
--- @param cond (boolean) expression to assert --- @param cond (boolean) expression to assert
--- @param expected (any) description of expected result --- @param expected (any) description of expected result
--- @param actual (any) description of actual result --- @param actual (any) description of actual result
function module.ok(cond, expected, actual) function M.ok(cond, expected, actual)
luaassert( luaassert(
(not expected and not actual) or (expected and actual), (not expected and not actual) or (expected and actual),
'if "expected" is given, "actual" is also required' 'if "expected" is given, "actual" is also required'
@ -122,14 +122,14 @@ local function epicfail(state, arguments, _)
return false return false
end end
luaassert:register('assertion', 'epicfail', epicfail) luaassert:register('assertion', 'epicfail', epicfail)
function module.fail(msg) function M.fail(msg)
return luaassert.epicfail(msg) return luaassert.epicfail(msg)
end end
--- @param pat string --- @param pat string
--- @param actual string --- @param actual string
--- @return boolean --- @return boolean
function module.matches(pat, actual) function M.matches(pat, actual)
if nil ~= string.match(actual, pat) then if nil ~= string.match(actual, pat) then
return true return true
end end
@ -144,14 +144,14 @@ end
---@param logfile? (string) Full path to log file (default=$NVIM_LOG_FILE) ---@param logfile? (string) Full path to log file (default=$NVIM_LOG_FILE)
---@param nrlines? (number) Search up to this many log lines ---@param nrlines? (number) Search up to this many log lines
---@param inverse? (boolean) Assert that the pattern does NOT match. ---@param inverse? (boolean) Assert that the pattern does NOT match.
function module.assert_log(pat, logfile, nrlines, inverse) function M.assert_log(pat, logfile, nrlines, inverse)
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog' logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
luaassert(logfile ~= nil, 'no logfile') luaassert(logfile ~= nil, 'no logfile')
nrlines = nrlines or 10 nrlines = nrlines or 10
inverse = inverse or false inverse = inverse or false
module.retry(nil, 1000, function() M.retry(nil, 1000, function()
local lines = module.read_file_list(logfile, -nrlines) or {} local lines = M.read_file_list(logfile, -nrlines) or {}
local msg = string.format( local msg = string.format(
'Pattern %q %sfound in log (last %d lines): %s:\n%s', 'Pattern %q %sfound in log (last %d lines): %s:\n%s',
pat, pat,
@ -181,14 +181,14 @@ end
--- @param pat (string) Lua pattern to match lines in the log file --- @param pat (string) Lua pattern to match lines in the log file
--- @param logfile? (string) Full path to log file (default=$NVIM_LOG_FILE) --- @param logfile? (string) Full path to log file (default=$NVIM_LOG_FILE)
--- @param nrlines? (number) Search up to this many log lines --- @param nrlines? (number) Search up to this many log lines
function module.assert_nolog(pat, logfile, nrlines) function M.assert_nolog(pat, logfile, nrlines)
return module.assert_log(pat, logfile, nrlines, true) return M.assert_log(pat, logfile, nrlines, true)
end end
--- @param fn fun(...): any --- @param fn fun(...): any
--- @param ... any --- @param ... any
--- @return boolean, any --- @return boolean, any
function module.pcall(fn, ...) function M.pcall(fn, ...)
luaassert(type(fn) == 'function') luaassert(type(fn) == 'function')
local status, rv = pcall(fn, ...) local status, rv = pcall(fn, ...)
if status then if status then
@ -237,9 +237,9 @@ end
-- --
--- @param fn function --- @param fn function
--- @return string --- @return string
function module.pcall_err_withfile(fn, ...) function M.pcall_err_withfile(fn, ...)
luaassert(type(fn) == 'function') luaassert(type(fn) == 'function')
local status, rv = module.pcall(fn, ...) local status, rv = M.pcall(fn, ...)
if status == true then if status == true then
error('expected failure, but got success') error('expected failure, but got success')
end end
@ -249,8 +249,8 @@ end
--- @param fn function --- @param fn function
--- @param ... any --- @param ... any
--- @return string --- @return string
function module.pcall_err_withtrace(fn, ...) function M.pcall_err_withtrace(fn, ...)
local errmsg = module.pcall_err_withfile(fn, ...) local errmsg = M.pcall_err_withfile(fn, ...)
return ( return (
errmsg errmsg
@ -263,20 +263,20 @@ end
--- @param fn function --- @param fn function
--- @param ... any --- @param ... any
--- @return string --- @return string
function module.pcall_err(fn, ...) function M.pcall_err(fn, ...)
return module.remove_trace(module.pcall_err_withtrace(fn, ...)) return M.remove_trace(M.pcall_err_withtrace(fn, ...))
end end
--- @param s string --- @param s string
--- @return string --- @return string
function module.remove_trace(s) function M.remove_trace(s)
return (s:gsub('\n%s*stack traceback:.*', '')) return (s:gsub('\n%s*stack traceback:.*', ''))
end end
-- initial_path: directory to recurse into -- initial_path: directory to recurse into
-- re: include pattern (string) -- re: include pattern (string)
-- exc_re: exclude pattern(s) (string or table) -- exc_re: exclude pattern(s) (string or table)
function module.glob(initial_path, re, exc_re) function M.glob(initial_path, re, exc_re)
exc_re = type(exc_re) == 'table' and exc_re or { exc_re } exc_re = type(exc_re) == 'table' and exc_re or { exc_re }
local paths_to_check = { initial_path } --- @type string[] local paths_to_check = { initial_path } --- @type string[]
local ret = {} --- @type string[] local ret = {} --- @type string[]
@ -318,10 +318,10 @@ function module.glob(initial_path, re, exc_re)
return ret return ret
end end
function module.check_logs() function M.check_logs()
local log_dir = os.getenv('LOG_DIR') local log_dir = os.getenv('LOG_DIR')
local runtime_errors = {} local runtime_errors = {}
if log_dir and module.isdir(log_dir) then if log_dir and M.isdir(log_dir) then
for tail in vim.fs.dir(log_dir) do for tail in vim.fs.dir(log_dir) do
if tail:sub(1, 30) == 'valgrind-' or tail:find('san%.') then if tail:sub(1, 30) == 'valgrind-' or tail:find('san%.') then
local file = log_dir .. '/' .. tail local file = log_dir .. '/' .. tail
@ -343,7 +343,7 @@ function module.check_logs()
local status, f local status, f
local out = io.stdout local out = io.stdout
if os.getenv('SYMBOLIZER') then if os.getenv('SYMBOLIZER') then
status, f = pcall(module.popen_r, os.getenv('SYMBOLIZER'), '-l', file) status, f = pcall(M.popen_r, os.getenv('SYMBOLIZER'), '-l', file)
end end
out:write(start_msg .. '\n') out:write(start_msg .. '\n')
if status then if status then
@ -368,22 +368,22 @@ function module.check_logs()
) )
end end
function module.sysname() function M.sysname()
return uv.os_uname().sysname:lower() return uv.os_uname().sysname:lower()
end end
--- @param s 'win'|'mac'|'freebsd'|'openbsd'|'bsd' --- @param s 'win'|'mac'|'freebsd'|'openbsd'|'bsd'
--- @return boolean --- @return boolean
function module.is_os(s) function M.is_os(s)
if not (s == 'win' or s == 'mac' or s == 'freebsd' or s == 'openbsd' or s == 'bsd') then if not (s == 'win' or s == 'mac' or s == 'freebsd' or s == 'openbsd' or s == 'bsd') then
error('unknown platform: ' .. tostring(s)) error('unknown platform: ' .. tostring(s))
end end
return not not ( return not not (
(s == 'win' and (module.sysname():find('windows') or module.sysname():find('mingw'))) (s == 'win' and (M.sysname():find('windows') or M.sysname():find('mingw')))
or (s == 'mac' and module.sysname() == 'darwin') or (s == 'mac' and M.sysname() == 'darwin')
or (s == 'freebsd' and module.sysname() == 'freebsd') or (s == 'freebsd' and M.sysname() == 'freebsd')
or (s == 'openbsd' and module.sysname() == 'openbsd') or (s == 'openbsd' and M.sysname() == 'openbsd')
or (s == 'bsd' and module.sysname():find('bsd')) or (s == 'bsd' and M.sysname():find('bsd'))
) )
end end
@ -402,7 +402,7 @@ local tmpname_id = 0
local tmpdir = tmpdir_get() local tmpdir = tmpdir_get()
--- Creates a new temporary file for use by tests. --- Creates a new temporary file for use by tests.
function module.tmpname() function M.tmpname()
if tmpdir_is_local(tmpdir) then if tmpdir_is_local(tmpdir) then
-- Cannot control os.tmpname() dir, so hack our own tmpname() impl. -- Cannot control os.tmpname() dir, so hack our own tmpname() impl.
tmpname_id = tmpname_id + 1 tmpname_id = tmpname_id + 1
@ -413,11 +413,11 @@ function module.tmpname()
end end
local fname = os.tmpname() local fname = os.tmpname()
if module.is_os('win') and fname:sub(1, 2) == '\\s' then if M.is_os('win') and fname:sub(1, 2) == '\\s' then
-- In Windows tmpname() returns a filename starting with -- In Windows tmpname() returns a filename starting with
-- special sequence \s, prepend $TEMP path -- special sequence \s, prepend $TEMP path
return tmpdir .. fname return tmpdir .. fname
elseif module.is_os('mac') and fname:match('^/tmp') then elseif M.is_os('mac') and fname:match('^/tmp') then
-- In OS X /tmp links to /private/tmp -- In OS X /tmp links to /private/tmp
return '/private' .. fname return '/private' .. fname
end end
@ -432,7 +432,7 @@ end
local tests_skipped = 0 local tests_skipped = 0
function module.check_cores(app, force) -- luacheck: ignore function M.check_cores(app, force) -- luacheck: ignore
-- Temporary workaround: skip core check as it interferes with CI. -- Temporary workaround: skip core check as it interferes with CI.
if true then if true then
return return
@ -459,14 +459,14 @@ function module.check_cores(app, force) -- luacheck: ignore
exc_re = { os.getenv('NVIM_TEST_CORE_EXC_RE'), local_tmpdir } exc_re = { os.getenv('NVIM_TEST_CORE_EXC_RE'), local_tmpdir }
db_cmd = os.getenv('NVIM_TEST_CORE_DB_CMD') or gdb_db_cmd db_cmd = os.getenv('NVIM_TEST_CORE_DB_CMD') or gdb_db_cmd
random_skip = os.getenv('NVIM_TEST_CORE_RANDOM_SKIP') ~= '' random_skip = os.getenv('NVIM_TEST_CORE_RANDOM_SKIP') ~= ''
elseif module.is_os('mac') then elseif M.is_os('mac') then
initial_path = '/cores' initial_path = '/cores'
re = nil re = nil
exc_re = { local_tmpdir } exc_re = { local_tmpdir }
db_cmd = lldb_db_cmd db_cmd = lldb_db_cmd
else else
initial_path = '.' initial_path = '.'
if module.is_os('freebsd') then if M.is_os('freebsd') then
re = '/nvim.core$' re = '/nvim.core$'
else else
re = '/core[^/]*$' re = '/core[^/]*$'
@ -480,7 +480,7 @@ function module.check_cores(app, force) -- luacheck: ignore
tests_skipped = tests_skipped + 1 tests_skipped = tests_skipped + 1
return return
end end
local cores = module.glob(initial_path, re, exc_re) local cores = M.glob(initial_path, re, exc_re)
local found_cores = 0 local found_cores = 0
local out = io.stdout local out = io.stdout
for _, core in ipairs(cores) do for _, core in ipairs(cores) do
@ -503,23 +503,23 @@ function module.check_cores(app, force) -- luacheck: ignore
end end
--- @return string? --- @return string?
function module.repeated_read_cmd(...) function M.repeated_read_cmd(...)
for _ = 1, 10 do for _ = 1, 10 do
local stream = module.popen_r(...) local stream = M.popen_r(...)
local ret = stream:read('*a') local ret = stream:read('*a')
stream:close() stream:close()
if ret then if ret then
return ret return ret
end end
end end
print('ERROR: Failed to execute ' .. module.argss_to_cmd(...) .. ': nil return after 10 attempts') print('ERROR: Failed to execute ' .. M.argss_to_cmd(...) .. ': nil return after 10 attempts')
return nil return nil
end end
--- @generic T --- @generic T
--- @param orig T --- @param orig T
--- @return T --- @return T
function module.shallowcopy(orig) function M.shallowcopy(orig)
if type(orig) ~= 'table' then if type(orig) ~= 'table' then
return orig return orig
end end
@ -534,13 +534,13 @@ end
--- @param d1 table<any,any> --- @param d1 table<any,any>
--- @param d2 table<any,any> --- @param d2 table<any,any>
--- @return table<any,any> --- @return table<any,any>
function module.mergedicts_copy(d1, d2) function M.mergedicts_copy(d1, d2)
local ret = module.shallowcopy(d1) local ret = M.shallowcopy(d1)
for k, v in pairs(d2) do for k, v in pairs(d2) do
if d2[k] == vim.NIL then if d2[k] == vim.NIL then
ret[k] = nil ret[k] = nil
elseif type(d1[k]) == 'table' and type(v) == 'table' then elseif type(d1[k]) == 'table' and type(v) == 'table' then
ret[k] = module.mergedicts_copy(d1[k], v) ret[k] = M.mergedicts_copy(d1[k], v)
else else
ret[k] = v ret[k] = v
end end
@ -553,7 +553,7 @@ end
--- Note: does not do copies of d2 values used. --- Note: does not do copies of d2 values used.
--- @param d1 table<any,any> --- @param d1 table<any,any>
--- @param d2 table<any,any> --- @param d2 table<any,any>
function module.dictdiff(d1, d2) function M.dictdiff(d1, d2)
local ret = {} --- @type table<any,any> local ret = {} --- @type table<any,any>
local hasdiff = false local hasdiff = false
for k, v in pairs(d1) do for k, v in pairs(d1) do
@ -562,7 +562,7 @@ function module.dictdiff(d1, d2)
ret[k] = vim.NIL ret[k] = vim.NIL
elseif type(v) == type(d2[k]) then elseif type(v) == type(d2[k]) then
if type(v) == 'table' then if type(v) == 'table' then
local subdiff = module.dictdiff(v, d2[k]) local subdiff = M.dictdiff(v, d2[k])
if subdiff ~= nil then if subdiff ~= nil then
hasdiff = true hasdiff = true
ret[k] = subdiff ret[k] = subdiff
@ -576,7 +576,7 @@ function module.dictdiff(d1, d2)
hasdiff = true hasdiff = true
end end
end end
local shallowcopy = module.shallowcopy local shallowcopy = M.shallowcopy
for k, v in pairs(d2) do for k, v in pairs(d2) do
if d1[k] == nil then if d1[k] == nil then
ret[k] = shallowcopy(v) ret[k] = shallowcopy(v)
@ -591,7 +591,7 @@ function module.dictdiff(d1, d2)
end end
-- Concat list-like tables. -- Concat list-like tables.
function module.concat_tables(...) function M.concat_tables(...)
local ret = {} --- @type table<any,any> local ret = {} --- @type table<any,any>
for i = 1, select('#', ...) do for i = 1, select('#', ...) do
--- @type table<any,any> --- @type table<any,any>
@ -608,7 +608,7 @@ end
--- @param str string --- @param str string
--- @param leave_indent? integer --- @param leave_indent? integer
--- @return string --- @return string
function module.dedent(str, leave_indent) function M.dedent(str, leave_indent)
-- find minimum common indent across lines -- find minimum common indent across lines
local indent --- @type string? local indent --- @type string?
for line in str:gmatch('[^\n]+') do for line in str:gmatch('[^\n]+') do
@ -633,14 +633,14 @@ function module.dedent(str, leave_indent)
return str return str
end end
function module.intchar2lua(ch) function M.intchar2lua(ch)
ch = tonumber(ch) ch = tonumber(ch)
return (20 <= ch and ch < 127) and ('%c'):format(ch) or ch return (20 <= ch and ch < 127) and ('%c'):format(ch) or ch
end end
--- @param str string --- @param str string
--- @return string --- @return string
function module.hexdump(str) function M.hexdump(str)
local len = string.len(str) local len = string.len(str)
local dump = '' local dump = ''
local hex = '' local hex = ''
@ -669,7 +669,7 @@ end
--- @param filename string path to file --- @param filename string path to file
--- @param start? integer start line (1-indexed), negative means "lines before end" (tail) --- @param start? integer start line (1-indexed), negative means "lines before end" (tail)
--- @return string[]? --- @return string[]?
function module.read_file_list(filename, start) function M.read_file_list(filename, start)
local lnum = (start ~= nil and type(start) == 'number') and start or 1 local lnum = (start ~= nil and type(start) == 'number') and start or 1
local tail = (lnum < 0) local tail = (lnum < 0)
local maxlines = tail and math.abs(lnum) or nil local maxlines = tail and math.abs(lnum) or nil
@ -707,7 +707,7 @@ end
--- Reads the entire contents of `filename` into a string. --- Reads the entire contents of `filename` into a string.
--- @param filename string --- @param filename string
--- @return string? --- @return string?
function module.read_file(filename) function M.read_file(filename)
local file = io.open(filename, 'r') local file = io.open(filename, 'r')
if not file then if not file then
return nil return nil
@ -718,7 +718,7 @@ function module.read_file(filename)
end end
-- Dedent the given text and write it to the file name. -- Dedent the given text and write it to the file name.
function module.write_file(name, text, no_dedent, append) function M.write_file(name, text, no_dedent, append)
local file = assert(io.open(name, (append and 'a' or 'w'))) local file = assert(io.open(name, (append and 'a' or 'w')))
if type(text) == 'table' then if type(text) == 'table' then
-- Byte blob -- Byte blob
@ -729,7 +729,7 @@ function module.write_file(name, text, no_dedent, append)
text = ('%s%c'):format(text, char) text = ('%s%c'):format(text, char)
end end
elseif not no_dedent then elseif not no_dedent then
text = module.dedent(text) text = M.dedent(text)
end end
file:write(text) file:write(text)
file:flush() file:flush()
@ -738,7 +738,7 @@ end
--- @param name? 'cirrus'|'github' --- @param name? 'cirrus'|'github'
--- @return boolean --- @return boolean
function module.is_ci(name) function M.is_ci(name)
local any = (name == nil) local any = (name == nil)
luaassert(any or name == 'github' or name == 'cirrus') luaassert(any or name == 'github' or name == 'cirrus')
local gh = ((any or name == 'github') and nil ~= os.getenv('GITHUB_ACTIONS')) local gh = ((any or name == 'github') and nil ~= os.getenv('GITHUB_ACTIONS'))
@ -748,11 +748,11 @@ end
-- Gets the (tail) contents of `logfile`. -- Gets the (tail) contents of `logfile`.
-- Also moves the file to "${NVIM_LOG_FILE}.displayed" on CI environments. -- Also moves the file to "${NVIM_LOG_FILE}.displayed" on CI environments.
function module.read_nvim_log(logfile, ci_rename) function M.read_nvim_log(logfile, ci_rename)
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog' logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
local is_ci = module.is_ci() local is_ci = M.is_ci()
local keep = is_ci and 100 or 10 local keep = is_ci and 100 or 10
local lines = module.read_file_list(logfile, -keep) or {} local lines = M.read_file_list(logfile, -keep) or {}
local log = ( local log = (
('-'):rep(78) ('-'):rep(78)
.. '\n' .. '\n'
@ -771,9 +771,9 @@ end
--- @param path string --- @param path string
--- @return boolean? --- @return boolean?
function module.mkdir(path) function M.mkdir(path)
-- 493 is 0755 in decimal -- 493 is 0755 in decimal
return (uv.fs_mkdir(path, 493)) return (uv.fs_mkdir(path, 493))
end end
return module return M

View File

@ -877,7 +877,7 @@ local function is_asan()
end end
--- @class test.unit.testutil.module --- @class test.unit.testutil.module
local module = { local M = {
cimport = cimport, cimport = cimport,
cppimport = cppimport, cppimport = cppimport,
internalize = internalize, internalize = internalize,
@ -907,6 +907,6 @@ local module = {
is_asan = is_asan, is_asan = is_asan,
} }
--- @class test.unit.testutil: test.unit.testutil.module, test.testutil --- @class test.unit.testutil: test.unit.testutil.module, test.testutil
module = vim.tbl_extend('error', module, t_global) M = vim.tbl_extend('error', M, t_global)
return module return M