Files
neovim/test/runner.lua
Lewis Russell 9432e6c1e2 test: run Lua harness with nvim -l
Problem:
The Lua test harness still ran through standalone -ll mode, so tests
depended on the low-level Lua path instead of the regular Nvim Lua
environment. That also meant os.exit() coverage had to carry an ASAN
workaround because Lua's raw process exit skipped Nvim teardown and let
LeakSanitizer interfere with the observed exit code.

Solution:
Run the harness and related fixtures with nvim -l. Patch os.exit() in
the main Lua state to exit through getout(), so scripts observe normal
Nvim shutdown while standalone -ll remains available for generator-style
scripts. As a consequence, the startup test can assert os.exit() without
disabling leak detection.

AI-assisted: Codex
2026-05-13 13:14:07 +01:00

42 lines
1.3 KiB
Lua

local uv = vim.uv
---@return string
local function repo_root()
local source = debug.getinfo(1, 'S').source
assert(type(source) == 'string' and vim.startswith(source, '@'), 'failed to resolve runner path')
local script_path = assert(uv.fs_realpath(source:sub(2)), 'failed to resolve runner path')
return vim.fs.dirname(vim.fs.dirname(script_path))
end
---@param roots string[]
local function prepend_package_roots(roots)
local entries = {}
for _, root in ipairs(roots) do
entries[#entries + 1] = root .. '/?.lua'
entries[#entries + 1] = root .. '/?/init.lua'
end
package.path = table.concat(entries, ';') .. ';' .. package.path
end
_G.c_include_path = {}
while _G.arg[1] and vim.startswith(_G.arg[1], '-I') do
table.insert(_G.c_include_path, string.sub(table.remove(_G.arg, 1), 3))
end
local root = repo_root()
prepend_package_roots({ root, root .. '/test', '.', './test' })
-- The harness is not an Nvim instance under test. If its startup server stays
-- visible, serverlist({ peer = true }) can connect back to the runner and wait
-- forever for an RPC response.
if vim.v.servername ~= '' then
assert(vim.fn.serverstop(vim.v.servername) == 1)
end
local exit_code = require('test.harness').main(_G.arg)
io.stdout:flush()
io.stderr:flush()
os.exit(exit_code)