refactor(tests): merge n.spawn/n.spawn_argv into n.new_session #31859

Problem:
- `n.spawn()` is misleading because it also connects RPC, it's not just
  "spawning" a process.
- It's confusing that `n.spawn()` and `n.spawn_argv()` are separate.

Solution:
- Replace `n.spawn()`/`n.spawn_argv()` with a single function `n.new_session()`.
  This name aligns with the existing functions `n.set_session`/`n.get_session`.
    - Note: removes direct handling of `prepend_argv`, but I doubt that was
      important or intentional. If callers want to control use of `prepend_argv`
      then we should add a new flag to `test.session.Opts`.
- Move `keep` to first parameter of `n.new_session()`.
- Add a `merge` flag to `test.session.Opts`
- Mark `_new_argv()` as private. Test should use clear/new_session/spawn_wait
  instead.
This commit is contained in:
Justin M. Keyes
2025-01-04 16:48:00 -08:00
committed by GitHub
parent a8ace2c58a
commit 64b0e6582a
11 changed files with 110 additions and 122 deletions

View File

@@ -455,23 +455,6 @@ function M.check_close()
session = nil
end
--- Starts `argv` process as a Nvim msgpack-RPC session.
---
--- @param argv string[]
--- @param merge boolean?
--- @param env string[]?
--- @param keep boolean? Don't close the current global session.
--- @param io_extra uv.uv_pipe_t? used for stdin_fd, see :help ui-option
--- @return test.Session
function M.spawn(argv, merge, env, keep, io_extra)
if not keep then
M.check_close()
end
local proc = ProcStream.spawn(merge and M.merge_args(prepend_argv, argv) or argv, env, io_extra)
return Session.new(proc)
end
-- Creates a new Session connected by domain socket (named pipe) or TCP.
function M.connect(file_or_address)
local addr, port = string.match(file_or_address, '(.*):(%d+)')
@@ -480,9 +463,9 @@ function M.connect(file_or_address)
return Session.new(stream)
end
--- Starts (and returns) a new global Nvim session.
--- Starts a new, global Nvim session and clears the current one.
---
--- Use `spawn_argv()` to get a new session without replacing the current global session.
--- Note: Use `new_session()` to start a session without replacing the current one.
---
--- Parameters are interpreted as startup args, OR a map with these keys:
--- - args: List: Args appended to the default `nvim_argv` set.
@@ -499,33 +482,41 @@ end
---
--- @param ... string Nvim CLI args
--- @return test.Session
--- @overload fun(opts: test.new_argv.Opts): test.Session
--- @overload fun(opts: test.session.Opts): test.Session
function M.clear(...)
M.set_session(M.spawn_argv(false, ...))
M.set_session(M.new_session(false, ...))
return M.get_session()
end
--- Same as clear(), but doesn't replace the current global session.
--- Starts a new Nvim process with the given args and returns a msgpack-RPC session.
---
--- @param keep boolean Don't close the current global session.
--- @param ... string Nvim CLI args
--- Does not replace the current global session, unlike `clear()`.
---
--- @param keep boolean (default: false) Don't close the current global session.
--- @param ... string Nvim CLI args (or see overload)
--- @return test.Session
--- @overload fun(opts: test.new_argv.Opts): test.Session
function M.spawn_argv(keep, ...)
local argv, env, io_extra = M.new_argv(...)
return M.spawn(argv, nil, env, keep, io_extra)
--- @overload fun(keep: boolean, opts: test.session.Opts): test.Session
function M.new_session(keep, ...)
if not keep then
M.check_close()
end
local argv, env, io_extra = M._new_argv(...)
local proc = ProcStream.spawn(argv, env, io_extra)
return Session.new(proc)
end
--- Starts a (non-RPC, `--headless --listen "Tx"`) Nvim process, waits for exit, and returns result.
---
--- @param ... string Nvim CLI args
--- @param ... string Nvim CLI args, or `test.session.Opts` table.
--- @return test.ProcStream
--- @overload fun(opts: test.new_argv.Opts): test.ProcStream
--- @overload fun(opts: test.session.Opts): test.ProcStream
function M.spawn_wait(...)
local opts = type(...) == 'string' and { args = { ... } } or ...
opts.args_rm = opts.args_rm and opts.args_rm or {}
table.insert(opts.args_rm, '--embed')
local argv, env, io_extra = M.new_argv(opts)
local argv, env, io_extra = M._new_argv(opts)
local proc = ProcStream.spawn(argv, env, io_extra)
proc.collect_text = true
proc:read_start()
@@ -534,36 +525,50 @@ function M.spawn_wait(...)
return proc
end
--- @class test.new_argv.Opts
--- @class test.session.Opts
--- Nvim CLI args
--- @field args? string[]
--- Remove these args from the default `nvim_argv` args set. Ignored if `merge=false`.
--- @field args_rm? string[]
--- (default: true) Merge `args` with the default set. Else use only the provided `args`.
--- @field merge? boolean
--- Environment variables
--- @field env? table<string,string>
--- Used for stdin_fd, see `:help ui-option`
--- @field io_extra? uv.uv_pipe_t
--- Builds an argument list for use in clear().
--- @private
---
--- @param ... string See clear().
--- Builds an argument list for use in `new_session()`, `clear()`, and `spawn_wait()`.
---
--- @param ... string Nvim CLI args, or `test.session.Opts` table.
--- @return string[]
--- @return string[]?
--- @return uv.uv_pipe_t?
--- @overload fun(opts: test.new_argv.Opts): string[], string[]?, uv.uv_pipe_t?
function M.new_argv(...)
local args = { unpack(M.nvim_argv) }
table.insert(args, '--headless')
if _G._nvim_test_id then
-- Set the server name to the test-id for logging. #8519
table.insert(args, '--listen')
table.insert(args, _G._nvim_test_id)
--- @overload fun(opts: test.session.Opts): string[], string[]?, uv.uv_pipe_t?
function M._new_argv(...)
--- @type test.session.Opts|string
local opts = select(1, ...)
local merge = type(opts) ~= 'table' and true or opts.merge ~= false
local args = merge and { unpack(M.nvim_argv) } or { M.nvim_prog }
if merge then
table.insert(args, '--headless')
if _G._nvim_test_id then
-- Set the server name to the test-id for logging. #8519
table.insert(args, '--listen')
table.insert(args, _G._nvim_test_id)
end
end
local new_args --- @type string[]
local io_extra --- @type uv.uv_pipe_t?
local env --- @type string[]?
--- @type test.new_argv.Opts|string
local opts = select(1, ...)
local env --- @type string[]? List of "key=value" env vars.
if type(opts) ~= 'table' then
new_args = { ... }
else
args = remove_args(args, opts.args_rm)
args = merge and remove_args(args, opts.args_rm) or args
if opts.env then
local env_opt = {} --- @type table<string,string>
for k, v in pairs(opts.env) do