aboutsummaryrefslogtreecommitdiff
path: root/test/functional/core
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/core')
-rw-r--r--test/functional/core/channels_spec.lua250
-rw-r--r--test/functional/core/exit_spec.lua19
-rw-r--r--test/functional/core/fileio_spec.lua258
-rw-r--r--test/functional/core/job_spec.lua778
-rw-r--r--test/functional/core/log_spec.lua16
-rw-r--r--test/functional/core/main_spec.lua167
-rw-r--r--test/functional/core/path_spec.lua50
-rw-r--r--test/functional/core/remote_spec.lua39
-rw-r--r--test/functional/core/spellfile_spec.lua55
-rw-r--r--test/functional/core/startup_spec.lua907
10 files changed, 1578 insertions, 961 deletions
diff --git a/test/functional/core/channels_spec.lua b/test/functional/core/channels_spec.lua
index 5771ddcb94..56a2f5a571 100644
--- a/test/functional/core/channels_spec.lua
+++ b/test/functional/core/channels_spec.lua
@@ -1,10 +1,10 @@
local helpers = require('test.functional.helpers')(after_each)
-local clear, eq, eval, next_msg, ok, source = helpers.clear, helpers.eq,
- helpers.eval, helpers.next_msg, helpers.ok, helpers.source
-local command, funcs, meths = helpers.command, helpers.funcs, helpers.meths
-local sleep = helpers.sleep
+local clear, eq, eval, next_msg, ok, source =
+ helpers.clear, helpers.eq, helpers.eval, helpers.next_msg, helpers.ok, helpers.source
+local command, fn, api = helpers.command, helpers.fn, helpers.api
+local sleep = vim.uv.sleep
local spawn, nvim_argv = helpers.spawn, helpers.nvim_argv
-local set_session = helpers.set_session
+local get_session, set_session = helpers.get_session, helpers.set_session
local nvim_prog = helpers.nvim_prog
local is_os = helpers.is_os
local retry = helpers.retry
@@ -33,31 +33,67 @@ describe('channels', function()
pending('can connect to socket', function()
local server = spawn(nvim_argv, nil, nil, true)
set_session(server)
- local address = funcs.serverlist()[1]
+ local address = fn.serverlist()[1]
local client = spawn(nvim_argv, nil, nil, true)
set_session(client)
source(init)
- meths.set_var('address', address)
+ api.nvim_set_var('address', address)
command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})")
- local id = eval("g:id")
+ local id = eval('g:id')
ok(id > 0)
command("call chansend(g:id, msgpackdump([[2,'nvim_set_var',['code',23]]]))")
set_session(server)
retry(nil, 1000, function()
- eq(23, meths.get_var('code'))
+ eq(23, api.nvim_get_var('code'))
end)
set_session(client)
command("call chansend(g:id, msgpackdump([[0,0,'nvim_eval',['2+3']]]))")
-
- local res = eval("msgpackdump([[1,0,v:null,5]])")
- eq({"\148\001\n\192\005"}, res)
- eq({'notification', 'data', {id, res}}, next_msg())
+ local res = eval('msgpackdump([[1,0,v:null,5]])')
+ eq({ '\148\001\n\192\005' }, res)
+ eq({ 'notification', 'data', { id, res } }, next_msg())
command("call chansend(g:id, msgpackdump([[2,'nvim_command',['quit']]]))")
- eq({'notification', 'data', {id, {''}}}, next_msg())
+ eq({ 'notification', 'data', { id, { '' } } }, next_msg())
+ end)
+
+ it('dont crash due to garbage in rpc #23781', function()
+ local client = get_session()
+ local server = spawn(nvim_argv, nil, nil, true)
+ set_session(server)
+ local address = fn.serverlist()[1]
+ set_session(client)
+
+ api.nvim_set_var('address', address)
+ command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})")
+ local id = eval('g:id')
+ ok(id > 0)
+
+ command("call chansend(g:id, 'F')")
+ eq({ 'notification', 'data', { id, { '' } } }, next_msg())
+ set_session(server)
+ assert_alive()
+
+ set_session(client)
+ command('call chanclose(g:id)')
+ command("let g:id = sockconnect('pipe', address, {'on_data':'OnEvent'})")
+ id = eval('g:id')
+ ok(id > 0)
+
+ command("call chansend(g:id, msgpackdump([[2, 'redraw', 'F']], 'B')[:-4])")
+ set_session(server)
+ assert_alive()
+ set_session(client)
+ command("call chansend(g:id, 'F')")
+ eq({ 'notification', 'data', { id, { '' } } }, next_msg())
+
+ set_session(server)
+ assert_alive()
+ set_session(client)
+ command('call chanclose(g:id)')
+ server:close()
end)
it('can use stdio channel', function()
@@ -68,8 +104,10 @@ describe('channels', function()
\ 'on_exit': function('OnEvent'),
\ }
]])
- meths.set_var("nvim_prog", nvim_prog)
- meths.set_var("code", [[
+ api.nvim_set_var('nvim_prog', nvim_prog)
+ api.nvim_set_var(
+ 'code',
+ [[
function! OnEvent(id, data, event) dict
let text = string([a:id, a:data, a:event])
call chansend(g:x, text)
@@ -81,25 +119,31 @@ describe('channels', function()
endfunction
let g:x = stdioopen({'on_stdin':'OnEvent'})
call chansend(x, "hello")
- ]])
- command("let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)")
- local id = eval("g:id")
+ ]]
+ )
+ command(
+ "let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)"
+ )
+ local id = eval('g:id')
ok(id > 0)
- eq({ "notification", "stdout", {id, { "hello" } } }, next_msg())
+ eq({ 'notification', 'stdout', { id, { 'hello' } } }, next_msg())
command("call chansend(id, 'howdy')")
- eq({"notification", "stdout", {id, {"[1, ['howdy'], 'stdin']"}}}, next_msg())
+ eq({ 'notification', 'stdout', { id, { "[1, ['howdy'], 'stdin']" } } }, next_msg())
- command("call chansend(id, 0z686f6c61)")
- eq({"notification", "stdout", {id, {"[1, ['hola'], 'stdin']"}}}, next_msg())
+ command('call chansend(id, 0z686f6c61)')
+ eq({ 'notification', 'stdout', { id, { "[1, ['hola'], 'stdin']" } } }, next_msg())
command("call chanclose(id, 'stdin')")
- expect_twostreams({{"notification", "stdout", {id, {"[1, [''], 'stdin']"}}},
- {'notification', 'stdout', {id, {''}}}},
- {{"notification", "stderr", {id, {"*dies*"}}},
- {'notification', 'stderr', {id, {''}}}})
- eq({"notification", "exit", {3,0}}, next_msg())
+ expect_twostreams({
+ { 'notification', 'stdout', { id, { "[1, [''], 'stdin']" } } },
+ { 'notification', 'stdout', { id, { '' } } },
+ }, {
+ { 'notification', 'stderr', { id, { '*dies*' } } },
+ { 'notification', 'stderr', { id, { '' } } },
+ })
+ eq({ 'notification', 'exit', { 3, 0 } }, next_msg())
end)
it('can use stdio channel and on_print callback', function()
@@ -110,8 +154,10 @@ describe('channels', function()
\ 'on_exit': function('OnEvent'),
\ }
]])
- meths.set_var("nvim_prog", nvim_prog)
- meths.set_var("code", [[
+ api.nvim_set_var('nvim_prog', nvim_prog)
+ api.nvim_set_var(
+ 'code',
+ [[
function! OnStdin(id, data, event) dict
echo string([a:id, a:data, a:event])
if a:data == ['']
@@ -123,24 +169,27 @@ describe('channels', function()
endfunction
let g:x = stdioopen({'on_stdin': funcref('OnStdin'), 'on_print':'OnPrint'})
call chansend(x, "hello")
- ]])
- command("let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)")
- local id = eval("g:id")
+ ]]
+ )
+ command(
+ "let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)"
+ )
+ local id = eval('g:id')
ok(id > 0)
- eq({ "notification", "stdout", {id, { "hello" } } }, next_msg())
+ eq({ 'notification', 'stdout', { id, { 'hello' } } }, next_msg())
command("call chansend(id, 'howdy')")
- eq({"notification", "stdout", {id, {"OnPrint:[1, ['howdy'], 'stdin']"}}}, next_msg())
+ eq({ 'notification', 'stdout', { id, { "OnPrint:[1, ['howdy'], 'stdin']" } } }, next_msg())
end)
local function expect_twoline(id, stream, line1, line2, nobr)
local msg = next_msg()
- local joined = nobr and {line1..line2} or {line1, line2}
- if not pcall(eq, {"notification", stream, {id, joined}}, msg) then
- local sep = (not nobr) and "" or nil
- eq({"notification", stream, {id, {line1, sep}}}, msg)
- eq({"notification", stream, {id, {line2}}}, next_msg())
+ local joined = nobr and { line1 .. line2 } or { line1, line2 }
+ if not pcall(eq, { 'notification', stream, { id, joined } }, msg) then
+ local sep = (not nobr) and '' or nil
+ eq({ 'notification', stream, { id, { line1, sep } } }, msg)
+ eq({ 'notification', stream, { id, { line2 } } }, next_msg())
end
end
@@ -153,50 +202,52 @@ describe('channels', function()
\ 'pty': v:true,
\ }
]])
- meths.set_var("nvim_prog", nvim_prog)
- meths.set_var("code", [[
+ api.nvim_set_var('nvim_prog', nvim_prog)
+ api.nvim_set_var(
+ 'code',
+ [[
function! OnEvent(id, data, event) dict
let text = string([a:id, a:data, a:event])
call chansend(g:x, text)
endfunction
let g:x = stdioopen({'on_stdin':'OnEvent'})
- ]])
- command("let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)")
- local id = eval("g:id")
+ ]]
+ )
+ command(
+ "let g:id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)"
+ )
+ local id = eval('g:id')
ok(id > 0)
command("call chansend(id, 'TEXT\n')")
- expect_twoline(id, "stdout", "TEXT\r", "[1, ['TEXT', ''], 'stdin']")
+ expect_twoline(id, 'stdout', 'TEXT\r', "[1, ['TEXT', ''], 'stdin']")
- command("call chansend(id, 0z426c6f6273210a)")
- expect_twoline(id, "stdout", "Blobs!\r", "[1, ['Blobs!', ''], 'stdin']")
+ command('call chansend(id, 0z426c6f6273210a)')
+ expect_twoline(id, 'stdout', 'Blobs!\r', "[1, ['Blobs!', ''], 'stdin']")
command("call chansend(id, 'neovan')")
- eq({"notification", "stdout", {id, {"neovan"}}}, next_msg())
+ eq({ 'notification', 'stdout', { id, { 'neovan' } } }, next_msg())
command("call chansend(id, '\127\127im\n')")
- expect_twoline(id, "stdout", "\b \b\b \bim\r", "[1, ['neovim', ''], 'stdin']")
+ expect_twoline(id, 'stdout', '\b \b\b \bim\r', "[1, ['neovim', ''], 'stdin']")
command("call chansend(id, 'incomplet\004')")
local bsdlike = is_os('bsd') or is_os('mac')
- local extra = bsdlike and "^D\008\008" or ""
- expect_twoline(id, "stdout",
- "incomplet"..extra, "[1, ['incomplet'], 'stdin']", true)
-
+ local extra = bsdlike and '^D\008\008' or ''
+ expect_twoline(id, 'stdout', 'incomplet' .. extra, "[1, ['incomplet'], 'stdin']", true)
command("call chansend(id, '\004')")
if bsdlike then
- expect_twoline(id, "stdout", extra, "[1, [''], 'stdin']", true)
+ expect_twoline(id, 'stdout', extra, "[1, [''], 'stdin']", true)
else
- eq({"notification", "stdout", {id, {"[1, [''], 'stdin']"}}}, next_msg())
+ eq({ 'notification', 'stdout', { id, { "[1, [''], 'stdin']" } } }, next_msg())
end
-- channel is still open
command("call chansend(id, 'hi again!\n')")
- eq({"notification", "stdout", {id, {"hi again!\r", ""}}}, next_msg())
+ eq({ 'notification', 'stdout', { id, { 'hi again!\r', '' } } }, next_msg())
end)
-
it('stdio channel can use rpc and stderr simultaneously', function()
skip(is_os('win'))
source([[
@@ -206,31 +257,37 @@ describe('channels', function()
\ 'rpc': v:true,
\ }
]])
- meths.set_var("nvim_prog", nvim_prog)
- meths.set_var("code", [[
+ api.nvim_set_var('nvim_prog', nvim_prog)
+ api.nvim_set_var(
+ 'code',
+ [[
let id = stdioopen({'rpc':v:true})
call rpcnotify(id,"nvim_call_function", "rpcnotify", [1, "message", "hi there!", id])
call chansend(v:stderr, "trouble!")
- ]])
- command("let id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)")
- eq({"notification", "message", {"hi there!", 1}}, next_msg())
- eq({"notification", "stderr", {3, {"trouble!"}}}, next_msg())
+ ]]
+ )
+ command(
+ "let id = jobstart([ g:nvim_prog, '-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--headless', '--cmd', g:code], g:job_opts)"
+ )
+ eq({ 'notification', 'message', { 'hi there!', 1 } }, next_msg())
+ eq({ 'notification', 'stderr', { 3, { 'trouble!' } } }, next_msg())
eq(30, eval("rpcrequest(id, 'nvim_eval', '[chansend(v:stderr, \"math??\"), 5*6][1]')"))
- eq({"notification", "stderr", {3, {"math??"}}}, next_msg())
+ eq({ 'notification', 'stderr', { 3, { 'math??' } } }, next_msg())
- local _, err = pcall(command,"call rpcrequest(id, 'nvim_command', 'call chanclose(v:stderr, \"stdin\")')")
- ok(string.find(err,"E906: invalid stream for channel") ~= nil)
+ local _, err =
+ pcall(command, "call rpcrequest(id, 'nvim_command', 'call chanclose(v:stderr, \"stdin\")')")
+ ok(string.find(err, 'E906: invalid stream for channel') ~= nil)
eq(1, eval("rpcrequest(id, 'nvim_eval', 'chanclose(v:stderr, \"stderr\")')"))
- eq({"notification", "stderr", {3, {""}}}, next_msg())
+ eq({ 'notification', 'stderr', { 3, { '' } } }, next_msg())
command("call rpcnotify(id, 'nvim_command', 'quit')")
- eq({"notification", "exit", {3, 0}}, next_msg())
+ eq({ 'notification', 'exit', { 3, 0 } }, next_msg())
end)
it('can use buffered output mode', function()
- skip(funcs.executable('grep') == 0, 'missing "grep" command')
+ skip(fn.executable('grep') == 0, 'missing "grep" command')
source([[
let g:job_opts = {
\ 'on_stdout': function('OnEvent'),
@@ -239,31 +296,33 @@ describe('channels', function()
\ }
]])
command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)")
- local id = eval("g:id")
+ local id = eval('g:id')
command([[call chansend(id, "stuff\n10 PRINT \"NVIM\"\nxx")]])
sleep(10)
command([[call chansend(id, "xx\n20 GOTO 10\nzz\n")]])
command("call chanclose(id, 'stdin')")
- eq({"notification", "stdout", {id, {'10 PRINT "NVIM"',
- '20 GOTO 10', ''}}}, next_msg())
- eq({"notification", "exit", {id, 0}}, next_msg())
+ eq({
+ 'notification',
+ 'stdout',
+ { id, { '10 PRINT "NVIM"', '20 GOTO 10', '' } },
+ }, next_msg())
+ eq({ 'notification', 'exit', { id, 0 } }, next_msg())
command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)")
- id = eval("g:id")
+ id = eval('g:id')
command([[call chansend(id, "is no number\nnot at all")]])
command("call chanclose(id, 'stdin')")
-- works correctly with no output
- eq({"notification", "stdout", {id, {''}}}, next_msg())
- eq({"notification", "exit", {id, 1}}, next_msg())
-
+ eq({ 'notification', 'stdout', { id, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { id, 1 } }, next_msg())
end)
it('can use buffered output mode with no stream callback', function()
- skip(funcs.executable('grep') == 0, 'missing "grep" command')
+ skip(fn.executable('grep') == 0, 'missing "grep" command')
source([[
function! OnEvent(id, data, event) dict
call rpcnotify(1, a:event, a:id, a:data, self.stdout)
@@ -274,31 +333,40 @@ describe('channels', function()
\ }
]])
command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)")
- local id = eval("g:id")
+ local id = eval('g:id')
command([[call chansend(id, "stuff\n10 PRINT \"NVIM\"\nxx")]])
sleep(10)
command([[call chansend(id, "xx\n20 GOTO 10\nzz\n")]])
command("call chanclose(id, 'stdin')")
- eq({"notification", "exit", {id, 0, {'10 PRINT "NVIM"',
- '20 GOTO 10', ''}}}, next_msg())
+ eq({
+ 'notification',
+ 'exit',
+ { id, 0, { '10 PRINT "NVIM"', '20 GOTO 10', '' } },
+ }, next_msg())
-- if dict is reused the new value is not stored,
-- but nvim also does not crash
command("let id = jobstart(['cat'], g:job_opts)")
- id = eval("g:id")
+ id = eval('g:id')
command([[call chansend(id, "cat text\n")]])
sleep(10)
command("call chanclose(id, 'stdin')")
-- old value was not overwritten
- eq({"notification", "exit", {id, 0, {'10 PRINT "NVIM"',
- '20 GOTO 10', ''}}}, next_msg())
+ eq({
+ 'notification',
+ 'exit',
+ { id, 0, { '10 PRINT "NVIM"', '20 GOTO 10', '' } },
+ }, next_msg())
-- and an error was thrown.
- eq("E5210: dict key 'stdout' already set for buffered stream in channel "..id, eval('v:errmsg'))
+ eq(
+ "E5210: dict key 'stdout' already set for buffered stream in channel " .. id,
+ eval('v:errmsg')
+ )
-- reset dictionary
source([[
@@ -308,13 +376,13 @@ describe('channels', function()
\ }
]])
command("let id = jobstart(['grep', '^[0-9]'], g:job_opts)")
- id = eval("g:id")
+ id = eval('g:id')
command([[call chansend(id, "is no number\nnot at all")]])
command("call chanclose(id, 'stdin')")
-- works correctly with no output
- eq({"notification", "exit", {id, 1, {''}}}, next_msg())
+ eq({ 'notification', 'exit', { id, 1, { '' } } }, next_msg())
end)
end)
@@ -325,8 +393,10 @@ describe('loopback', function()
end)
it('does not crash when sending raw data', function()
- eq("Vim(call):Can't send raw data to rpc channel",
- pcall_err(command, "call chansend(chan, 'test')"))
+ eq(
+ "Vim(call):Can't send raw data to rpc channel",
+ pcall_err(command, "call chansend(chan, 'test')")
+ )
assert_alive()
end)
diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua
index d474b77806..d9e3cc3f31 100644
--- a/test/functional/core/exit_spec.lua
+++ b/test/functional/core/exit_spec.lua
@@ -7,7 +7,7 @@ local feed = helpers.feed
local eval = helpers.eval
local eq = helpers.eq
local run = helpers.run
-local funcs = helpers.funcs
+local fn = helpers.fn
local nvim_prog = helpers.nvim_prog
local pcall_err = helpers.pcall_err
local exec_capture = helpers.exec_capture
@@ -18,7 +18,7 @@ describe('v:exiting', function()
before_each(function()
helpers.clear()
- cid = helpers.nvim('get_api_info')[1]
+ cid = helpers.api.nvim_get_chan_info(0).id
end)
it('defaults to v:null', function()
@@ -27,8 +27,8 @@ describe('v:exiting', function()
local function test_exiting(setup_fn)
local function on_setup()
- command('autocmd VimLeavePre * call rpcrequest('..cid..', "exit", "VimLeavePre")')
- command('autocmd VimLeave * call rpcrequest('..cid..', "exit", "VimLeave")')
+ command('autocmd VimLeavePre * call rpcrequest(' .. cid .. ', "exit", "VimLeavePre")')
+ command('autocmd VimLeave * call rpcrequest(' .. cid .. ', "exit", "VimLeave")')
setup_fn()
end
local requests_args = {}
@@ -39,7 +39,7 @@ describe('v:exiting', function()
return ''
end
run(on_request, nil, on_setup)
- eq({{'VimLeavePre'}, {'VimLeave'}}, requests_args)
+ eq({ { 'VimLeavePre' }, { 'VimLeave' } }, requests_args)
end
it('is 0 on normal exit', function()
@@ -59,11 +59,16 @@ end)
describe(':cquit', function()
local function test_cq(cmdline, exit_code, redir_msg)
if redir_msg then
- eq(redir_msg, pcall_err(function() return exec_capture(cmdline) end))
+ eq(
+ redir_msg,
+ pcall_err(function()
+ return exec_capture(cmdline)
+ end)
+ )
poke_eventloop()
assert_alive()
else
- funcs.system({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', cmdline})
+ fn.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', cmdline })
eq(exit_code, eval('v:shell_error'))
end
end
diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua
index 65f947132e..928cab525c 100644
--- a/test/functional/core/fileio_spec.lua
+++ b/test/functional/core/fileio_spec.lua
@@ -1,4 +1,4 @@
-local luv = require('luv')
+local uv = vim.uv
local helpers = require('test.functional.helpers')(after_each)
local assert_log = helpers.assert_log
@@ -9,18 +9,18 @@ local eq = helpers.eq
local neq = helpers.neq
local ok = helpers.ok
local feed = helpers.feed
-local funcs = helpers.funcs
+local fn = helpers.fn
local nvim_prog = helpers.nvim_prog
local request = helpers.request
local retry = helpers.retry
local rmdir = helpers.rmdir
local matches = helpers.matches
-local meths = helpers.meths
+local api = helpers.api
local mkdir = helpers.mkdir
-local sleep = helpers.sleep
+local sleep = vim.uv.sleep
local read_file = helpers.read_file
-local trim = helpers.trim
-local currentdir = helpers.funcs.getcwd
+local trim = vim.trim
+local currentdir = helpers.fn.getcwd
local assert_alive = helpers.assert_alive
local check_close = helpers.check_close
local expect_exit = helpers.expect_exit
@@ -30,10 +30,11 @@ local feed_command = helpers.feed_command
local skip = helpers.skip
local is_os = helpers.is_os
local is_ci = helpers.is_ci
+local spawn = helpers.spawn
+local set_session = helpers.set_session
describe('fileio', function()
- before_each(function()
- end)
+ before_each(function() end)
after_each(function()
check_close()
os.remove('Xtest_startup_shada')
@@ -49,54 +50,91 @@ describe('fileio', function()
rmdir('Xtest_backupdir with spaces')
end)
- it('fsync() codepaths #8304', function()
- clear({ args={ '-i', 'Xtest_startup_shada',
- '--cmd', 'set nofsync',
- '--cmd', 'set directory=Xtest_startup_swapdir' } })
+ local args = { nvim_prog, '--clean', '--cmd', 'set nofsync directory=Xtest_startup_swapdir' }
+ --- Starts a new nvim session and returns an attached screen.
+ local function startup(extra_args)
+ extra_args = extra_args or {}
+ local argv = vim.tbl_flatten({ args, '--embed', extra_args })
+ local screen_nvim = spawn(argv)
+ set_session(screen_nvim)
+ local screen = Screen.new(70, 10)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = { foreground = Screen.colors.NvimDarkGrey4 },
+ [2] = { background = Screen.colors.NvimDarkGrey1, foreground = Screen.colors.NvimLightGrey3 },
+ [3] = { foreground = Screen.colors.NvimLightCyan },
+ })
+ return screen
+ end
+
+ it("fsync() with 'nofsync' #8304", function()
+ clear({ args = { '--cmd', 'set nofsync directory=Xtest_startup_swapdir' } })
-- These cases ALWAYS force fsync (regardless of 'fsync' option):
-- 1. Idle (CursorHold) with modified buffers (+ 'swapfile').
command('write Xtest_startup_file1')
- feed('ifoo<esc>h')
+ feed('Afoo<esc>h')
command('write')
- eq(0, request('nvim__stats').fsync) -- 'nofsync' is the default.
+ eq(0, request('nvim__stats').fsync)
command('set swapfile')
command('set updatetime=1')
- feed('izub<esc>h') -- File is 'modified'.
- sleep(3) -- Allow 'updatetime' to expire.
+ feed('Azub<esc>h') -- File is 'modified'.
+ sleep(3) -- Allow 'updatetime' to expire.
retry(3, nil, function()
eq(1, request('nvim__stats').fsync)
end)
- command('set updatetime=9999')
+ command('set updatetime=100000 updatecount=100000')
- -- 2. Exit caused by deadly signal (+ 'swapfile').
- local j = funcs.jobstart({ nvim_prog, '-u', 'NONE', '-i',
- 'Xtest_startup_shada', '--headless',
- '-c', 'set swapfile',
- '-c', 'write Xtest_startup_file2',
- '-c', 'put =localtime()', })
- sleep(10) -- Let Nvim start.
- funcs.jobstop(j) -- Send deadly signal.
-
- -- 3. SIGPWR signal.
- -- ??
-
- -- 4. Explicit :preserve command.
+ -- 2. Explicit :preserve command.
command('preserve')
- eq(2, request('nvim__stats').fsync)
+ -- TODO: should be exactly 2; where is the extra fsync() is coming from? #26404
+ ok(request('nvim__stats').fsync == 2 or request('nvim__stats').fsync == 3)
- -- 5. Enable 'fsync' option, write file.
+ -- 3. Enable 'fsync' option, write file.
command('set fsync')
- feed('ibaz<esc>h')
+ feed('Abaz<esc>h')
command('write')
- eq(4, request('nvim__stats').fsync)
+ -- TODO: should be exactly 4; where is the extra fsync() is coming from? #26404
+ ok(request('nvim__stats').fsync == 4 or request('nvim__stats').fsync == 5)
+ eq('foozubbaz', trim(read_file('Xtest_startup_file1')))
+
+ -- 4. Exit caused by deadly signal (+ 'swapfile').
+ local j = fn.jobstart(vim.tbl_flatten({ args, '--embed' }), { rpc = true })
+ fn.rpcrequest(
+ j,
+ 'nvim_exec2',
+ [[
+ set nofsync directory=Xtest_startup_swapdir
+ edit Xtest_startup_file2
+ write
+ put ='fsyncd text'
+ ]],
+ {}
+ )
+ eq('Xtest_startup_swapdir', fn.rpcrequest(j, 'nvim_eval', '&directory'))
+ fn.jobstop(j) -- Send deadly signal.
+
+ local screen = startup()
+ feed(':recover Xtest_startup_file2<cr>')
+ screen:expect({ any = [[Using swap file "Xtest_startup_swapdir[/\]Xtest_startup_file2%.swp"]] })
+ feed('<cr>')
+ screen:expect({ any = 'fsyncd text' })
+
+ -- 5. SIGPWR signal.
+ -- oldtest: Test_signal_PWR()
end)
it('backup #9709', function()
skip(is_ci('cirrus'))
- clear({ args={ '-i', 'Xtest_startup_shada',
- '--cmd', 'set directory=Xtest_startup_swapdir' } })
+ clear({
+ args = {
+ '-i',
+ 'Xtest_startup_shada',
+ '--cmd',
+ 'set directory=Xtest_startup_swapdir',
+ },
+ })
command('write Xtest_startup_file1')
feed('ifoo<esc>')
@@ -109,8 +147,8 @@ describe('fileio', function()
local foobar_contents = trim(read_file('Xtest_startup_file1'))
local bar_contents = trim(read_file('Xtest_startup_file1~'))
- eq('foobar', foobar_contents);
- eq('foo', bar_contents);
+ eq('foobar', foobar_contents)
+ eq('foo', bar_contents)
end)
it('backup with full path #11214', function()
@@ -126,13 +164,16 @@ describe('fileio', function()
command('write')
-- Backup filename = fullpath, separators replaced with "%".
- local backup_file_name = string.gsub(currentdir()..'/Xtest_startup_file1',
- is_os('win') and '[:/\\]' or '/', '%%') .. '~'
- local foo_contents = trim(read_file('Xtest_backupdir/'..backup_file_name))
+ local backup_file_name = string.gsub(
+ currentdir() .. '/Xtest_startup_file1',
+ is_os('win') and '[:/\\]' or '/',
+ '%%'
+ ) .. '~'
+ local foo_contents = trim(read_file('Xtest_backupdir/' .. backup_file_name))
local foobar_contents = trim(read_file('Xtest_startup_file1'))
- eq('foobar', foobar_contents);
- eq('foo', foo_contents);
+ eq('foobar', foobar_contents)
+ eq('foo', foo_contents)
end)
it('backup with full path with spaces', function()
@@ -148,13 +189,16 @@ describe('fileio', function()
command('write')
-- Backup filename = fullpath, separators replaced with "%".
- local backup_file_name = string.gsub(currentdir()..'/Xtest_startup_file1',
- is_os('win') and '[:/\\]' or '/', '%%') .. '~'
- local foo_contents = trim(read_file('Xtest_backupdir with spaces/'..backup_file_name))
+ local backup_file_name = string.gsub(
+ currentdir() .. '/Xtest_startup_file1',
+ is_os('win') and '[:/\\]' or '/',
+ '%%'
+ ) .. '~'
+ local foo_contents = trim(read_file('Xtest_backupdir with spaces/' .. backup_file_name))
local foobar_contents = trim(read_file('Xtest_startup_file1'))
- eq('foobar', foobar_contents);
- eq('foo', foo_contents);
+ eq('foobar', foobar_contents)
+ eq('foo', foo_contents)
end)
it('backup symlinked files #11349', function()
@@ -166,7 +210,7 @@ describe('fileio', function()
local backup_file_name = link_file_name .. '~'
write_file('Xtest_startup_file1', initial_content, false)
- luv.fs_symlink('Xtest_startup_file1', link_file_name)
+ uv.fs_symlink('Xtest_startup_file1', link_file_name)
command('set backup')
command('set backupcopy=yes')
command('edit ' .. link_file_name)
@@ -174,11 +218,10 @@ describe('fileio', function()
command('write')
local backup_raw = read_file(backup_file_name)
- neq(nil, backup_raw, "Expected backup file " .. backup_file_name .. "to exist but did not")
+ neq(nil, backup_raw, 'Expected backup file ' .. backup_file_name .. 'to exist but did not')
eq(initial_content, trim(backup_raw), 'Expected backup to contain original contents')
end)
-
it('backup symlinked files in first available backupdir #11349', function()
skip(is_ci('cirrus'))
clear()
@@ -190,7 +233,7 @@ describe('fileio', function()
local backup_file_name = backup_dir .. sep .. link_file_name .. '~'
write_file('Xtest_startup_file1', initial_content, false)
- luv.fs_symlink('Xtest_startup_file1', link_file_name)
+ uv.fs_symlink('Xtest_startup_file1', link_file_name)
mkdir(backup_dir)
command('set backup')
command('set backupcopy=yes')
@@ -200,7 +243,7 @@ describe('fileio', function()
command('write')
local backup_raw = read_file(backup_file_name)
- neq(nil, backup_raw, "Expected backup file " .. backup_file_name .. " to exist but did not")
+ neq(nil, backup_raw, 'Expected backup file ' .. backup_file_name .. ' to exist but did not')
eq(initial_content, trim(backup_raw), 'Expected backup to contain original contents')
end)
@@ -215,11 +258,11 @@ describe('fileio', function()
'',
}
local fname = 'Xtest_тест.md'
- funcs.writefile(text, fname, 's')
+ fn.writefile(text, fname, 's')
table.insert(text, '')
- eq(text, funcs.readfile(fname, 'b'))
+ eq(text, fn.readfile(fname, 'b'))
end)
- it('read invalid u8 over INT_MAX doesn\'t segfault', function()
+ it("read invalid u8 over INT_MAX doesn't segfault", function()
clear()
command('call writefile(0zFFFFFFFF, "Xtest-u8-int-max")')
-- This should not segfault
@@ -229,34 +272,32 @@ describe('fileio', function()
it(':w! does not show "file has been changed" warning', function()
clear()
- write_file("Xtest-overwrite-forced", 'foobar')
+ write_file('Xtest-overwrite-forced', 'foobar')
command('set nofixendofline')
- local screen = Screen.new(40,4)
+ local screen = Screen.new(40, 4)
screen:set_default_attr_ids({
- [1] = {bold = true, foreground = Screen.colors.Blue1},
- [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
- [3] = {bold = true, foreground = Screen.colors.SeaGreen4}
+ [1] = { bold = true, foreground = Screen.colors.Blue1 },
+ [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
+ [3] = { bold = true, foreground = Screen.colors.SeaGreen4 },
})
screen:attach()
- command("set shortmess-=F")
+ command('set shortmess-=F')
- command("e Xtest-overwrite-forced")
+ command('e Xtest-overwrite-forced')
screen:expect([[
^foobar |
- {1:~ }|
- {1:~ }|
+ {1:~ }|*2
"Xtest-overwrite-forced" [noeol] 1L, 6B |
]])
-- Get current unix time.
- local cur_unix_time = os.time(os.date("!*t"))
+ local cur_unix_time = os.time(os.date('!*t'))
local future_time = cur_unix_time + 999999
-- Set the file's access/update time to be
-- greater than the time at which it was created.
- local uv = require("luv")
uv.fs_utime('Xtest-overwrite-forced', future_time, future_time)
-- use async feed_command because nvim basically hangs on the prompt
- feed_command("w")
+ feed_command('w')
screen:expect([[
{2:WARNING: The file has been changed since}|
{2: reading it!!!} |
@@ -264,20 +305,18 @@ describe('fileio', function()
^ |
]])
- feed("n")
- feed("<cr>")
+ feed('n')
+ feed('<cr>')
screen:expect([[
^foobar |
- {1:~ }|
- {1:~ }|
+ {1:~ }|*2
|
]])
-- Use a screen test because the warning does not set v:errmsg.
- command("w!")
+ command('w!')
screen:expect([[
^foobar |
- {1:~ }|
- {1:~ }|
+ {1:~ }|*2
<erwrite-forced" [noeol] 1L, 6B written |
]])
end)
@@ -302,13 +341,13 @@ describe('tmpdir', function()
-- Tempfiles typically look like: "…/nvim.<user>/xxx/0".
-- - "…/nvim.<user>/xxx/" is the per-process tmpdir, not shared with other Nvims.
-- - "…/nvim.<user>/" is the tmpdir root, shared by all Nvims (normally).
- local tmproot = (funcs.tempname()):match(tmproot_pat)
+ local tmproot = (fn.tempname()):match(tmproot_pat)
ok(tmproot:len() > 4, 'tmproot like "nvim.foo"', tmproot)
return tmproot
end
it('failure modes', function()
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
+ clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } })
assert_nolog('tempdir is not a directory', testlog)
assert_nolog('tempdir has invalid permissions', testlog)
@@ -319,9 +358,9 @@ describe('tmpdir', function()
-- "…/nvim.<user>/" is not a directory:
expect_exit(command, ':qall!')
rmdir(tmproot)
- write_file(tmproot, '') -- Not a directory, vim_mktempdir() should skip it.
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
- matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir().
+ write_file(tmproot, '') -- Not a directory, vim_mktempdir() should skip it.
+ clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } })
+ matches(tmproot_pat, fn.stdpath('run')) -- Tickle vim_mktempdir().
-- Assert that broken tmpdir root was handled.
assert_log('tempdir root not a directory', testlog, 100)
@@ -330,9 +369,9 @@ describe('tmpdir', function()
os.remove(testlog)
os.remove(tmproot)
mkdir(tmproot)
- funcs.setfperm(tmproot, 'rwxr--r--') -- Invalid permissions, vim_mktempdir() should skip it.
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
- matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir().
+ fn.setfperm(tmproot, 'rwxr--r--') -- Invalid permissions, vim_mktempdir() should skip it.
+ clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } })
+ matches(tmproot_pat, fn.stdpath('run')) -- Tickle vim_mktempdir().
-- Assert that broken tmpdir root was handled.
assert_log('tempdir root has invalid permissions', testlog, 100)
end)
@@ -340,53 +379,54 @@ describe('tmpdir', function()
it('too long', function()
local bigname = ('%s/%s'):format(os_tmpdir, ('x'):rep(666))
mkdir(bigname)
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=bigname, } })
- matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir().
- local len = (funcs.tempname()):len()
+ clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = bigname } })
+ matches(tmproot_pat, fn.stdpath('run')) -- Tickle vim_mktempdir().
+ local len = (fn.tempname()):len()
ok(len > 4 and len < 256, '4 < len < 256', tostring(len))
end)
it('disappeared #1432', function()
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
+ clear({ env = { NVIM_LOG_FILE = testlog, TMPDIR = os_tmpdir } })
assert_nolog('tempdir disappeared', testlog)
local function rm_tmpdir()
- local tmpname1 = funcs.tempname()
- local tmpdir1 = funcs.fnamemodify(tmpname1, ':h')
- eq(funcs.stdpath('run'), tmpdir1)
+ local tmpname1 = fn.tempname()
+ local tmpdir1 = fn.fnamemodify(tmpname1, ':h')
+ eq(fn.stdpath('run'), tmpdir1)
rmdir(tmpdir1)
retry(nil, 1000, function()
- eq(0, funcs.isdirectory(tmpdir1))
+ eq(0, fn.isdirectory(tmpdir1))
end)
- local tmpname2 = funcs.tempname()
- local tmpdir2 = funcs.fnamemodify(tmpname2, ':h')
+ local tmpname2 = fn.tempname()
+ local tmpdir2 = fn.fnamemodify(tmpname2, ':h')
neq(tmpdir1, tmpdir2)
end
-- Your antivirus hates you...
rm_tmpdir()
assert_log('tempdir disappeared', testlog, 100)
- funcs.tempname()
- funcs.tempname()
- funcs.tempname()
- eq('', meths.get_vvar('errmsg'))
+ fn.tempname()
+ fn.tempname()
+ fn.tempname()
+ eq('', api.nvim_get_vvar('errmsg'))
rm_tmpdir()
- funcs.tempname()
- funcs.tempname()
- funcs.tempname()
- eq('E5431: tempdir disappeared (2 times)', meths.get_vvar('errmsg'))
+ fn.tempname()
+ fn.tempname()
+ fn.tempname()
+ eq('E5431: tempdir disappeared (2 times)', api.nvim_get_vvar('errmsg'))
rm_tmpdir()
- eq('E5431: tempdir disappeared (3 times)', meths.get_vvar('errmsg'))
+ eq('E5431: tempdir disappeared (3 times)', api.nvim_get_vvar('errmsg'))
end)
it('$NVIM_APPNAME relative path', function()
- clear({ env={
- NVIM_APPNAME='a/b',
- NVIM_LOG_FILE=testlog,
- TMPDIR=os_tmpdir,
- } })
- matches([=[.*[/\\]a%%b%.[^/\\]+]=], funcs.tempname())
+ clear({
+ env = {
+ NVIM_APPNAME = 'a/b',
+ NVIM_LOG_FILE = testlog,
+ TMPDIR = os_tmpdir,
+ },
+ })
+ matches([=[.*[/\\]a%%b%.[^/\\]+]=], fn.tempname())
end)
-
end)
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 038368c387..13f5f9a5e1 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -1,17 +1,28 @@
local helpers = require('test.functional.helpers')(after_each)
-local clear, eq, eval, exc_exec, feed_command, feed, insert, neq, next_msg, nvim,
- testprg, ok, source, write_file, mkdir, rmdir = helpers.clear,
- helpers.eq, helpers.eval, helpers.exc_exec, helpers.feed_command, helpers.feed,
- helpers.insert, helpers.neq, helpers.next_msg, helpers.nvim,
- helpers.testprg, helpers.ok, helpers.source,
- helpers.write_file, helpers.mkdir, helpers.rmdir
+local thelpers = require('test.functional.terminal.helpers')
+
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local exc_exec = helpers.exc_exec
+local feed_command = helpers.feed_command
+local feed = helpers.feed
+local insert = helpers.insert
+local neq = helpers.neq
+local next_msg = helpers.next_msg
+local testprg = helpers.testprg
+local ok = helpers.ok
+local source = helpers.source
+local write_file = helpers.write_file
+local mkdir = helpers.mkdir
+local rmdir = helpers.rmdir
local assert_alive = helpers.assert_alive
local command = helpers.command
-local funcs = helpers.funcs
+local fn = helpers.fn
local os_kill = helpers.os_kill
local retry = helpers.retry
-local meths = helpers.meths
-local NIL = helpers.NIL
+local api = helpers.api
+local NIL = vim.NIL
local poke_eventloop = helpers.poke_eventloop
local get_pathsep = helpers.get_pathsep
local pathroot = helpers.pathroot
@@ -31,8 +42,8 @@ describe('jobs', function()
before_each(function()
clear()
- channel = nvim('get_api_info')[1]
- nvim('set_var', 'channel', channel)
+ channel = api.nvim_get_chan_info(0).id
+ api.nvim_set_var('channel', channel)
source([[
function! Normalize(data) abort
" Windows: remove ^M and term escape sequences
@@ -54,66 +65,60 @@ describe('jobs', function()
end)
it('must specify env option as a dict', function()
- command("let g:job_opts.env = v:true")
+ command('let g:job_opts.env = v:true')
local _, err = pcall(function()
if is_os('win') then
- nvim('command', "let j = jobstart('set', g:job_opts)")
+ command("let j = jobstart('set', g:job_opts)")
else
- nvim('command', "let j = jobstart('env', g:job_opts)")
+ command("let j = jobstart('env', g:job_opts)")
end
end)
- ok(string.find(err, "E475: Invalid argument: env") ~= nil)
+ ok(string.find(err, 'E475: Invalid argument: env') ~= nil)
end)
it('append environment #env', function()
- nvim('command', "let $VAR = 'abc'")
- nvim('command', "let $TOTO = 'goodbye world'")
- nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}")
+ command("let $VAR = 'abc'")
+ command("let $TOTO = 'goodbye world'")
+ command("let g:job_opts.env = {'TOTO': 'hello world'}")
if is_os('win') then
- nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
+ command([[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
else
- nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]])
+ command([[call jobstart('echo $TOTO $VAR', g:job_opts)]])
end
- expect_msg_seq(
- {
- {'notification', 'stdout', {0, {'hello world abc'}}},
- {'notification', 'stdout', {0, {'', ''}}},
- },
- {
- {'notification', 'stdout', {0, {'hello world abc', ''}}},
- {'notification', 'stdout', {0, {''}}}
- }
- )
+ expect_msg_seq({
+ { 'notification', 'stdout', { 0, { 'hello world abc' } } },
+ { 'notification', 'stdout', { 0, { '', '' } } },
+ }, {
+ { 'notification', 'stdout', { 0, { 'hello world abc', '' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
+ })
end)
it('append environment with pty #env', function()
- nvim('command', "let $VAR = 'abc'")
- nvim('command', "let $TOTO = 'goodbye world'")
- nvim('command', "let g:job_opts.pty = v:true")
- nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}")
+ command("let $VAR = 'abc'")
+ command("let $TOTO = 'goodbye world'")
+ command('let g:job_opts.pty = v:true')
+ command("let g:job_opts.env = {'TOTO': 'hello world'}")
if is_os('win') then
- nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
+ command([[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
else
- nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]])
+ command([[call jobstart('echo $TOTO $VAR', g:job_opts)]])
end
- expect_msg_seq(
- {
- {'notification', 'stdout', {0, {'hello world abc'}}},
- {'notification', 'stdout', {0, {'', ''}}},
- },
- {
- {'notification', 'stdout', {0, {'hello world abc', ''}}},
- {'notification', 'stdout', {0, {''}}}
- }
- )
+ expect_msg_seq({
+ { 'notification', 'stdout', { 0, { 'hello world abc' } } },
+ { 'notification', 'stdout', { 0, { '', '' } } },
+ }, {
+ { 'notification', 'stdout', { 0, { 'hello world abc', '' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
+ })
end)
it('replace environment #env', function()
- nvim('command', "let $VAR = 'abc'")
- nvim('command', "let $TOTO = 'goodbye world'")
- nvim('command', "let g:job_opts.env = {'TOTO': 'hello world'}")
- nvim('command', "let g:job_opts.clear_env = 1")
+ command("let $VAR = 'abc'")
+ command("let $TOTO = 'goodbye world'")
+ command("let g:job_opts.env = {'TOTO': 'hello world'}")
+ command('let g:job_opts.clear_env = 1')
-- libuv ensures that certain "required" environment variables are
-- preserved if the user doesn't provide them in a custom environment
@@ -123,39 +128,39 @@ describe('jobs', function()
-- Rather than expecting a completely empty environment, ensure that $VAR
-- is *not* in the environment but $TOTO is.
if is_os('win') then
- nvim('command', [[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
+ command([[call jobstart('echo %TOTO% %VAR%', g:job_opts)]])
expect_msg_seq({
- {'notification', 'stdout', {0, {'hello world %VAR%', ''}}}
+ { 'notification', 'stdout', { 0, { 'hello world %VAR%', '' } } },
})
else
- nvim('command', "set shell=/bin/sh")
- nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]])
+ command('set shell=/bin/sh')
+ command([[call jobstart('echo $TOTO $VAR', g:job_opts)]])
expect_msg_seq({
- {'notification', 'stdout', {0, {'hello world', ''}}}
+ { 'notification', 'stdout', { 0, { 'hello world', '' } } },
})
end
end)
it('handles case-insensitively matching #env vars', function()
- nvim('command', "let $TOTO = 'abc'")
+ command("let $TOTO = 'abc'")
-- Since $Toto is being set in the job, it should take precedence over the
-- global $TOTO on Windows
- nvim('command', "let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}")
+ command("let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}")
if is_os('win') then
- nvim('command', [[let j = jobstart('set | find /I "toto="', g:job_opts)]])
+ command([[let j = jobstart('set | find /I "toto="', g:job_opts)]])
else
- nvim('command', [[let j = jobstart('env | grep -i toto=', g:job_opts)]])
+ command([[let j = jobstart('env | grep -i toto=', g:job_opts)]])
end
- nvim('command', "call jobwait([j])")
- nvim('command', "let g:output = Normalize(g:job_opts.stdout)")
+ command('call jobwait([j])')
+ command('let g:output = Normalize(g:job_opts.stdout)')
local actual = eval('g:output')
local expected
if is_os('win') then
-- Toto is normalized to TOTO so we can detect duplicates, and because
-- Windows doesn't care about case
- expected = {'TOTO=def', ''}
+ expected = { 'TOTO=def', '' }
else
- expected = {'TOTO=abc', 'Toto=def', ''}
+ expected = { 'TOTO=abc', 'Toto=def', '' }
end
table.sort(actual)
table.sort(expected)
@@ -163,49 +168,50 @@ describe('jobs', function()
end)
it('uses &shell and &shellcmdflag if passed a string', function()
- nvim('command', "let $VAR = 'abc'")
+ command("let $VAR = 'abc'")
if is_os('win') then
- nvim('command', "let j = jobstart('echo %VAR%', g:job_opts)")
+ command("let j = jobstart('echo %VAR%', g:job_opts)")
else
- nvim('command', "let j = jobstart('echo $VAR', g:job_opts)")
+ command("let j = jobstart('echo $VAR', g:job_opts)")
end
- eq({'notification', 'stdout', {0, {'abc', ''}}}, next_msg())
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 0}}, next_msg())
+ eq({ 'notification', 'stdout', { 0, { 'abc', '' } } }, next_msg())
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 0 } }, next_msg())
end)
it('changes to given / directory', function()
- nvim('command', "let g:job_opts.cwd = '/'")
+ command("let g:job_opts.cwd = '/'")
if is_os('win') then
- nvim('command', "let j = jobstart('cd', g:job_opts)")
+ command("let j = jobstart('cd', g:job_opts)")
else
- nvim('command', "let j = jobstart('pwd', g:job_opts)")
+ command("let j = jobstart('pwd', g:job_opts)")
end
- eq({'notification', 'stdout',
- {0, {pathroot(), ''}}}, next_msg())
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 0}}, next_msg())
+ eq({ 'notification', 'stdout', { 0, { pathroot(), '' } } }, next_msg())
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 0 } }, next_msg())
end)
it('changes to given `cwd` directory', function()
- local dir = eval("resolve(tempname())"):gsub("/", get_pathsep())
+ local dir = eval('resolve(tempname())'):gsub('/', get_pathsep())
mkdir(dir)
- nvim('command', "let g:job_opts.cwd = '" .. dir .. "'")
+ command("let g:job_opts.cwd = '" .. dir .. "'")
if is_os('win') then
- nvim('command', "let j = jobstart('cd', g:job_opts)")
+ command("let j = jobstart('cd', g:job_opts)")
else
- nvim('command', "let j = jobstart('pwd', g:job_opts)")
+ command("let j = jobstart('pwd', g:job_opts)")
end
expect_msg_seq(
- { {'notification', 'stdout', {0, {dir, ''} } },
- {'notification', 'stdout', {0, {''} } },
- {'notification', 'exit', {0, 0} }
+ {
+ { 'notification', 'stdout', { 0, { dir, '' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
+ { 'notification', 'exit', { 0, 0 } },
},
-- Alternative sequence:
- { {'notification', 'stdout', {0, {dir} } },
- {'notification', 'stdout', {0, {'', ''} } },
- {'notification', 'stdout', {0, {''} } },
- {'notification', 'exit', {0, 0} }
+ {
+ { 'notification', 'stdout', { 0, { dir } } },
+ { 'notification', 'stdout', { 0, { '', '' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
+ { 'notification', 'exit', { 0, 0 } },
}
)
rmdir(dir)
@@ -214,14 +220,14 @@ describe('jobs', function()
it('fails to change to invalid `cwd`', function()
local dir = eval('resolve(tempname())."-bogus"')
local _, err = pcall(function()
- nvim('command', "let g:job_opts.cwd = '" .. dir .. "'")
+ command("let g:job_opts.cwd = '" .. dir .. "'")
if is_os('win') then
- nvim('command', "let j = jobstart('cd', g:job_opts)")
+ command("let j = jobstart('cd', g:job_opts)")
else
- nvim('command', "let j = jobstart('pwd', g:job_opts)")
+ command("let j = jobstart('pwd', g:job_opts)")
end
end)
- ok(string.find(err, "E475: Invalid argument: expected valid directory$") ~= nil)
+ ok(string.find(err, 'E475: Invalid argument: expected valid directory$') ~= nil)
end)
it('error on non-executable `cwd`', function()
@@ -229,17 +235,19 @@ describe('jobs', function()
local dir = 'Xtest_not_executable_dir'
mkdir(dir)
- funcs.setfperm(dir, 'rw-------')
- matches('^Vim%(call%):E903: Process failed to start: permission denied: .*',
- pcall_err(nvim, 'command', "call jobstart(['pwd'], {'cwd': '"..dir.."'})"))
+ fn.setfperm(dir, 'rw-------')
+ matches(
+ '^Vim%(call%):E903: Process failed to start: permission denied: .*',
+ pcall_err(command, "call jobstart(['pwd'], {'cwd': '" .. dir .. "'})")
+ )
rmdir(dir)
end)
it('returns 0 when it fails to start', function()
- eq("", eval("v:errmsg"))
- feed_command("let g:test_jobid = jobstart([])")
- eq(0, eval("g:test_jobid"))
- eq("E474:", string.match(eval("v:errmsg"), "E%d*:"))
+ eq('', eval('v:errmsg'))
+ feed_command('let g:test_jobid = jobstart([])')
+ eq(0, eval('g:test_jobid'))
+ eq('E474:', string.match(eval('v:errmsg'), 'E%d*:'))
end)
it('returns -1 when target is not executable #5465', function()
@@ -248,124 +256,131 @@ describe('jobs', function()
end
local executable_jobid = new_job()
- local exe = is_os('win') and './test/functional/fixtures' or './test/functional/fixtures/non_executable.txt'
- eq("Vim:E475: Invalid value for argument cmd: '"..exe.."' is not executable",
- pcall_err(eval, "jobstart(['"..exe.."'])"))
- eq("", eval("v:errmsg"))
+ local exe = is_os('win') and './test/functional/fixtures'
+ or './test/functional/fixtures/non_executable.txt'
+ eq(
+ "Vim:E475: Invalid value for argument cmd: '" .. exe .. "' is not executable",
+ pcall_err(eval, "jobstart(['" .. exe .. "'])")
+ )
+ eq('', eval('v:errmsg'))
-- Non-executable job should not increment the job ids. #5465
eq(executable_jobid + 1, new_job())
end)
it('invokes callbacks when the job writes and exits', function()
- nvim('command', "let g:job_opts.on_stderr = function('OnEvent')")
- nvim('command', [[call jobstart(has('win32') ? 'echo:' : 'echo', g:job_opts)]])
- expect_twostreams({{'notification', 'stdout', {0, {'', ''}}},
- {'notification', 'stdout', {0, {''}}}},
- {{'notification', 'stderr', {0, {''}}}})
- eq({'notification', 'exit', {0, 0}}, next_msg())
+ command("let g:job_opts.on_stderr = function('OnEvent')")
+ command([[call jobstart(has('win32') ? 'echo:' : 'echo', g:job_opts)]])
+ expect_twostreams({
+ { 'notification', 'stdout', { 0, { '', '' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
+ }, { { 'notification', 'stderr', { 0, { '' } } } })
+ eq({ 'notification', 'exit', { 0, 0 } }, next_msg())
end)
it('interactive commands', function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
neq(0, eval('j'))
- nvim('command', 'call jobsend(j, "abc\\n")')
- eq({'notification', 'stdout', {0, {'abc', ''}}}, next_msg())
- nvim('command', 'call jobsend(j, "123\\nxyz\\n")')
+ command('call jobsend(j, "abc\\n")')
+ eq({ 'notification', 'stdout', { 0, { 'abc', '' } } }, next_msg())
+ command('call jobsend(j, "123\\nxyz\\n")')
expect_msg_seq(
- { {'notification', 'stdout', {0, {'123', 'xyz', ''}}}
- },
+ { { 'notification', 'stdout', { 0, { '123', 'xyz', '' } } } },
-- Alternative sequence:
- { {'notification', 'stdout', {0, {'123', ''}}},
- {'notification', 'stdout', {0, {'xyz', ''}}}
+ {
+ { 'notification', 'stdout', { 0, { '123', '' } } },
+ { 'notification', 'stdout', { 0, { 'xyz', '' } } },
}
)
- nvim('command', 'call jobsend(j, [123, "xyz", ""])')
+ command('call jobsend(j, [123, "xyz", ""])')
expect_msg_seq(
- { {'notification', 'stdout', {0, {'123', 'xyz', ''}}}
- },
+ { { 'notification', 'stdout', { 0, { '123', 'xyz', '' } } } },
-- Alternative sequence:
- { {'notification', 'stdout', {0, {'123', ''}}},
- {'notification', 'stdout', {0, {'xyz', ''}}}
+ {
+ { 'notification', 'stdout', { 0, { '123', '' } } },
+ { 'notification', 'stdout', { 0, { 'xyz', '' } } },
}
)
- nvim('command', "call jobstop(j)")
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 143}}, next_msg())
+ command('call jobstop(j)')
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 143 } }, next_msg())
end)
it('preserves NULs', function()
-- Make a file with NULs in it.
local filename = helpers.tmpname()
- write_file(filename, "abc\0def\n")
+ write_file(filename, 'abc\0def\n')
- nvim('command', "let j = jobstart(['cat', '"..filename.."'], g:job_opts)")
- eq({'notification', 'stdout', {0, {'abc\ndef', ''}}}, next_msg())
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 0}}, next_msg())
+ command("let j = jobstart(['cat', '" .. filename .. "'], g:job_opts)")
+ eq({ 'notification', 'stdout', { 0, { 'abc\ndef', '' } } }, next_msg())
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 0 } }, next_msg())
os.remove(filename)
-- jobsend() preserves NULs.
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('command', [[call jobsend(j, ["123\n456",""])]])
- eq({'notification', 'stdout', {0, {'123\n456', ''}}}, next_msg())
- nvim('command', "call jobstop(j)")
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ command([[call jobsend(j, ["123\n456",""])]])
+ eq({ 'notification', 'stdout', { 0, { '123\n456', '' } } }, next_msg())
+ command('call jobstop(j)')
end)
- it("emits partial lines (does NOT buffer data lacking newlines)", function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('command', 'call jobsend(j, "abc\\nxyz")')
- eq({'notification', 'stdout', {0, {'abc', 'xyz'}}}, next_msg())
- nvim('command', "call jobstop(j)")
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 143}}, next_msg())
+ it('emits partial lines (does NOT buffer data lacking newlines)', function()
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ command('call jobsend(j, "abc\\nxyz")')
+ eq({ 'notification', 'stdout', { 0, { 'abc', 'xyz' } } }, next_msg())
+ command('call jobstop(j)')
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 143 } }, next_msg())
end)
it('preserves newlines', function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('command', 'call jobsend(j, "a\\n\\nc\\n\\n\\n\\nb\\n\\n")')
- eq({'notification', 'stdout',
- {0, {'a', '', 'c', '', '', '', 'b', '', ''}}}, next_msg())
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ command('call jobsend(j, "a\\n\\nc\\n\\n\\n\\nb\\n\\n")')
+ eq({ 'notification', 'stdout', { 0, { 'a', '', 'c', '', '', '', 'b', '', '' } } }, next_msg())
end)
it('preserves NULs', function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('command', 'call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])')
- eq({'notification', 'stdout', {0, {'\n123\n', 'abc\nxyz\n', ''}}},
- next_msg())
- nvim('command', "call jobstop(j)")
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 143}}, next_msg())
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ command('call jobsend(j, ["\n123\n", "abc\\nxyz\n", ""])')
+ eq({ 'notification', 'stdout', { 0, { '\n123\n', 'abc\nxyz\n', '' } } }, next_msg())
+ command('call jobstop(j)')
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 143 } }, next_msg())
end)
it('avoids sending final newline', function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('command', 'call jobsend(j, ["some data", "without\nfinal nl"])')
- eq({'notification', 'stdout', {0, {'some data', 'without\nfinal nl'}}},
- next_msg())
- nvim('command', "call jobstop(j)")
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 143}}, next_msg())
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ command('call jobsend(j, ["some data", "without\nfinal nl"])')
+ eq({ 'notification', 'stdout', { 0, { 'some data', 'without\nfinal nl' } } }, next_msg())
+ command('call jobstop(j)')
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 143 } }, next_msg())
end)
it('closes the job streams with jobclose', function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('command', 'call jobclose(j, "stdin")')
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 0}}, next_msg())
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ command('call jobclose(j, "stdin")')
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 0 } }, next_msg())
end)
- it("disallows jobsend on a job that closed stdin", function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('command', 'call jobclose(j, "stdin")')
- eq(false, pcall(function()
- nvim('command', 'call jobsend(j, ["some data"])')
- end))
+ it('disallows jobsend on a job that closed stdin', function()
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ command('call jobclose(j, "stdin")')
+ eq(
+ false,
+ pcall(function()
+ command('call jobsend(j, ["some data"])')
+ end)
+ )
command("let g:job_opts.stdin = 'null'")
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- eq(false, pcall(function()
- nvim('command', 'call jobsend(j, ["some data"])')
- end))
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ eq(
+ false,
+ pcall(function()
+ command('call jobsend(j, ["some data"])')
+ end)
+ )
end)
it('disallows jobsend on a non-existent job', function()
@@ -374,91 +389,99 @@ describe('jobs', function()
end)
it('jobstop twice on the stopped or exited job return 0', function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
neq(0, eval('j'))
- eq(1, eval("jobstop(j)"))
- eq(0, eval("jobstop(j)"))
+ eq(1, eval('jobstop(j)'))
+ eq(0, eval('jobstop(j)'))
end)
it('will not leak memory if we leave a job running', function()
- nvim('command', "call jobstart(['cat', '-'], g:job_opts)")
+ command("call jobstart(['cat', '-'], g:job_opts)")
end)
it('can get the pid value using getpid', function()
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
local pid = eval('jobpid(j)')
- neq(NIL, meths.get_proc(pid))
- nvim('command', 'call jobstop(j)')
- eq({'notification', 'stdout', {0, {''}}}, next_msg())
- eq({'notification', 'exit', {0, 143}}, next_msg())
- eq(NIL, meths.get_proc(pid))
+ neq(NIL, api.nvim_get_proc(pid))
+ command('call jobstop(j)')
+ eq({ 'notification', 'stdout', { 0, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 0, 143 } }, next_msg())
+ eq(NIL, api.nvim_get_proc(pid))
end)
- it("disposed on Nvim exit", function()
+ it('disposed on Nvim exit', function()
-- use sleep, which doesn't die on stdin close
- nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)")
+ command(
+ "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)"
+ )
local pid = eval('jobpid(g:j)')
- neq(NIL, meths.get_proc(pid))
+ neq(NIL, api.nvim_get_proc(pid))
clear()
- eq(NIL, meths.get_proc(pid))
+ eq(NIL, api.nvim_get_proc(pid))
end)
it('can survive the exit of nvim with "detach"', function()
- nvim('command', 'let g:job_opts.detach = 1')
- nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)")
+ command('let g:job_opts.detach = 1')
+ command(
+ "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)"
+ )
local pid = eval('jobpid(g:j)')
- neq(NIL, meths.get_proc(pid))
+ neq(NIL, api.nvim_get_proc(pid))
clear()
- neq(NIL, meths.get_proc(pid))
+ neq(NIL, api.nvim_get_proc(pid))
-- clean up after ourselves
eq(0, os_kill(pid))
end)
it('can pass user data to the callback', function()
- nvim('command', 'let g:job_opts.user = {"n": 5, "s": "str", "l": [1]}')
- nvim('command', [[call jobstart('echo foo', g:job_opts)]])
- local data = {n = 5, s = 'str', l = {1}}
+ command('let g:job_opts.user = {"n": 5, "s": "str", "l": [1]}')
+ command([[call jobstart('echo foo', g:job_opts)]])
+ local data = { n = 5, s = 'str', l = { 1 } }
expect_msg_seq(
- { {'notification', 'stdout', {data, {'foo', ''}}},
- {'notification', 'stdout', {data, {''}}},
+ {
+ { 'notification', 'stdout', { data, { 'foo', '' } } },
+ { 'notification', 'stdout', { data, { '' } } },
},
-- Alternative sequence:
- { {'notification', 'stdout', {data, {'foo'}}},
- {'notification', 'stdout', {data, {'', ''}}},
- {'notification', 'stdout', {data, {''}}},
+ {
+ { 'notification', 'stdout', { data, { 'foo' } } },
+ { 'notification', 'stdout', { data, { '', '' } } },
+ { 'notification', 'stdout', { data, { '' } } },
}
)
- eq({'notification', 'exit', {data, 0}}, next_msg())
+ eq({ 'notification', 'exit', { data, 0 } }, next_msg())
end)
it('can omit data callbacks', function()
- nvim('command', 'unlet g:job_opts.on_stdout')
- nvim('command', 'let g:job_opts.user = 5')
- nvim('command', [[call jobstart('echo foo', g:job_opts)]])
- eq({'notification', 'exit', {5, 0}}, next_msg())
+ command('unlet g:job_opts.on_stdout')
+ command('let g:job_opts.user = 5')
+ command([[call jobstart('echo foo', g:job_opts)]])
+ eq({ 'notification', 'exit', { 5, 0 } }, next_msg())
end)
it('can omit exit callback', function()
- nvim('command', 'unlet g:job_opts.on_exit')
- nvim('command', 'let g:job_opts.user = 5')
- nvim('command', [[call jobstart('echo foo', g:job_opts)]])
+ command('unlet g:job_opts.on_exit')
+ command('let g:job_opts.user = 5')
+ command([[call jobstart('echo foo', g:job_opts)]])
expect_msg_seq(
- { {'notification', 'stdout', {5, {'foo', ''} } },
- {'notification', 'stdout', {5, {''} } },
+ {
+ { 'notification', 'stdout', { 5, { 'foo', '' } } },
+ { 'notification', 'stdout', { 5, { '' } } },
},
-- Alternative sequence:
- { {'notification', 'stdout', {5, {'foo'} } },
- {'notification', 'stdout', {5, {'', ''} } },
- {'notification', 'stdout', {5, {''} } },
+ {
+ { 'notification', 'stdout', { 5, { 'foo' } } },
+ { 'notification', 'stdout', { 5, { '', '' } } },
+ { 'notification', 'stdout', { 5, { '' } } },
}
)
end)
it('will pass return code with the exit event', function()
- nvim('command', 'let g:job_opts.user = 5')
- nvim('command', "call jobstart('exit 55', g:job_opts)")
- eq({'notification', 'stdout', {5, {''}}}, next_msg())
- eq({'notification', 'exit', {5, 55}}, next_msg())
+ command('let g:job_opts.user = 5')
+ command("call jobstart('exit 55', g:job_opts)")
+ eq({ 'notification', 'stdout', { 5, { '' } } }, next_msg())
+ eq({ 'notification', 'exit', { 5, 55 } }, next_msg())
end)
it('can receive dictionary functions', function()
@@ -469,14 +492,14 @@ describe('jobs', function()
endfunction
call jobstart('exit 45', g:dict)
]])
- eq({'notification', 'exit', {45, 10}}, next_msg())
+ eq({ 'notification', 'exit', { 45, 10 } }, next_msg())
end)
it('can redefine callbacks being used by a job', function()
local screen = Screen.new()
screen:attach()
screen:set_default_attr_ids({
- [1] = {bold=true, foreground=Screen.colors.Blue},
+ [1] = { bold = true, foreground = Screen.colors.Blue },
})
source([[
function! g:JobHandler(job_id, data, event)
@@ -495,16 +518,16 @@ describe('jobs', function()
endfunction
]])
- eq("", eval("v:errmsg"))
+ eq('', eval('v:errmsg'))
end)
it('requires funcrefs for script-local (s:) functions', function()
local screen = Screen.new(60, 5)
screen:attach()
screen:set_default_attr_ids({
- [1] = {bold = true, foreground = Screen.colors.Blue1},
- [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
- [3] = {bold = true, foreground = Screen.colors.SeaGreen4}
+ [1] = { bold = true, foreground = Screen.colors.Blue1 },
+ [2] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
+ [3] = { bold = true, foreground = Screen.colors.SeaGreen4 },
})
-- Pass job callback names _without_ `function(...)`.
@@ -519,7 +542,7 @@ describe('jobs', function()
\ })
]])
- screen:expect{any="{2:E120: Using <SID> not in a script context: s:OnEvent}"}
+ screen:expect { any = '{2:E120: Using <SID> not in a script context: s:OnEvent}' }
end)
it('does not repeat output with slow output handlers', function()
@@ -542,22 +565,22 @@ describe('jobs', function()
call jobwait([g:id])
]])
- local expected = {'1', '2', '3', '4', '5', ''}
+ local expected = { '1', '2', '3', '4', '5', '' }
local chunks = eval('d.data')
-- check nothing was received after exit, including EOF
eq(eval('g:exit_data'), chunks)
- local received = {''}
+ local received = { '' }
for i, chunk in ipairs(chunks) do
if i < #chunks then
-- if chunks got joined, a spurious [''] callback was not sent
- neq({''}, chunk)
+ neq({ '' }, chunk)
else
-- but EOF callback is still sent
- eq({''}, chunk)
+ eq({ '' }, chunk)
end
- received[#received] = received[#received]..chunk[1]
+ received[#received] = received[#received] .. chunk[1]
for j = 2, #chunk do
- received[#received+1] = chunk[j]
+ received[#received + 1] = chunk[j]
end
end
eq(expected, received)
@@ -585,22 +608,22 @@ describe('jobs', function()
call jobwait([g:id])
]])
- local expected = {'1', '2', '3', '4', '5', ''}
+ local expected = { '1', '2', '3', '4', '5', '' }
local chunks = eval('d.data')
-- check nothing was received after exit, including EOF
eq(eval('g:exit_data'), chunks)
- local received = {''}
+ local received = { '' }
for i, chunk in ipairs(chunks) do
if i < #chunks then
-- if chunks got joined, a spurious [''] callback was not sent
- neq({''}, chunk)
+ neq({ '' }, chunk)
else
-- but EOF callback is still sent
- eq({''}, chunk)
+ eq({ '' }, chunk)
end
- received[#received] = received[#received]..chunk[1]
+ received[#received] = received[#received] .. chunk[1]
for j = 2, #chunk do
- received[#received+1] = chunk[j]
+ received[#received + 1] = chunk[j]
end
end
eq(expected, received)
@@ -618,11 +641,11 @@ describe('jobs', function()
call jobstart('echo some text', g:job_opts)
]])
expect_msg_seq(
- { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}},
- },
+ { { 'notification', '1', { 'foo', 'bar', { 'some text', '' }, 'stdout' } } },
-- Alternative sequence:
- { {'notification', '1', {'foo', 'bar', {'some text'}, 'stdout'}},
- {'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}},
+ {
+ { 'notification', '1', { 'foo', 'bar', { 'some text' }, 'stdout' } },
+ { 'notification', '1', { 'foo', 'bar', { '', '' }, 'stdout' } },
}
)
end)
@@ -638,11 +661,11 @@ describe('jobs', function()
call jobstart('echo some text', g:job_opts)
]])
expect_msg_seq(
- { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}},
- },
+ { { 'notification', '1', { 'foo', 'bar', { 'some text', '' }, 'stdout' } } },
-- Alternative sequence:
- { {'notification', '1', {'foo', 'bar', {'some text'}, 'stdout'}},
- {'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}},
+ {
+ { 'notification', '1', { 'foo', 'bar', { 'some text' }, 'stdout' } },
+ { 'notification', '1', { 'foo', 'bar', { '', '' }, 'stdout' } },
}
)
end)
@@ -653,18 +676,19 @@ describe('jobs', function()
call jobstart('echo some text', g:job_opts)
]])
expect_msg_seq(
- { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}},
- },
+ { { 'notification', '1', { 'foo', 'bar', { 'some text', '' }, 'stdout' } } },
-- Alternative sequence:
- { {'notification', '1', {'foo', 'bar', {'some text'}, 'stdout'}},
- {'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}},
+ {
+ { 'notification', '1', { 'foo', 'bar', { 'some text' }, 'stdout' } },
+ { 'notification', '1', { 'foo', 'bar', { '', '' }, 'stdout' } },
}
)
end)
it('jobstart() environment: $NVIM, $NVIM_LISTEN_ADDRESS #11009', function()
local function get_env_in_child_job(envname, env)
- return exec_lua([[
+ return exec_lua(
+ [[
local envname, env = ...
local join = function(s) return vim.fn.join(s, '') end
local stdout = {}
@@ -676,12 +700,13 @@ describe('jobs', function()
on_stderr = function(chan, data, name) stderr = data end,
on_stdout = function(chan, data, name) stdout = data end,
}
- local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1',( '+echo "%s="..getenv("%s")'):format(envname, envname), '+qa!' }, opt)
+ local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1',('+echo "%s="..getenv("%s")'):format(envname, envname), '+qa!' }, opt)
vim.fn.jobwait({ j1 }, 10000)
return join({ join(stdout), join(stderr) })
]],
- envname,
- env)
+ envname,
+ env
+ )
end
local addr = eval('v:servername')
@@ -689,14 +714,18 @@ describe('jobs', function()
-- $NVIM is _not_ defined in the top-level Nvim process.
eq('', eval('$NVIM'))
-- jobstart() shares its v:servername with the child via $NVIM.
- eq('NVIM='..addr, get_env_in_child_job('NVIM'))
+ eq('NVIM=' .. addr, get_env_in_child_job('NVIM'))
-- $NVIM_LISTEN_ADDRESS is unset by server_init in the child.
eq('NVIM_LISTEN_ADDRESS=v:null', get_env_in_child_job('NVIM_LISTEN_ADDRESS'))
- eq('NVIM_LISTEN_ADDRESS=v:null', get_env_in_child_job('NVIM_LISTEN_ADDRESS',
- { NVIM_LISTEN_ADDRESS='Xtest_jobstart_env' }))
+ eq(
+ 'NVIM_LISTEN_ADDRESS=v:null',
+ get_env_in_child_job('NVIM_LISTEN_ADDRESS', { NVIM_LISTEN_ADDRESS = 'Xtest_jobstart_env' })
+ )
-- User can explicitly set $NVIM_LOG_FILE, $VIM, $VIMRUNTIME.
- eq('NVIM_LOG_FILE=Xtest_jobstart_env',
- get_env_in_child_job('NVIM_LOG_FILE', { NVIM_LOG_FILE='Xtest_jobstart_env' }))
+ eq(
+ 'NVIM_LOG_FILE=Xtest_jobstart_env',
+ get_env_in_child_job('NVIM_LOG_FILE', { NVIM_LOG_FILE = 'Xtest_jobstart_env' })
+ )
os.remove('Xtest_jobstart_env')
end)
@@ -721,7 +750,7 @@ describe('jobs', function()
\ jobstart('sleep 0.310; exit 7')
\ ]))
]])
- eq({'notification', 'wait', {{4, 5, 6, 7}}}, next_msg())
+ eq({ 'notification', 'wait', { { 4, 5, 6, 7 } } }, next_msg())
end)
it('will run callbacks while waiting', function()
@@ -751,8 +780,7 @@ describe('jobs', function()
\ ])
call rpcnotify(g:channel, 'wait', sort(g:jobs), sort(g:exits))
]])
- eq({'notification', 'wait',
- {{3,4,5,6}, {3,4,5,6}}}, next_msg())
+ eq({ 'notification', 'wait', { { 3, 4, 5, 6 }, { 3, 4, 5, 6 } } }, next_msg())
end)
it('will return status codes in the order of passed ids', function()
@@ -769,7 +797,7 @@ describe('jobs', function()
\ jobstart('sleep 0.010; exit 7')
\ ]))
]])
- eq({'notification', 'wait', {{4, 5, 6, 7}}}, next_msg())
+ eq({ 'notification', 'wait', { { 4, 5, 6, 7 } } }, next_msg())
end)
it('will return -3 for invalid job ids', function()
@@ -779,29 +807,33 @@ describe('jobs', function()
\ jobstart((has('win32') ? 'Start-Sleep -Milliseconds 100' : 'sleep 0.01').'; exit 5'),
\ ]))
]])
- eq({'notification', 'wait', {{-3, 5}}}, next_msg())
+ eq({ 'notification', 'wait', { { -3, 5 } } }, next_msg())
end)
it('will return -2 when interrupted without timeout', function()
- feed_command('call rpcnotify(g:channel, "ready") | '..
- 'call rpcnotify(g:channel, "wait", '..
- 'jobwait([jobstart("'..
- (is_os('win') and 'Start-Sleep 10' or 'sleep 10')..
- '; exit 55")]))')
- eq({'notification', 'ready', {}}, next_msg())
+ feed_command(
+ 'call rpcnotify(g:channel, "ready") | '
+ .. 'call rpcnotify(g:channel, "wait", '
+ .. 'jobwait([jobstart("'
+ .. (is_os('win') and 'Start-Sleep 10' or 'sleep 10')
+ .. '; exit 55")]))'
+ )
+ eq({ 'notification', 'ready', {} }, next_msg())
feed('<c-c>')
- eq({'notification', 'wait', {{-2}}}, next_msg())
+ eq({ 'notification', 'wait', { { -2 } } }, next_msg())
end)
it('will return -2 when interrupted with timeout', function()
- feed_command('call rpcnotify(g:channel, "ready") | '..
- 'call rpcnotify(g:channel, "wait", '..
- 'jobwait([jobstart("'..
- (is_os('win') and 'Start-Sleep 10' or 'sleep 10')..
- '; exit 55")], 10000))')
- eq({'notification', 'ready', {}}, next_msg())
+ feed_command(
+ 'call rpcnotify(g:channel, "ready") | '
+ .. 'call rpcnotify(g:channel, "wait", '
+ .. 'jobwait([jobstart("'
+ .. (is_os('win') and 'Start-Sleep 10' or 'sleep 10')
+ .. '; exit 55")], 10000))'
+ )
+ eq({ 'notification', 'ready', {} }, next_msg())
feed('<c-c>')
- eq({'notification', 'wait', {{-2}}}, next_msg())
+ eq({ 'notification', 'wait', { { -2 } } }, next_msg())
end)
it('can be called recursively', function()
@@ -844,11 +876,11 @@ describe('jobs', function()
local r
for i = 10, 1, -1 do
r = next_msg()
- eq('job '..i..' closed', r[3][1])
+ eq('job ' .. i .. ' closed', r[3][1])
r = next_msg()
- eq('job '..i..' exited', r[3][1])
+ eq('job ' .. i .. ' exited', r[3][1])
end
- eq(10, nvim('eval', 'g:counter'))
+ eq(10, api.nvim_eval('g:counter'))
end)
describe('with timeout argument', function()
@@ -858,7 +890,7 @@ describe('jobs', function()
\ jobstart((has('win32') ? 'Start-Sleep 10' : 'sleep 10').'; exit 5'),
\ ], 100))
]])
- eq({'notification', 'wait', {{-1}}}, next_msg())
+ eq({ 'notification', 'wait', { { -1 } } }, next_msg())
end)
it('can pass 0 to check if a job exists', function()
@@ -871,16 +903,16 @@ describe('jobs', function()
\ jobstart('sleep 0.3; exit 5'),
\ ], 0))
]])
- eq({'notification', 'wait', {{-1, -1}}}, next_msg())
+ eq({ 'notification', 'wait', { { -1, -1 } } }, next_msg())
end)
end)
it('hides cursor and flushes messages before blocking', function()
local screen = Screen.new(50, 6)
screen:set_default_attr_ids({
- [0] = {foreground = Screen.colors.Blue, bold = true}; -- NonText
- [1] = {bold = true, reverse = true}; -- MsgSeparator
- [2] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg
+ [0] = { foreground = Screen.colors.Blue, bold = true }, -- NonText
+ [1] = { bold = true, reverse = true }, -- MsgSeparator
+ [2] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg
})
screen:attach()
command([[let g:id = jobstart([v:progpath, '--clean', '--headless'])]])
@@ -892,56 +924,66 @@ describe('jobs', function()
endfunc
]])
feed_command('call PrintAndWait()')
- screen:expect{grid=[[
+ screen:expect {
+ grid = [[
|
- {0:~ }|
- {0:~ }|
+ {0:~ }|*2
{1: }|
aaa |
bbb |
- ]], timeout=100}
- screen:expect{grid=[[
+ ]],
+ timeout = 100,
+ }
+ screen:expect {
+ grid = [[
|
{1: }|
aaa |
bbb |
ccc |
{2:Press ENTER or type command to continue}^ |
- ]]}
+ ]],
+ }
feed('<CR>')
- funcs.jobstop(meths.get_var('id'))
+ fn.jobstop(api.nvim_get_var('id'))
end)
end)
pending('exit event follows stdout, stderr', function()
- nvim('command', "let g:job_opts.on_stderr = function('OnEvent')")
- nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)")
- nvim('eval', 'jobsend(j, "abcdef")')
- nvim('eval', 'jobstop(j)')
+ command("let g:job_opts.on_stderr = function('OnEvent')")
+ command("let j = jobstart(['cat', '-'], g:job_opts)")
+ api.nvim_eval('jobsend(j, "abcdef")')
+ api.nvim_eval('jobstop(j)')
expect_msg_seq(
- { {'notification', 'stdout', {0, {'abcdef'}}},
- {'notification', 'stdout', {0, {''}}},
- {'notification', 'stderr', {0, {''}}},
+ {
+ { 'notification', 'stdout', { 0, { 'abcdef' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
+ { 'notification', 'stderr', { 0, { '' } } },
},
-- Alternative sequence:
- { {'notification', 'stderr', {0, {''}}},
- {'notification', 'stdout', {0, {'abcdef'}}},
- {'notification', 'stdout', {0, {''}}},
+ {
+ { 'notification', 'stderr', { 0, { '' } } },
+ { 'notification', 'stdout', { 0, { 'abcdef' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
},
-- Alternative sequence:
- { {'notification', 'stdout', {0, {'abcdef'}}},
- {'notification', 'stderr', {0, {''}}},
- {'notification', 'stdout', {0, {''}}},
+ {
+ { 'notification', 'stdout', { 0, { 'abcdef' } } },
+ { 'notification', 'stderr', { 0, { '' } } },
+ { 'notification', 'stdout', { 0, { '' } } },
}
)
- eq({'notification', 'exit', {0, 143}}, next_msg())
+ eq({ 'notification', 'exit', { 0, 143 } }, next_msg())
end)
it('cannot have both rpc and pty options', function()
- command("let g:job_opts.pty = v:true")
- command("let g:job_opts.rpc = v:true")
+ command('let g:job_opts.pty = v:true')
+ command('let g:job_opts.rpc = v:true')
local _, err = pcall(command, "let j = jobstart(['cat', '-'], g:job_opts)")
- ok(string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set") ~= nil)
+ ok(
+ string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set")
+ ~= nil
+ )
end)
it('does not crash when repeatedly failing to start shell', function()
@@ -954,7 +996,7 @@ describe('jobs', function()
]])
-- The crash only triggered if both jobs are cleaned up on the same event
-- loop tick. This is also prevented by try-block, so feed must be used.
- feed_command("call DoIt()")
+ feed_command('call DoIt()')
feed('<cr>') -- press RETURN
assert_alive()
end)
@@ -991,7 +1033,7 @@ describe('jobs', function()
\ 'substitute(v:val, "\r", "", "")'),
\ 'split(v:val, "\\s\\+")')
if len(proc) == 6
- let s:procs[proc[1]] ..']]'..[[= {'name': proc[0],
+ let s:procs[proc[1]] .. ']]' .. [[= {'name': proc[0],
\ 'Session Name': proc[2],
\ 'Session': proc[3]}
endif
@@ -1015,15 +1057,13 @@ describe('jobs', function()
endfunction
]])
end
- local sleep_cmd = (is_os('win')
- and 'ping -n 31 127.0.0.1'
- or 'sleep 30')
- local j = eval("jobstart('"..sleep_cmd..' | '..sleep_cmd..' | '..sleep_cmd.."')")
- local ppid = funcs.jobpid(j)
+ local sleep_cmd = (is_os('win') and 'ping -n 31 127.0.0.1' or 'sleep 30')
+ local j = eval("jobstart('" .. sleep_cmd .. ' | ' .. sleep_cmd .. ' | ' .. sleep_cmd .. "')")
+ local ppid = fn.jobpid(j)
local children
if is_os('win') then
local status, result = pcall(retry, nil, nil, function()
- children = meths.get_proc_children(ppid)
+ children = api.nvim_get_proc_children(ppid)
-- On Windows conhost.exe may exist, and
-- e.g. vctip.exe might appear. #10783
ok(#children >= 3 and #children <= 5)
@@ -1034,36 +1074,38 @@ describe('jobs', function()
error(result)
end
else
- retry(nil, nil, function()
- children = meths.get_proc_children(ppid)
+ retry(nil, nil, function()
+ children = api.nvim_get_proc_children(ppid)
eq(3, #children)
end)
end
-- Assert that nvim_get_proc() sees the children.
for _, child_pid in ipairs(children) do
- local info = meths.get_proc(child_pid)
+ local info = api.nvim_get_proc(child_pid)
-- eq((is_os('win') and 'nvim.exe' or 'nvim'), info.name)
eq(ppid, info.ppid)
end
-- Kill the root of the tree.
- eq(1, funcs.jobstop(j))
+ eq(1, fn.jobstop(j))
-- Assert that the children were killed.
retry(nil, nil, function()
for _, child_pid in ipairs(children) do
- eq(NIL, meths.get_proc(child_pid))
+ eq(NIL, api.nvim_get_proc(child_pid))
end
end)
end)
it('jobstop on same id before stopped', function()
- nvim('command', 'let j = jobstart(["cat", "-"], g:job_opts)')
+ command('let j = jobstart(["cat", "-"], g:job_opts)')
neq(0, eval('j'))
- eq({1, 0}, eval('[jobstop(j), jobstop(j)]'))
+ eq({ 1, 0 }, eval('[jobstop(j), jobstop(j)]'))
end)
describe('running tty-test program', function()
- if skip(is_os('win')) then return end
+ if skip(is_os('win')) then
+ return
+ end
local function next_chunk()
local rv
while true do
@@ -1084,7 +1126,7 @@ describe('jobs', function()
local j
local function send(str)
-- check no nvim_chan_free double free with pty job (#14198)
- meths.chan_send(j, str)
+ api.nvim_chan_send(j, str)
end
before_each(function()
@@ -1095,10 +1137,10 @@ describe('jobs', function()
endfunction
]])
insert(testprg('tty-test'))
- nvim('command', 'let g:job_opts.pty = 1')
- nvim('command', 'let exec = [expand("<cfile>:p")]')
- nvim('command', "let j = jobstart(exec, g:job_opts)")
- j = eval'j'
+ command('let g:job_opts.pty = 1')
+ command('let exec = [expand("<cfile>:p")]')
+ command('let j = jobstart(exec, g:job_opts)')
+ j = eval 'j'
eq('tty ready', next_chunk())
end)
@@ -1108,17 +1150,17 @@ describe('jobs', function()
end)
it('resizing window', function()
- nvim('command', 'call jobresize(j, 40, 10)')
+ command('call jobresize(j, 40, 10)')
eq('rows: 10, cols: 40', next_chunk())
- nvim('command', 'call jobresize(j, 10, 40)')
+ command('call jobresize(j, 10, 40)')
eq('rows: 40, cols: 10', next_chunk())
end)
it('jobclose() sends SIGHUP', function()
- nvim('command', 'call jobclose(j)')
+ command('call jobclose(j)')
local msg = next_msg()
- msg = (msg[2] == 'stdout') and next_msg() or msg -- Skip stdout, if any.
- eq({'notification', 'exit', {0, 42}}, msg)
+ msg = (msg[2] == 'stdout') and next_msg() or msg -- Skip stdout, if any.
+ eq({ 'notification', 'exit', { 0, 42 } }, msg)
end)
it('jobstart() does not keep ptmx file descriptor open', function()
@@ -1132,7 +1174,7 @@ describe('jobs', function()
-- Have to wait so that the SIGHUP can be processed by tty-test on time.
-- Can't wait for the next message in case this test fails, if it fails
-- there won't be any more messages, and the test would hang.
- helpers.sleep(100)
+ vim.uv.sleep(100)
local err = exc_exec('call jobpid(j)')
eq('Vim(call):E900: Invalid channel id', err)
@@ -1141,9 +1183,49 @@ describe('jobs', function()
command('call jobstop(' .. other_jobid .. ')')
end)
end)
+
+ it('does not close the same handle twice on exit #25086', function()
+ local filename = string.format('%s.lua', helpers.tmpname())
+ write_file(
+ filename,
+ [[
+ vim.api.nvim_create_autocmd('VimLeavePre', {
+ callback = function()
+ local id = vim.fn.jobstart('sleep 0')
+ vim.fn.jobwait({id})
+ end,
+ })
+ ]]
+ )
+
+ local screen = thelpers.setup_child_nvim({
+ '--cmd',
+ 'set notermguicolors',
+ '-i',
+ 'NONE',
+ '-u',
+ filename,
+ })
+ -- Wait for startup to complete, so that all terminal responses are received.
+ screen:expect([[
+ {1: } |
+ ~ |*3
+ {1:[No Name] 0,0-1 All}|
+ |
+ {3:-- TERMINAL --} |
+ ]])
+
+ feed(':q<CR>')
+ screen:expect([[
+ |
+ [Process exited 0]{1: } |
+ |*4
+ {3:-- TERMINAL --} |
+ ]])
+ end)
end)
-describe("pty process teardown", function()
+describe('pty process teardown', function()
local screen
before_each(function()
clear()
@@ -1151,31 +1233,33 @@ describe("pty process teardown", function()
screen:attach()
screen:expect([[
^ |
- ~ |
- ~ |
- ~ |
- ~ |
+ ~ |*4
|
]])
end)
- it("does not prevent/delay exit. #4798 #4900", function()
- skip(is_os('win'))
+ it('does not prevent/delay exit. #4798 #4900', function()
-- Use a nested nvim (in :term) to test without --headless.
- feed_command(":terminal '"..helpers.nvim_prog
- .."' -u NONE -i NONE --cmd '"..nvim_set.."' "
+ fn.termopen({
+ helpers.nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ nvim_set,
-- Use :term again in the _nested_ nvim to get a PTY process.
-- Use `sleep` to simulate a long-running child of the PTY.
- .."+terminal +'!(sleep 300 &)' +qa")
+ '+terminal',
+ '+!(sleep 300 &)',
+ '+qa',
+ }, { env = { VIMRUNTIME = os.getenv('VIMRUNTIME') } })
-- Exiting should terminate all descendants (PTY, its children, ...).
screen:expect([[
^ |
[Process exited 0] |
- |
- |
- |
- |
+ |*4
]])
end)
end)
diff --git a/test/functional/core/log_spec.lua b/test/functional/core/log_spec.lua
index f682df4155..1637e683c1 100644
--- a/test/functional/core/log_spec.lua
+++ b/test/functional/core/log_spec.lua
@@ -23,7 +23,7 @@ describe('log', function()
-- calls, that needs investigation.
clear()
eq(0, request('nvim__stats').log_skip)
- clear{env={CDPATH='~doesnotexist'}}
+ clear { env = { CDPATH = '~doesnotexist' } }
assert(request('nvim__stats').log_skip <= 13)
end)
@@ -32,14 +32,16 @@ describe('log', function()
-- ERR 2022-05-29T12:30:03.800 T2 log_init:110: test log message
-- ERR 2022-05-29T12:30:03.814 T2/child log_init:110: test log message
- clear({env={
- NVIM_LOG_FILE=testlog,
- -- TODO: remove this after nvim_log #7062 is merged.
- __NVIM_TEST_LOG='1'
- }})
+ clear({
+ env = {
+ NVIM_LOG_FILE = testlog,
+ -- TODO: remove this after nvim_log #7062 is merged.
+ __NVIM_TEST_LOG = '1',
+ },
+ })
local tid = _G._nvim_test_id
- assert_log(tid..'%.%d+%.%d +server_init:%d+: test log message', testlog, 100)
+ assert_log(tid .. '%.%d+%.%d +server_init:%d+: test log message', testlog, 100)
exec_lua([[
local j1 = vim.fn.jobstart({ vim.v.progpath, '-es', '-V1', '+foochild', '+qa!' }, vim.empty_dict())
diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua
index 19c7a93730..9d8d64c82d 100644
--- a/test/functional/core/main_spec.lua
+++ b/test/functional/core/main_spec.lua
@@ -1,4 +1,4 @@
-local luv = require('luv')
+local uv = vim.uv
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
@@ -7,7 +7,7 @@ local matches = helpers.matches
local feed = helpers.feed
local eval = helpers.eval
local clear = helpers.clear
-local funcs = helpers.funcs
+local fn = helpers.fn
local nvim_prog_abs = helpers.nvim_prog_abs
local write_file = helpers.write_file
local is_os = helpers.is_os
@@ -32,28 +32,57 @@ describe('command-line option', function()
end)
it('treats - as stdin', function()
- eq(nil, luv.fs_stat(fname))
- funcs.system(
- {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless',
- '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix',
- '-s', '-', fname},
- {':call setline(1, "42")', ':wqall!', ''})
+ eq(nil, uv.fs_stat(fname))
+ fn.system({
+ nvim_prog_abs(),
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '--cmd',
+ 'set noswapfile shortmess+=IFW fileformats=unix',
+ '-s',
+ '-',
+ fname,
+ }, { ':call setline(1, "42")', ':wqall!', '' })
eq(0, eval('v:shell_error'))
- local attrs = luv.fs_stat(fname)
- eq(#('42\n'), attrs.size)
+ local attrs = uv.fs_stat(fname)
+ eq(#'42\n', attrs.size)
end)
it('does not expand $VAR', function()
- eq(nil, luv.fs_stat(fname))
+ eq(nil, uv.fs_stat(fname))
eq(true, not not dollar_fname:find('%$%w+'))
write_file(dollar_fname, ':call setline(1, "100500")\n:wqall!\n')
- funcs.system(
- {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless',
- '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix',
- '-s', dollar_fname, fname})
+ fn.system({
+ nvim_prog_abs(),
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '--cmd',
+ 'set noswapfile shortmess+=IFW fileformats=unix',
+ '-s',
+ dollar_fname,
+ fname,
+ })
+ eq(0, eval('v:shell_error'))
+ local attrs = uv.fs_stat(fname)
+ eq(#'100500\n', attrs.size)
+ end)
+
+ it('does not crash when run completion in ex mode', function()
+ fn.system({
+ nvim_prog_abs(),
+ '--clean',
+ '-e',
+ '-s',
+ '--cmd',
+ 'exe "norm! i\\<C-X>\\<C-V>"',
+ })
eq(0, eval('v:shell_error'))
- local attrs = luv.fs_stat(fname)
- eq(#('100500\n'), attrs.size)
end)
it('does not crash after reading from stdin in non-headless mode', function()
@@ -61,36 +90,38 @@ describe('command-line option', function()
local screen = Screen.new(40, 8)
screen:attach()
local args = {
- nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE',
- '--cmd', '"set noswapfile shortmess+=IFW fileformats=unix"',
- '-s', '-'
+ nvim_prog_abs(),
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ '"set noswapfile shortmess+=IFW fileformats=unix notermguicolors"',
+ '-s',
+ '-',
}
-- Need to explicitly pipe to stdin so that the embedded Nvim instance doesn't try to read
-- data from the terminal #18181
- funcs.termopen(string.format([[echo "" | %s]], table.concat(args, " ")))
- screen:expect([[
- ^ |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {2:[No Name] 0,0-1 All}|
- |
- |
- ]], {
- [1] = {foreground = tonumber('0x4040ff'), fg_indexed=true},
- [2] = {bold = true, reverse = true}
+ fn.termopen(string.format([[echo "" | %s]], table.concat(args, ' ')), {
+ env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
})
+ screen:expect(
+ [[
+ ^ |
+ ~ |*4
+ {1:[No Name] 0,0-1 All}|
+ |*2
+ ]],
+ {
+ [1] = { reverse = true },
+ }
+ )
feed('i:cq<CR>')
screen:expect([[
|
[Process exited 1] |
- |
- |
- |
- |
- |
+ |*5
-- TERMINAL -- |
]])
--[=[ Example of incorrect output:
@@ -101,20 +132,29 @@ describe('command-line option', function()
LENO' failed. |
|
[Process exited 6] |
- |
- |
+ |*2
]])
]=]
end)
it('errors out when trying to use nonexistent file with -s', function()
eq(
- 'Cannot open for reading: "'..nonexistent_fname..'": no such file or directory\n',
- funcs.system(
- {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless',
- '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix',
- '--cmd', 'language C',
- '-s', nonexistent_fname}))
+ 'Cannot open for reading: "' .. nonexistent_fname .. '": no such file or directory\n',
+ fn.system({
+ nvim_prog_abs(),
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '--cmd',
+ 'set noswapfile shortmess+=IFW fileformats=unix',
+ '--cmd',
+ 'language C',
+ '-s',
+ nonexistent_fname,
+ })
+ )
eq(2, eval('v:shell_error'))
end)
@@ -122,21 +162,34 @@ describe('command-line option', function()
write_file(fname, ':call setline(1, "1")\n:wqall!\n')
write_file(dollar_fname, ':call setline(1, "2")\n:wqall!\n')
eq(
- 'Attempt to open script file again: "-s '..dollar_fname..'"\n',
- funcs.system(
- {nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless',
- '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix',
- '--cmd', 'language C',
- '-s', fname, '-s', dollar_fname, fname_2}))
+ 'Attempt to open script file again: "-s ' .. dollar_fname .. '"\n',
+ fn.system({
+ nvim_prog_abs(),
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '--cmd',
+ 'set noswapfile shortmess+=IFW fileformats=unix',
+ '--cmd',
+ 'language C',
+ '-s',
+ fname,
+ '-s',
+ dollar_fname,
+ fname_2,
+ })
+ )
eq(2, eval('v:shell_error'))
- eq(nil, luv.fs_stat(fname_2))
+ eq(nil, uv.fs_stat(fname_2))
end)
end)
it('nvim -v, :version', function()
- matches('Run ":verbose version"', funcs.execute(':version'))
- matches('Compilation: .*Run :checkhealth', funcs.execute(':verbose version'))
- matches('Run "nvim %-V1 %-v"', funcs.system({nvim_prog_abs(), '-v'}))
- matches('Compilation: .*Run :checkhealth', funcs.system({nvim_prog_abs(), '-V1', '-v'}))
+ matches('Run ":verbose version"', fn.execute(':version'))
+ matches('Compilation: .*Run :checkhealth', fn.execute(':verbose version'))
+ matches('Run "nvim %-V1 %-v"', fn.system({ nvim_prog_abs(), '-v' }))
+ matches('Compilation: .*Run :checkhealth', fn.system({ nvim_prog_abs(), '-V1', '-v' }))
end)
end)
diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua
index 97c32f7de6..e98bfc0d45 100644
--- a/test/functional/core/path_spec.lua
+++ b/test/functional/core/path_spec.lua
@@ -4,7 +4,7 @@ local command = helpers.command
local eq = helpers.eq
local eval = helpers.eval
local feed = helpers.feed
-local funcs = helpers.funcs
+local fn = helpers.fn
local insert = helpers.insert
local is_os = helpers.is_os
local mkdir = helpers.mkdir
@@ -13,7 +13,7 @@ local write_file = helpers.write_file
local function join_path(...)
local pathsep = (is_os('win') and '\\' or '/')
- return table.concat({...}, pathsep)
+ return table.concat({ ... }, pathsep)
end
describe('path collapse', function()
@@ -23,40 +23,40 @@ describe('path collapse', function()
before_each(function()
targetdir = join_path('test', 'functional', 'fixtures')
clear()
- command('edit '..join_path(targetdir, 'tty-test.c'))
+ command('edit ' .. join_path(targetdir, 'tty-test.c'))
expected_path = eval('expand("%:p")')
end)
it('with /./ segment #7117', function()
- command('edit '..join_path(targetdir, '.', 'tty-test.c'))
+ command('edit ' .. join_path(targetdir, '.', 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ./ prefix #7117', function()
- command('edit '..join_path('.', targetdir, 'tty-test.c'))
+ command('edit ' .. join_path('.', targetdir, 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ./ prefix, after directory change #7117', function()
- command('edit '..join_path('.', targetdir, 'tty-test.c'))
+ command('edit ' .. join_path('.', targetdir, 'tty-test.c'))
command('cd test')
eq(expected_path, eval('expand("%:p")'))
end)
it('with /../ segment #7117', function()
- command('edit '..join_path(targetdir, '..', 'fixtures', 'tty-test.c'))
+ command('edit ' .. join_path(targetdir, '..', 'fixtures', 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ../ and different starting directory #7117', function()
command('cd test')
- command('edit '..join_path('..', targetdir, 'tty-test.c'))
+ command('edit ' .. join_path('..', targetdir, 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
it('with ./../ and different starting directory #7117', function()
command('cd test')
- command('edit '..join_path('.', '..', targetdir, 'tty-test.c'))
+ command('edit ' .. join_path('.', '..', targetdir, 'tty-test.c'))
eq(expected_path, eval('expand("%:p")'))
end)
end)
@@ -67,16 +67,16 @@ describe('expand wildcard', function()
it('with special characters #24421', function()
local folders = is_os('win') and {
'{folder}',
- 'folder$name'
+ 'folder$name',
} or {
'folder-name',
- 'folder#name'
+ 'folder#name',
}
for _, folder in ipairs(folders) do
mkdir(folder)
local file = join_path(folder, 'file.txt')
write_file(file, '')
- eq(file, eval('expand("'..folder..'/*")'))
+ eq(file, eval('expand("' .. folder .. '/*")'))
rmdir(folder)
end
end)
@@ -131,14 +131,30 @@ describe('file search', function()
test_cfile([[c:foo]], [[c]])
-- Examples from: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#example-ways-to-refer-to-the-same-file
test_cfile([[c:\temp\test-file.txt]], [[c:]], [[c:\temp\test-file.txt]])
- test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]])
- test_cfile([[\\LOCALHOST\c$\temp\test-file.txt]], [[LOCALHOST]], [[\\LOCALHOST\c$\temp\test-file.txt]])
+ test_cfile(
+ [[\\127.0.0.1\c$\temp\test-file.txt]],
+ [[127.0.0.1]],
+ [[\\127.0.0.1\c$\temp\test-file.txt]]
+ )
+ test_cfile(
+ [[\\LOCALHOST\c$\temp\test-file.txt]],
+ [[LOCALHOST]],
+ [[\\LOCALHOST\c$\temp\test-file.txt]]
+ )
-- not supported yet
test_cfile([[\\.\c:\temp\test-file.txt]], [[.]], [[\\.\c]])
-- not supported yet
test_cfile([[\\?\c:\temp\test-file.txt]], [[c:]], [[\\]])
- test_cfile([[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]], [[.]], [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]])
- test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]])
+ test_cfile(
+ [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]],
+ [[.]],
+ [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]]
+ )
+ test_cfile(
+ [[\\127.0.0.1\c$\temp\test-file.txt]],
+ [[127.0.0.1]],
+ [[\\127.0.0.1\c$\temp\test-file.txt]]
+ )
end)
---@param funcname 'finddir' | 'findfile'
@@ -151,7 +167,7 @@ describe('file search', function()
else
write_file(expected, '')
end
- eq(expected, funcs[funcname](item, d:gsub(' ', [[\ ]])))
+ eq(expected, fn[funcname](item, d:gsub(' ', [[\ ]])))
end
it('finddir()', function()
diff --git a/test/functional/core/remote_spec.lua b/test/functional/core/remote_spec.lua
index a0ec748446..caff06f6ab 100644
--- a/test/functional/core/remote_spec.lua
+++ b/test/functional/core/remote_spec.lua
@@ -6,7 +6,7 @@ local eq = helpers.eq
local exec_capture = helpers.exec_capture
local exec_lua = helpers.exec_lua
local expect = helpers.expect
-local funcs = helpers.funcs
+local fn = helpers.fn
local insert = helpers.insert
local nvim_prog = helpers.nvim_prog
local new_argv = helpers.new_argv
@@ -42,7 +42,7 @@ describe('Remote', function()
-- Run a `nvim --remote*` command and return { stdout, stderr } of the process
local function run_remote(...)
set_session(server)
- local addr = funcs.serverlist()[1]
+ local addr = fn.serverlist()[1]
-- Create an nvim instance just to run the remote-invoking nvim. We want
-- to wait for the remote instance to exit and calling jobwait blocks
@@ -51,7 +51,10 @@ describe('Remote', function()
local client_starter = spawn(new_argv(), false, nil, true)
set_session(client_starter)
-- Call jobstart() and jobwait() in the same RPC request to reduce flakiness.
- eq({ 0 }, exec_lua([[return vim.fn.jobwait({ vim.fn.jobstart({...}, {
+ eq(
+ { 0 },
+ exec_lua(
+ [[return vim.fn.jobwait({ vim.fn.jobstart({...}, {
stdout_buffered = true,
stderr_buffered = true,
on_stdout = function(_, data, _)
@@ -60,7 +63,15 @@ describe('Remote', function()
on_stderr = function(_, data, _)
_G.Remote_stderr = table.concat(data, '\n')
end,
- }) })]], nvim_prog, '--clean', '--headless', '--server', addr, ...))
+ }) })]],
+ nvim_prog,
+ '--clean',
+ '--headless',
+ '--server',
+ addr,
+ ...
+ )
+ )
local res = exec_lua([[return { _G.Remote_stdout, _G.Remote_stderr }]])
client_starter:close()
set_session(server)
@@ -70,20 +81,20 @@ describe('Remote', function()
it('edit a single file', function()
eq({ '', '' }, run_remote('--remote', fname))
expect(contents)
- eq(2, #funcs.getbufinfo())
+ eq(1, #fn.getbufinfo())
end)
it('tab edit a single file with a non-changed buffer', function()
eq({ '', '' }, run_remote('--remote-tab', fname))
expect(contents)
- eq(1, #funcs.gettabinfo())
+ eq(1, #fn.gettabinfo())
end)
it('tab edit a single file with a changed buffer', function()
insert('hello')
eq({ '', '' }, run_remote('--remote-tab', fname))
expect(contents)
- eq(2, #funcs.gettabinfo())
+ eq(2, #fn.gettabinfo())
end)
it('edit multiple files', function()
@@ -91,15 +102,15 @@ describe('Remote', function()
expect(contents)
command('next')
expect(other_contents)
- eq(3, #funcs.getbufinfo())
+ eq(2, #fn.getbufinfo())
end)
it('send keys', function()
- eq({ '', '' }, run_remote('--remote-send', ':edit '..fname..'<CR><C-W>v'))
+ eq({ '', '' }, run_remote('--remote-send', ':edit ' .. fname .. '<CR><C-W>v'))
expect(contents)
- eq(2, #funcs.getwininfo())
+ eq(2, #fn.getwininfo())
-- Only a single buffer as we're using edit and not drop like --remote does
- eq(1, #funcs.getbufinfo())
+ eq(1, #fn.getbufinfo())
end)
it('evaluate expressions', function()
@@ -116,7 +127,7 @@ describe('Remote', function()
it('creates server if not found', function()
clear('--remote', fname)
expect(contents)
- eq(1, #funcs.getbufinfo())
+ eq(1, #fn.getbufinfo())
-- Since we didn't pass silent, we should get a complaint
neq(nil, string.find(exec_capture('messages'), 'E247:'))
end)
@@ -124,8 +135,8 @@ describe('Remote', function()
it('creates server if not found with tabs', function()
clear('--remote-tab-silent', fname, other_fname)
expect(contents)
- eq(2, #funcs.gettabinfo())
- eq(2, #funcs.getbufinfo())
+ eq(2, #fn.gettabinfo())
+ eq(2, #fn.getbufinfo())
-- We passed silent, so no message should be issued about the server not being found
eq(nil, string.find(exec_capture('messages'), 'E247:'))
end)
diff --git a/test/functional/core/spellfile_spec.lua b/test/functional/core/spellfile_spec.lua
index e3a59085cf..57953b8f80 100644
--- a/test/functional/core/spellfile_spec.lua
+++ b/test/functional/core/spellfile_spec.lua
@@ -2,8 +2,9 @@ local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local clear = helpers.clear
-local meths = helpers.meths
+local api = helpers.api
local exc_exec = helpers.exc_exec
+local fn = helpers.fn
local rmdir = helpers.rmdir
local write_file = helpers.write_file
local mkdir = helpers.mkdir
@@ -24,7 +25,8 @@ describe('spellfile', function()
-- │ ┌ Spell file version (#VIMSPELLVERSION)
local spellheader = 'VIMspell\050'
it('errors out when prefcond section is truncated', function()
- meths.set_option_value('runtimepath', testdir, {})
+ api.nvim_set_option_value('runtimepath', testdir, {})
+ -- stylua: ignore
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_PREFCOND)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -34,12 +36,12 @@ describe('spellfile', function()
-- │ ┌ Condition length (1 byte)
-- │ │ ┌ Condition regex (missing!)
.. '\000\001\001')
- meths.set_option_value('spelllang', 'en', {})
- eq('Vim(set):E758: Truncated spell file',
- exc_exec('set spell'))
+ api.nvim_set_option_value('spelllang', 'en', {})
+ eq('Vim(set):E758: Truncated spell file', exc_exec('set spell'))
end)
it('errors out when prefcond regexp contains NUL byte', function()
- meths.set_option_value('runtimepath', testdir, {})
+ api.nvim_set_option_value('runtimepath', testdir, {})
+ -- stylua: ignore
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_PREFCOND)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -54,12 +56,12 @@ describe('spellfile', function()
-- │ ┌ KWORDTREE tree length (4 bytes)
-- │ │ ┌ PREFIXTREE tree length
.. '\000\000\000\000\000\000\000\000\000\000\000\000')
- meths.set_option_value('spelllang', 'en', {})
- eq('Vim(set):E759: Format error in spell file',
- exc_exec('set spell'))
+ api.nvim_set_option_value('spelllang', 'en', {})
+ eq('Vim(set):E759: Format error in spell file', exc_exec('set spell'))
end)
it('errors out when region contains NUL byte', function()
- meths.set_option_value('runtimepath', testdir, {})
+ api.nvim_set_option_value('runtimepath', testdir, {})
+ -- stylua: ignore
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_REGION)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -71,12 +73,12 @@ describe('spellfile', function()
-- │ ┌ KWORDTREE tree length (4 bytes)
-- │ │ ┌ PREFIXTREE tree length
.. '\000\000\000\000\000\000\000\000\000\000\000\000')
- meths.set_option_value('spelllang', 'en', {})
- eq('Vim(set):E759: Format error in spell file',
- exc_exec('set spell'))
+ api.nvim_set_option_value('spelllang', 'en', {})
+ eq('Vim(set):E759: Format error in spell file', exc_exec('set spell'))
end)
it('errors out when SAL section contains NUL byte', function()
- meths.set_option_value('runtimepath', testdir, {})
+ api.nvim_set_option_value('runtimepath', testdir, {})
+ -- stylua: ignore
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_SAL)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -95,16 +97,23 @@ describe('spellfile', function()
-- │ ┌ KWORDTREE tree length (4 bytes)
-- │ │ ┌ PREFIXTREE tree length
.. '\000\000\000\000\000\000\000\000\000\000\000\000')
- meths.set_option_value('spelllang', 'en', {})
- eq('Vim(set):E759: Format error in spell file',
- exc_exec('set spell'))
+ api.nvim_set_option_value('spelllang', 'en', {})
+ eq('Vim(set):E759: Format error in spell file', exc_exec('set spell'))
end)
it('errors out when spell header contains NUL bytes', function()
- meths.set_option_value('runtimepath', testdir, {})
- write_file(testdir .. '/spell/en.ascii.spl',
- spellheader:sub(1, -3) .. '\000\000')
- meths.set_option_value('spelllang', 'en', {})
- eq('Vim(set):E757: This does not look like a spell file',
- exc_exec('set spell'))
+ api.nvim_set_option_value('runtimepath', testdir, {})
+ write_file(testdir .. '/spell/en.ascii.spl', spellheader:sub(1, -3) .. '\000\000')
+ api.nvim_set_option_value('spelllang', 'en', {})
+ eq('Vim(set):E757: This does not look like a spell file', exc_exec('set spell'))
+ end)
+
+ it('can be set to a relative path', function()
+ local fname = testdir .. '/spell/spell.add'
+ api.nvim_set_option_value('spellfile', fname, {})
+ end)
+
+ it('can be set to an absolute path', function()
+ local fname = fn.fnamemodify(testdir .. '/spell/spell.add', ':p')
+ api.nvim_set_option_value('spellfile', fname, {})
end)
end)
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 94ec3d4907..cc58226f48 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -13,8 +13,8 @@ local exec = helpers.exec
local exec_capture = helpers.exec_capture
local exec_lua = helpers.exec_lua
local feed = helpers.feed
-local funcs = helpers.funcs
-local pesc = helpers.pesc
+local fn = helpers.fn
+local pesc = vim.pesc
local mkdir = helpers.mkdir
local mkdir_p = helpers.mkdir_p
local nvim_prog = helpers.nvim_prog
@@ -22,23 +22,37 @@ local nvim_set = helpers.nvim_set
local read_file = helpers.read_file
local retry = helpers.retry
local rmdir = helpers.rmdir
-local sleep = helpers.sleep
-local startswith = helpers.startswith
+local sleep = vim.uv.sleep
+local startswith = vim.startswith
local write_file = helpers.write_file
-local meths = helpers.meths
+local api = helpers.api
local alter_slashes = helpers.alter_slashes
local is_os = helpers.is_os
local dedent = helpers.dedent
-local tbl_map = helpers.tbl_map
-local tbl_filter = helpers.tbl_filter
-local endswith = helpers.endswith
+local tbl_map = vim.tbl_map
+local tbl_filter = vim.tbl_filter
+local endswith = vim.endswith
describe('startup', function()
it('--clean', function()
clear()
- ok(string.find(alter_slashes(meths.get_option_value('runtimepath', {})), funcs.stdpath('config'), 1, true) ~= nil)
+ ok(
+ string.find(
+ alter_slashes(api.nvim_get_option_value('runtimepath', {})),
+ fn.stdpath('config'),
+ 1,
+ true
+ ) ~= nil
+ )
clear('--clean')
- ok(string.find(alter_slashes(meths.get_option_value('runtimepath', {})), funcs.stdpath('config'), 1, true) == nil)
+ ok(
+ string.find(
+ alter_slashes(api.nvim_get_option_value('runtimepath', {})),
+ fn.stdpath('config'),
+ 1,
+ true
+ ) == nil
+ )
end)
it('prevents remote UI infinite loop', function()
@@ -46,11 +60,10 @@ describe('startup', function()
local screen
screen = Screen.new(84, 3)
screen:attach()
- funcs.termopen({ nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' })
+ fn.termopen({ nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' })
screen:expect([[
^Cannot attach UI of :terminal child to its parent. (Unset $NVIM to skip this check) |
- |
- |
+ |*2
]])
end)
@@ -59,7 +72,8 @@ describe('startup', function()
finally(function()
os.remove(testfile)
end)
- clear({ args = {'--startuptime', testfile}})
+ clear({ args = { '--startuptime', testfile } })
+ assert_log('Embedded', testfile, 100)
assert_log('sourcing', testfile, 100)
assert_log("require%('vim%._editor'%)", testfile, 100)
end)
@@ -69,8 +83,20 @@ describe('startup', function()
local screen
screen = Screen.new(60, 7)
screen:attach()
- command([[let g:id = termopen('"]]..nvim_prog..
- [[" -u NONE -i NONE --cmd "set noruler" -D')]])
+ local id = fn.termopen({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'set noruler',
+ '-D',
+ }, {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ })
screen:expect([[
^ |
|
@@ -80,15 +106,12 @@ describe('startup', function()
> |
|
]])
- command([[call chansend(g:id, "cont\n")]])
+ fn.chansend(id, 'cont\n')
screen:expect([[
^ |
- ~ |
- ~ |
- ~ |
+ ~ |*3
[No Name] |
- |
- |
+ |*2
]])
end)
end)
@@ -102,13 +125,13 @@ describe('startup', function()
vim.list_extend(args, nvim_args or {})
vim.list_extend(args, { '-l', (script or 'test/functional/fixtures/startup.lua') })
vim.list_extend(args, lua_args or {})
- local out = funcs.system(args, input):gsub('\r\n', '\n')
+ local out = fn.system(args, input):gsub('\r\n', '\n')
return eq(dedent(expected), out)
end
it('failure modes', function()
-- nvim -l <empty>
- matches('nvim%.?e?x?e?: Argument missing after: "%-l"', funcs.system({ nvim_prog, '-l' }))
+ matches('nvim%.?e?x?e?: Argument missing after: "%-l"', fn.system({ nvim_prog, '-l' }))
eq(1, eval('v:shell_error'))
end)
@@ -122,39 +145,48 @@ describe('startup', function()
vim.uv.os_setenv('ASAN_OPTIONS', asan_options .. ':detect_leaks=0')
]]
-- nvim -l foo.lua -arg1 -- a b c
- assert_l_out([[
+ assert_l_out(
+ [[
bufs:
nvim args: 7
lua args: { "-arg1", "--exitcode", "73", "--arg2",
[0] = "test/functional/fixtures/startup.lua"
}]],
{},
- { '-arg1', "--exitcode", "73", '--arg2' }
+ { '-arg1', '--exitcode', '73', '--arg2' }
)
eq(73, eval('v:shell_error'))
end)
it('Lua-error sets Nvim exitcode', function()
eq(0, eval('v:shell_error'))
- matches('E5113: .* my pearls!!',
- funcs.system({ nvim_prog, '-l', 'test/functional/fixtures/startup-fail.lua' }))
+ matches(
+ 'E5113: .* my pearls!!',
+ fn.system({ nvim_prog, '-l', 'test/functional/fixtures/startup-fail.lua' })
+ )
eq(1, eval('v:shell_error'))
- matches('E5113: .* %[string "error%("whoa"%)"%]:1: whoa',
- funcs.system({ nvim_prog, '-l', '-' }, 'error("whoa")'))
+ matches(
+ 'E5113: .* %[string "error%("whoa"%)"%]:1: whoa',
+ fn.system({ nvim_prog, '-l', '-' }, 'error("whoa")')
+ )
eq(1, eval('v:shell_error'))
end)
it('executes stdin "-"', function()
- assert_l_out('arg0=- args=2 whoa\n',
+ assert_l_out(
+ 'arg0=- args=2 whoa\n',
nil,
{ 'arg1', 'arg 2' },
'-',
- "print(('arg0=%s args=%d %s'):format(_G.arg[0], #_G.arg, 'whoa'))")
- assert_l_out('biiig input: 1000042\n',
+ "print(('arg0=%s args=%d %s'):format(_G.arg[0], #_G.arg, 'whoa'))"
+ )
+ assert_l_out(
+ 'biiig input: 1000042\n',
nil,
nil,
'-',
- ('print("biiig input: "..("%s"):len())'):format(string.rep('x', (1000 * 1000) + 42)))
+ ('print("biiig input: "..("%s"):len())'):format(string.rep('x', (1000 * 1000) + 42))
+ )
eq(0, eval('v:shell_error'))
end)
@@ -169,7 +201,8 @@ describe('startup', function()
it('sets _G.arg', function()
-- nvim -l foo.lua
- assert_l_out([[
+ assert_l_out(
+ [[
bufs:
nvim args: 3
lua args: {
@@ -182,7 +215,8 @@ describe('startup', function()
eq(0, eval('v:shell_error'))
-- nvim -l foo.lua [args]
- assert_l_out([[
+ assert_l_out(
+ [[
bufs:
nvim args: 7
lua args: { "-arg1", "--arg2", "--", "arg3",
@@ -195,20 +229,22 @@ describe('startup', function()
eq(0, eval('v:shell_error'))
-- nvim file1 file2 -l foo.lua -arg1 -- file3 file4
- assert_l_out([[
+ assert_l_out(
+ [[
bufs: file1 file2
nvim args: 10
lua args: { "-arg1", "arg 2", "--", "file3", "file4",
[0] = "test/functional/fixtures/startup.lua"
}
]],
- { 'file1', 'file2', },
+ { 'file1', 'file2' },
{ '-arg1', 'arg 2', '--', 'file3', 'file4' }
)
eq(0, eval('v:shell_error'))
-- nvim -l foo.lua <vim args>
- assert_l_out([[
+ assert_l_out(
+ [[
bufs:
nvim args: 5
lua args: { "-c", "set wrap?",
@@ -239,30 +275,50 @@ describe('startup', function()
end)
it('disables swapfile/shada/config/plugins', function()
- assert_l_out('updatecount=0 shadafile=NONE loadplugins=false scripts=1\n',
+ assert_l_out(
+ 'updatecount=0 shadafile=NONE loadplugins=false scripts=1\n',
nil,
nil,
'-',
[[print(('updatecount=%d shadafile=%s loadplugins=%s scripts=%d'):format(
- vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]])
+ vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]]
+ )
end)
end)
it('--cmd/-c/+ do not truncate long Lua print() message with --headless', function()
- local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
- '--cmd', 'lua print(("A"):rep(1234))',
- '-c', 'lua print(("B"):rep(1234))',
- '+lua print(("C"):rep(1234))',
- '+q' })
+ local out = fn.system({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '--cmd',
+ 'lua print(("A"):rep(1234))',
+ '-c',
+ 'lua print(("B"):rep(1234))',
+ '+lua print(("C"):rep(1234))',
+ '+q',
+ })
eq(('A'):rep(1234) .. '\r\n' .. ('B'):rep(1234) .. '\r\n' .. ('C'):rep(1234), out)
end)
it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function()
-- system() puts a pipe at both ends.
- local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
- '--cmd', nvim_set,
- '-c', [[echo has('ttyin') has('ttyout')]],
- '+q' })
+ local out = fn.system({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '--cmd',
+ nvim_set,
+ '-c',
+ [[echo has('ttyin') has('ttyout')]],
+ '+q',
+ })
eq('0 0', out)
end)
@@ -285,10 +341,21 @@ describe('startup', function()
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
- command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]]
- ..nvim_set..[[\"]]
- ..[[ -c \"echo has('ttyin') has('ttyout')\""]]
- ..[[, shellescape(v:progpath))]])
+ fn.termopen({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ nvim_set,
+ '-c',
+ 'echo has("ttyin") has("ttyout")',
+ }, {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ })
screen:expect([[
^ |
~ |
@@ -306,15 +373,24 @@ describe('startup', function()
os.remove('Xtest_startup_ttyout')
end)
-- Running in :terminal
- command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]]
- ..nvim_set..[[\"]]
- ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]]
- ..[[ -c q | cat -v"]] -- Output to a pipe.
- ..[[, shellescape(v:progpath))]])
+ fn.termopen(
+ (
+ [["%s" -u NONE -i NONE --cmd "%s"]]
+ .. [[ -c "call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')"]]
+ .. [[ -c q | cat -v]]
+ ):format(nvim_prog, nvim_set),
+ {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ }
+ )
retry(nil, 3000, function()
sleep(1)
- eq('1\n0\n', -- stdin is a TTY, stdout is a pipe
- read_file('Xtest_startup_ttyout'))
+ eq(
+ '1\n0\n', -- stdin is a TTY, stdout is a pipe
+ read_file('Xtest_startup_ttyout')
+ )
end)
end)
@@ -327,16 +403,25 @@ describe('startup', function()
os.remove('Xtest_startup_ttyout')
end)
-- Running in :terminal
- command([[exe printf("terminal echo foo | ]] -- Input from a pipe.
- ..[[%s -u NONE -i NONE --cmd \"]]
- ..nvim_set..[[\"]]
- ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]]
- ..[[ -c q -- -"]]
- ..[[, shellescape(v:progpath))]])
+ fn.termopen(
+ (
+ [[echo foo | ]] -- Input from a pipe.
+ .. [["%s" -u NONE -i NONE --cmd "%s"]]
+ .. [[ -c "call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')"]]
+ .. [[ -c q -- -]]
+ ):format(nvim_prog, nvim_set),
+ {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ }
+ )
retry(nil, 3000, function()
sleep(1)
- eq('0\n1\n', -- stdin is a pipe, stdout is a TTY
- read_file('Xtest_startup_ttyout'))
+ eq(
+ '0\n1\n', -- stdin is a pipe, stdout is a TTY
+ read_file('Xtest_startup_ttyout')
+ )
end)
end)
@@ -347,11 +432,18 @@ describe('startup', function()
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
-- Running in :terminal
- command([[exe printf("terminal echo foo | ]] -- Input from a pipe.
- ..[[%s -u NONE -i NONE --cmd \"]]
- ..nvim_set..[[\"]]
- ..[[ -c \"echo has('ttyin') has('ttyout')\""]]
- ..[[, shellescape(v:progpath))]])
+ fn.termopen(
+ (
+ [[echo foo | ]]
+ .. [["%s" -u NONE -i NONE --cmd "%s"]]
+ .. [[ -c "echo has('ttyin') has('ttyout')"]]
+ ):format(nvim_prog, nvim_set),
+ {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ }
+ )
screen:expect([[
^foo |
~ |
@@ -361,28 +453,44 @@ describe('startup', function()
end)
it('input from pipe + file args #7679', function()
- eq('ohyeah\r\n0 0 bufs=3',
- funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless',
- '+.print',
- "+echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')",
- '+qall!',
- '-',
- 'test/functional/fixtures/tty-test.c',
- 'test/functional/fixtures/shell-test.c',
- },
- { 'ohyeah', '' }))
+ eq(
+ 'ohyeah\r\n0 0 bufs=3',
+ fn.system({
+ nvim_prog,
+ '-n',
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '+.print',
+ "+echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')",
+ '+qall!',
+ '-',
+ 'test/functional/fixtures/tty-test.c',
+ 'test/functional/fixtures/shell-test.c',
+ }, { 'ohyeah', '' })
+ )
end)
it('if stdin is empty: selects buffer 2, deletes buffer 1 #8561', function()
- eq('\r\n 2 %a "file1" line 0\r\n 3 "file2" line 0',
- funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless',
- '+ls!',
- '+qall!',
- '-',
- 'file1',
- 'file2',
- },
- { '' }))
+ eq(
+ '\r\n 2 %a "file1" line 0\r\n 3 "file2" line 0',
+ fn.system({
+ nvim_prog,
+ '-n',
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '+ls!',
+ '+qall!',
+ '-',
+ 'file1',
+ 'file2',
+ }, { '' })
+ )
end)
it('stdin with -es/-Es #7679', function()
@@ -392,48 +500,70 @@ describe('startup', function()
--
-- -Es: read stdin as text
--
- eq('partylikeits1999\n',
- funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-Es', '+.print', 'test/functional/fixtures/tty-test.c' },
- { 'partylikeits1999', '' }))
- eq(inputstr,
- funcs.system({nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' },
- input))
+ eq(
+ 'partylikeits1999\n',
+ fn.system({
+ nvim_prog,
+ '-n',
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '-Es',
+ '+.print',
+ 'test/functional/fixtures/tty-test.c',
+ }, { 'partylikeits1999', '' })
+ )
+ eq(inputstr, fn.system({ nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' }, input))
-- with `-u NORC`
- eq('thepartycontinues\n',
- funcs.system({nvim_prog, '-n', '-u', 'NORC', '-Es', '+.print' },
- { 'thepartycontinues', '' }))
+ eq(
+ 'thepartycontinues\n',
+ fn.system({ nvim_prog, '-n', '-u', 'NORC', '-Es', '+.print' }, { 'thepartycontinues', '' })
+ )
-- without `-u`
- eq('thepartycontinues\n',
- funcs.system({nvim_prog, '-n', '-Es', '+.print' },
- { 'thepartycontinues', '' }))
+ eq(
+ 'thepartycontinues\n',
+ fn.system({ nvim_prog, '-n', '-Es', '+.print' }, { 'thepartycontinues', '' })
+ )
--
-- -es: read stdin as ex-commands
--
- eq(' encoding=utf-8\n',
- funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-es', 'test/functional/fixtures/tty-test.c' },
- { 'set encoding', '' }))
- eq('line1\nline2\n',
- funcs.system({nvim_prog, '-i', 'NONE', '-es', '-' },
- input))
+ eq(
+ ' encoding=utf-8\n',
+ fn.system({
+ nvim_prog,
+ '-n',
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '-es',
+ 'test/functional/fixtures/tty-test.c',
+ }, { 'set encoding', '' })
+ )
+ eq('line1\nline2\n', fn.system({ nvim_prog, '-i', 'NONE', '-es', '-' }, input))
-- with `-u NORC`
- eq(' encoding=utf-8\n',
- funcs.system({nvim_prog, '-n', '-u', 'NORC', '-es' },
- { 'set encoding', '' }))
+ eq(
+ ' encoding=utf-8\n',
+ fn.system({ nvim_prog, '-n', '-u', 'NORC', '-es' }, { 'set encoding', '' })
+ )
-- without `-u`
- eq(' encoding=utf-8\n',
- funcs.system({nvim_prog, '-n', '-es' },
- { 'set encoding', '' }))
+ eq(' encoding=utf-8\n', fn.system({ nvim_prog, '-n', '-es' }, { 'set encoding', '' }))
end)
it('-es/-Es disables swapfile, user config #8540', function()
- for _,arg in ipairs({'-es', '-Es'}) do
- local out = funcs.system({nvim_prog, arg,
- '+set swapfile? updatecount? shadafile?',
- "+put =map(getscriptinfo(), {-> v:val.name})", '+%print'})
+ for _, arg in ipairs({ '-es', '-Es' }) do
+ local out = fn.system({
+ nvim_prog,
+ arg,
+ '+set swapfile? updatecount? shadafile?',
+ '+put =map(getscriptinfo(), {-> v:val.name})',
+ '+%print',
+ })
local line1 = string.match(out, '^.-\n')
-- updatecount=0 means swapfile was disabled.
- eq(" swapfile updatecount=0 shadafile=\n", line1)
+ eq(' swapfile updatecount=0 shadafile=\n', line1)
-- Standard plugins were loaded, but not user config.
ok(string.find(out, 'man.lua') ~= nil)
ok(string.find(out, 'init.vim') == nil)
@@ -441,20 +571,39 @@ describe('startup', function()
end)
it('fails on --embed with -es/-Es/-l', function()
- matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
- funcs.system({nvim_prog, '--embed', '-es' }))
- matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
- funcs.system({nvim_prog, '--embed', '-Es' }))
- matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
- funcs.system({nvim_prog, '--embed', '-l', 'foo.lua' }))
+ matches(
+ 'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
+ fn.system({ nvim_prog, '--embed', '-es' })
+ )
+ matches(
+ 'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
+ fn.system({ nvim_prog, '--embed', '-Es' })
+ )
+ matches(
+ 'nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
+ fn.system({ nvim_prog, '--embed', '-l', 'foo.lua' })
+ )
end)
it('ENTER dismisses early message #7967', function()
local screen
screen = Screen.new(60, 6)
screen:attach()
- command([[let g:id = termopen('"]]..nvim_prog..
- [[" -u NONE -i NONE --cmd "set noruler" --cmd "let g:foo = g:bar"')]])
+ local id = fn.termopen({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--cmd',
+ 'set noruler',
+ '--cmd',
+ 'let g:foo = g:bar',
+ }, {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ })
screen:expect([[
^ |
|
@@ -463,14 +612,12 @@ describe('startup', function()
Press ENTER or type command to continue |
|
]])
- command([[call chansend(g:id, "\n")]])
+ fn.chansend(id, '\n')
screen:expect([[
^ |
- ~ |
- ~ |
+ ~ |*2
[No Name] |
- |
- |
+ |*2
]])
end)
@@ -505,19 +652,32 @@ describe('startup', function()
expected,
-- FIXME(codehex): We should really set a timeout for the system function.
-- If this test fails, there will be a waiting input state.
- funcs.system({nvim_prog, '-u', 'NONE', '-c',
+ fn.system({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-c',
'for i in range(1, 100) | echo i | endfor | quit',
- '--headless'
+ '--headless',
})
)
end)
- it("get command line arguments from v:argv", function()
- local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
- '--cmd', nvim_set,
- '-c', [[echo v:argv[-1:] len(v:argv) > 1]],
- '+q' })
- eq('[\'+q\'] 1', out)
+ it('get command line arguments from v:argv', function()
+ local out = fn.system({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '--cmd',
+ nvim_set,
+ '-c',
+ [[echo v:argv[-1:] len(v:argv) > 1]],
+ '+q',
+ })
+ eq("['+q'] 1", out)
end)
end)
@@ -549,20 +709,20 @@ describe('startup', function()
clear('-e')
screen:attach()
-- Verify we set the proper mode both before and after :vi.
- feed("put =mode(1)<CR>vi<CR>:put =mode(1)<CR>")
+ feed('put =mode(1)<CR>vi<CR>:put =mode(1)<CR>')
screen:expect([[
cv |
^n |
:put =mode(1) |
]])
- eq('cv\n',
- funcs.system({nvim_prog, '-n', '-es' },
- { 'put =mode(1)', 'print', '' }))
+ eq('cv\n', fn.system({ nvim_prog, '-n', '-es' }, { 'put =mode(1)', 'print', '' }))
end)
it('-d does not diff non-arglist windows #13720 #21289', function()
- write_file('Xdiff.vim', [[
+ write_file(
+ 'Xdiff.vim',
+ [[
let bufnr = nvim_create_buf(0, 1)
let config = {
\ 'relative': 'editor',
@@ -572,78 +732,92 @@ describe('startup', function()
\ 'row': 3,
\ 'col': 3
\ }
- autocmd WinEnter * call nvim_open_win(bufnr, v:false, config)]])
+ autocmd WinEnter * call nvim_open_win(bufnr, v:false, config)]]
+ )
finally(function()
os.remove('Xdiff.vim')
end)
- clear{args={'-u', 'Xdiff.vim', '-d', 'Xdiff.vim', 'Xdiff.vim'}}
- eq(true, meths.get_option_value('diff', {win = funcs.win_getid(1)}))
- eq(true, meths.get_option_value('diff', {win = funcs.win_getid(2)}))
- local float_win = funcs.win_getid(3)
- eq('editor', meths.win_get_config(float_win).relative)
- eq(false, meths.get_option_value('diff', {win = float_win}))
+ clear { args = { '-u', 'Xdiff.vim', '-d', 'Xdiff.vim', 'Xdiff.vim' } }
+ eq(true, api.nvim_get_option_value('diff', { win = fn.win_getid(1) }))
+ eq(true, api.nvim_get_option_value('diff', { win = fn.win_getid(2) }))
+ local float_win = fn.win_getid(3)
+ eq('editor', api.nvim_win_get_config(float_win).relative)
+ eq(false, api.nvim_get_option_value('diff', { win = float_win }))
end)
it('does not crash if --embed is given twice', function()
- clear{args={'--embed'}}
+ clear { args = { '--embed' } }
assert_alive()
end)
it('does not crash when expanding cdpath during early_init', function()
- clear{env={CDPATH='~doesnotexist'}}
+ clear { env = { CDPATH = '~doesnotexist' } }
assert_alive()
eq(',~doesnotexist', eval('&cdpath'))
end)
it("sets 'shortmess' when loading other tabs", function()
- clear({args={'-p', 'a', 'b', 'c'}})
+ clear({ args = { '-p', 'a', 'b', 'c' } })
local screen = Screen.new(25, 4)
screen:attach()
- screen:expect({grid=[[
+ screen:expect({
+ grid = [[
{1: a }{2: b c }{3: }{2:X}|
^ |
{4:~ }|
|
]],
- attr_ids={
- [1] = {bold = true},
- [2] = {background = Screen.colors.LightGrey, underline = true},
- [3] = {reverse = true},
- [4] = {bold = true, foreground = Screen.colors.Blue1},
- }})
+ attr_ids = {
+ [1] = { bold = true },
+ [2] = { background = Screen.colors.LightGrey, underline = true },
+ [3] = { reverse = true },
+ [4] = { bold = true, foreground = Screen.colors.Blue1 },
+ },
+ })
end)
end)
describe('startup', function()
local function pack_clear(cmd)
-- add packages after config dir in rtp but before config/after
- clear{args={'--cmd', 'set packpath=test/functional/fixtures', '--cmd', 'let paths=split(&rtp, ",")', '--cmd', 'let &rtp = paths[0]..",test/functional/fixtures,test/functional/fixtures/middle,"..join(paths[1:],",")', '--cmd', cmd}, env={XDG_CONFIG_HOME='test/functional/fixtures/'},
- args_rm={'runtimepath'},
+ clear {
+ args = {
+ '--cmd',
+ 'set packpath=test/functional/fixtures',
+ '--cmd',
+ 'let paths=split(&rtp, ",")',
+ '--cmd',
+ 'let &rtp = paths[0]..",test/functional/fixtures,test/functional/fixtures/middle,"..join(paths[1:],",")',
+ '--cmd',
+ cmd,
+ },
+ env = { XDG_CONFIG_HOME = 'test/functional/fixtures/' },
+ args_rm = { 'runtimepath' },
}
end
- it("handles &packpath during startup", function()
+ it('handles &packpath during startup', function()
pack_clear [[
let g:x = bar#test()
let g:y = leftpad#pad("heyya")
]]
eq(-3, eval 'g:x')
- eq(" heyya", eval 'g:y')
+ eq(' heyya', eval 'g:y')
pack_clear [[ lua _G.y = require'bar'.doit() _G.z = require'leftpad''howdy' ]]
- eq({9003, '\thowdy'}, exec_lua [[ return { _G.y, _G.z } ]])
+ eq({ 9003, '\thowdy' }, exec_lua [[ return { _G.y, _G.z } ]])
end)
- it("handles require from &packpath in an async handler", function()
- -- NO! you cannot just speed things up by calling async functions during startup!
- -- It doesn't make anything actually faster! NOOOO!
+ it('handles require from &packpath in an async handler', function()
+ -- NO! you cannot just speed things up by calling async functions during startup!
+ -- It doesn't make anything actually faster! NOOOO!
pack_clear [[ lua require'async_leftpad'('brrrr', 'async_res') ]]
-- haha, async leftpad go brrrrr
eq('\tbrrrr', exec_lua [[ return _G.async_res ]])
end)
- it("handles :packadd during startup", function()
+ it('handles :packadd during startup', function()
-- control group: opt/bonus is not available by default
pack_clear [[
try
@@ -655,8 +829,10 @@ describe('startup', function()
eq('Vim(let):E117: Unknown function: bonus#secret', eval 'g:err')
pack_clear [[ lua _G.test = {pcall(function() require'bonus'.launch() end)} ]]
- eq({false, [[[string ":lua"]:1: module 'bonus' not found:]]},
- exec_lua [[ _G.test[2] = string.gsub(_G.test[2], '[\r\n].*', '') return _G.test ]])
+ eq(
+ { false, [[[string ":lua"]:1: module 'bonus' not found:]] },
+ exec_lua [[ _G.test[2] = string.gsub(_G.test[2], '[\r\n].*', '') return _G.test ]]
+ )
-- ok, time to launch the nukes:
pack_clear [[ packadd! bonus | let g:x = bonus#secret() ]]
@@ -666,46 +842,77 @@ describe('startup', function()
eq('CPE 1704 TKS', exec_lua [[ return _G.y ]])
end)
- it("handles the correct order with start packages and after/", function()
+ it('handles the correct order with start packages and after/', function()
pack_clear [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]]
- eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq(
+ { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
+ exec_lua [[ return _G.test_loadorder ]]
+ )
end)
- it("handles the correct order with start packages and after/ after startup", function()
+ it('handles the correct order with start packages and after/ after startup', function()
pack_clear [[ lua _G.test_loadorder = {} ]]
command [[ runtime! filen.lua ]]
- eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq(
+ { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
+ exec_lua [[ return _G.test_loadorder ]]
+ )
end)
- it("handles the correct order with globpath(&rtp, ...)", function()
+ it('handles the correct order with globpath(&rtp, ...)', function()
pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]]
command [[
for x in globpath(&rtp, "filen.lua",1,1)
call v:lua.dofile(x)
endfor
]]
- eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq(
+ { 'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
+ exec_lua [[ return _G.test_loadorder ]]
+ )
- local rtp = meths.get_option_value('rtp', {})
- ok(startswith(rtp, 'test/functional/fixtures/nvim,test/functional/fixtures/pack/*/start/*,test/functional/fixtures/start/*,test/functional/fixtures,test/functional/fixtures/middle,'),
- 'startswith(…)', 'rtp='..rtp)
+ local rtp = api.nvim_get_option_value('rtp', {})
+ ok(
+ startswith(
+ rtp,
+ 'test/functional/fixtures/nvim,test/functional/fixtures/pack/*/start/*,test/functional/fixtures/start/*,test/functional/fixtures,test/functional/fixtures/middle,'
+ ),
+ 'startswith(…)',
+ 'rtp=' .. rtp
+ )
end)
- it("handles the correct order with opt packages and after/", function()
+ it('handles the correct order with opt packages and after/', function()
pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! superspecial\nruntime! filen.lua" ]]
- eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'FANCY after', 'SuperSpecial after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq({
+ 'ordinary',
+ 'SuperSpecial',
+ 'FANCY',
+ 'mittel',
+ 'FANCY after',
+ 'SuperSpecial after',
+ 'ordinary after',
+ }, exec_lua [[ return _G.test_loadorder ]])
end)
- it("handles the correct order with opt packages and after/ after startup", function()
+ it('handles the correct order with opt packages and after/ after startup', function()
pack_clear [[ lua _G.test_loadorder = {} ]]
command [[
packadd! superspecial
runtime! filen.lua
]]
- eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'FANCY after', 'SuperSpecial after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq({
+ 'ordinary',
+ 'SuperSpecial',
+ 'FANCY',
+ 'mittel',
+ 'FANCY after',
+ 'SuperSpecial after',
+ 'ordinary after',
+ }, exec_lua [[ return _G.test_loadorder ]])
end)
- it("handles the correct order with opt packages and globpath(&rtp, ...)", function()
+ it('handles the correct order with opt packages and globpath(&rtp, ...)', function()
pack_clear [[ set loadplugins | lua _G.test_loadorder = {} ]]
command [[
packadd! superspecial
@@ -713,18 +920,40 @@ describe('startup', function()
call v:lua.dofile(x)
endfor
]]
- eq({'ordinary', 'SuperSpecial', 'FANCY', 'mittel', 'SuperSpecial after', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ eq({
+ 'ordinary',
+ 'SuperSpecial',
+ 'FANCY',
+ 'mittel',
+ 'SuperSpecial after',
+ 'FANCY after',
+ 'ordinary after',
+ }, exec_lua [[ return _G.test_loadorder ]])
end)
- it("handles the correct order with a package that changes packpath", function()
+ it('handles the correct order with a package that changes packpath', function()
pack_clear [[ lua _G.test_loadorder = {} vim.cmd "packadd! funky\nruntime! filen.lua" ]]
- eq({'ordinary', 'funky!', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
- eq({'ordinary', 'funky!', 'mittel', 'ordinary after'}, exec_lua [[ return _G.nested_order ]])
+ eq(
+ { 'ordinary', 'funky!', 'FANCY', 'mittel', 'FANCY after', 'ordinary after' },
+ exec_lua [[ return _G.test_loadorder ]]
+ )
+ eq({ 'ordinary', 'funky!', 'mittel', 'ordinary after' }, exec_lua [[ return _G.nested_order ]])
end)
- it("handles the correct order when prepending packpath", function()
- clear{args={'--cmd', 'set packpath^=test/functional/fixtures', '--cmd', [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]]}, env={XDG_CONFIG_HOME='test/functional/fixtures/'}}
- eq({'ordinary', 'FANCY', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
+ it('handles the correct order when prepending packpath', function()
+ clear {
+ args = {
+ '--cmd',
+ 'set packpath^=test/functional/fixtures',
+ '--cmd',
+ [[ lua _G.test_loadorder = {} vim.cmd "runtime! filen.lua" ]],
+ },
+ env = { XDG_CONFIG_HOME = 'test/functional/fixtures/' },
+ }
+ eq(
+ { 'ordinary', 'FANCY', 'FANCY after', 'ordinary after' },
+ exec_lua [[ return _G.test_loadorder ]]
+ )
end)
it('window widths are correct when modelines set &columns with tabpages', function()
@@ -734,10 +963,10 @@ describe('startup', function()
os.remove('Xtab1.noft')
os.remove('Xtab2.noft')
end)
- clear({args = {'-p', 'Xtab1.noft', 'Xtab2.noft'}})
- eq(81, meths.win_get_width(0))
+ clear({ args = { '-p', 'Xtab1.noft', 'Xtab2.noft' } })
+ eq(81, api.nvim_win_get_width(0))
command('tabnext')
- eq(81, meths.win_get_width(0))
+ eq(81, api.nvim_win_get_width(0))
end)
end)
@@ -754,16 +983,22 @@ describe('sysinit', function()
mkdir(xdgdir)
mkdir(xdgdir .. pathsep .. 'nvim')
- write_file(table.concat({xdgdir, 'nvim', 'sysinit.vim'}, pathsep), [[
+ write_file(
+ table.concat({ xdgdir, 'nvim', 'sysinit.vim' }, pathsep),
+ [[
let g:loaded = get(g:, "loaded", 0) + 1
let g:xdg = 1
- ]])
+ ]]
+ )
mkdir(vimdir)
- write_file(table.concat({vimdir, 'sysinit.vim'}, pathsep), [[
+ write_file(
+ table.concat({ vimdir, 'sysinit.vim' }, pathsep),
+ [[
let g:loaded = get(g:, "loaded", 0) + 1
let g:vim = 1
- ]])
+ ]]
+ )
mkdir(xhome)
end)
@@ -774,23 +1009,27 @@ describe('sysinit', function()
end)
it('prefers XDG_CONFIG_DIRS over VIM', function()
- clear{args={'--cmd', 'set nomore undodir=. directory=. belloff='},
- args_rm={'-u', '--cmd'},
- env={ HOME=xhome,
- XDG_CONFIG_DIRS=xdgdir,
- VIM=vimdir }}
- eq('loaded 1 xdg 1 vim 0',
- eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
+ clear {
+ args = { '--cmd', 'set nomore undodir=. directory=. belloff=' },
+ args_rm = { '-u', '--cmd' },
+ env = { HOME = xhome, XDG_CONFIG_DIRS = xdgdir, VIM = vimdir },
+ }
+ eq(
+ 'loaded 1 xdg 1 vim 0',
+ eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')
+ )
end)
it('uses VIM if XDG_CONFIG_DIRS unset', function()
- clear{args={'--cmd', 'set nomore undodir=. directory=. belloff='},
- args_rm={'-u', '--cmd'},
- env={ HOME=xhome,
- XDG_CONFIG_DIRS='',
- VIM=vimdir }}
- eq('loaded 1 xdg 0 vim 1',
- eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
+ clear {
+ args = { '--cmd', 'set nomore undodir=. directory=. belloff=' },
+ args_rm = { '-u', '--cmd' },
+ env = { HOME = xhome, XDG_CONFIG_DIRS = '', VIM = vimdir },
+ }
+ eq(
+ 'loaded 1 xdg 0 vim 1',
+ eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))')
+ )
end)
end)
@@ -799,8 +1038,8 @@ describe('user config init', function()
local pathsep = helpers.get_pathsep()
local xconfig = xhome .. pathsep .. 'Xconfig'
local xdata = xhome .. pathsep .. 'Xdata'
- local init_lua_path = table.concat({xconfig, 'nvim', 'init.lua'}, pathsep)
- local xenv = { XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata }
+ local init_lua_path = table.concat({ xconfig, 'nvim', 'init.lua' }, pathsep)
+ local xenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata }
before_each(function()
rmdir(xhome)
@@ -808,9 +1047,12 @@ describe('user config init', function()
mkdir_p(xconfig .. pathsep .. 'nvim')
mkdir_p(xdata)
- write_file(init_lua_path, [[
+ write_file(
+ init_lua_path,
+ [[
vim.g.lua_rc = 1
- ]])
+ ]]
+ )
end)
after_each(function()
@@ -818,36 +1060,51 @@ describe('user config init', function()
end)
it('loads init.lua from XDG config home by default', function()
- clear{ args_rm={'-u'}, env=xenv }
+ clear { args_rm = { '-u' }, env = xenv }
eq(1, eval('g:lua_rc'))
- eq(funcs.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC'))
+ eq(fn.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC'))
end)
describe('loads existing', function()
local exrc_path = '.exrc'
local xstate = 'Xstate'
- local xstateenv = { XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata, XDG_STATE_HOME=xstate }
+ local xstateenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata, XDG_STATE_HOME = xstate }
local function setup_exrc_file(filename)
exrc_path = filename
- if string.find(exrc_path, "%.lua$") then
- write_file(exrc_path, string.format([[
+ if string.find(exrc_path, '%.lua$') then
+ write_file(
+ exrc_path,
+ string.format(
+ [[
vim.g.exrc_file = "%s"
- ]], exrc_path))
+ ]],
+ exrc_path
+ )
+ )
else
- write_file(exrc_path, string.format([[
+ write_file(
+ exrc_path,
+ string.format(
+ [[
let g:exrc_file = "%s"
- ]], exrc_path))
+ ]],
+ exrc_path
+ )
+ )
end
end
before_each(function()
- write_file(init_lua_path, [[
+ write_file(
+ init_lua_path,
+ [[
vim.o.exrc = true
vim.g.exrc_file = '---'
- ]])
+ ]]
+ )
mkdir_p(xstate .. pathsep .. (is_os('win') and 'nvim-data' or 'nvim'))
end)
@@ -860,39 +1117,41 @@ describe('user config init', function()
it(filename .. ' in cwd', function()
setup_exrc_file(filename)
- clear{ args_rm={'-u'}, env=xstateenv }
+ clear { args_rm = { '-u' }, env = xstateenv }
-- The 'exrc' file is not trusted, and the prompt is skipped because there is no UI.
eq('---', eval('g:exrc_file'))
local screen = Screen.new(50, 8)
screen:attach()
- funcs.termopen({nvim_prog})
+ fn.termopen({ nvim_prog }, {
+ env = {
+ VIMRUNTIME = os.getenv('VIMRUNTIME'),
+ },
+ })
screen:expect({ any = pesc('[i]gnore, (v)iew, (d)eny, (a)llow:') })
-- `i` to enter Terminal mode, `a` to allow
feed('ia')
screen:expect([[
|
- ~ |
- ~ |
- ~ |
- ~ |
+ ~ |*4
[No Name] 0,0-1 All|
|
-- TERMINAL -- |
]])
feed(':echo g:exrc_file<CR>')
- screen:expect(string.format([[
+ screen:expect(string.format(
+ [[
|
- ~ |
- ~ |
- ~ |
- ~ |
+ ~ |*4
[No Name] 0,0-1 All|
%s%s|
-- TERMINAL -- |
- ]], filename, string.rep(' ', 50 - #filename)))
+ ]],
+ filename,
+ string.rep(' ', 50 - #filename)
+ ))
- clear{ args_rm={'-u'}, env=xstateenv }
+ clear { args_rm = { '-u' }, env = xstateenv }
-- The 'exrc' file is now trusted.
eq(filename, eval('g:exrc_file'))
end)
@@ -900,15 +1159,18 @@ describe('user config init', function()
end)
describe('with explicitly provided config', function()
- local custom_lua_path = table.concat({xhome, 'custom.lua'}, pathsep)
+ local custom_lua_path = table.concat({ xhome, 'custom.lua' }, pathsep)
before_each(function()
- write_file(custom_lua_path, [[
+ write_file(
+ custom_lua_path,
+ [[
vim.g.custom_lua_rc = 1
- ]])
+ ]]
+ )
end)
it('loads custom lua config and does not set $MYVIMRC', function()
- clear{ args={'-u', custom_lua_path }, env=xenv }
+ clear { args = { '-u', custom_lua_path }, env = xenv }
eq(1, eval('g:custom_lua_rc'))
eq('', eval('$MYVIMRC'))
end)
@@ -916,14 +1178,17 @@ describe('user config init', function()
describe('VIMRC also exists', function()
before_each(function()
- write_file(table.concat({xconfig, 'nvim', 'init.vim'}, pathsep), [[
+ write_file(
+ table.concat({ xconfig, 'nvim', 'init.vim' }, pathsep),
+ [[
let g:vim_rc = 1
- ]])
+ ]]
+ )
end)
it('loads default lua config, but shows an error', function()
- clear{ args_rm={'-u'}, env=xenv }
- feed('<cr><c-c>') -- Dismiss "Conflicting config …" message.
+ clear { args_rm = { '-u' }, env = xenv }
+ feed('<cr><c-c>') -- Dismiss "Conflicting config …" message.
eq(1, eval('g:lua_rc'))
matches('^E5422: Conflicting configs', exec_capture('messages'))
end)
@@ -935,7 +1200,7 @@ describe('runtime:', function()
local pathsep = helpers.get_pathsep()
local xconfig = xhome .. pathsep .. 'Xconfig'
local xdata = xhome .. pathsep .. 'Xdata'
- local xenv = { XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata }
+ local xenv = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata }
setup(function()
rmdir(xhome)
@@ -948,23 +1213,24 @@ describe('runtime:', function()
end)
it('loads plugin/*.lua from XDG config home', function()
- local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep)
- local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep)
+ local plugin_folder_path = table.concat({ xconfig, 'nvim', 'plugin' }, pathsep)
+ local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep)
mkdir_p(plugin_folder_path)
finally(function()
rmdir(plugin_folder_path)
end)
write_file(plugin_file_path, [[ vim.g.lua_plugin = 1 ]])
- clear{ args_rm={'-u'}, env=xenv }
+ clear { args_rm = { '-u' }, env = xenv }
eq(1, eval('g:lua_plugin'))
end)
it('loads plugin/*.lua from start packages', function()
- local plugin_path = table.concat({xconfig, 'nvim', 'pack', 'category', 'start', 'test_plugin'}, pathsep)
- local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep)
- local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep)
+ local plugin_path =
+ table.concat({ xconfig, 'nvim', 'pack', 'category', 'start', 'test_plugin' }, pathsep)
+ local plugin_folder_path = table.concat({ plugin_path, 'plugin' }, pathsep)
+ local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep)
local profiler_file = 'test_startuptime.log'
mkdir_p(plugin_folder_path)
finally(function()
@@ -974,12 +1240,16 @@ describe('runtime:', function()
write_file(plugin_file_path, [[vim.g.lua_plugin = 2]])
- clear{ args_rm={'-u'}, args={'--startuptime', profiler_file}, env=xenv }
+ clear { args_rm = { '-u' }, args = { '--startuptime', profiler_file }, env = xenv }
eq(2, eval('g:lua_plugin'))
-- Check if plugin_file_path is listed in getscriptinfo()
- local scripts = tbl_map(function(s) return s.name end, funcs.getscriptinfo())
- ok(#tbl_filter(function(s) return endswith(s, plugin_file_path) end, scripts) > 0)
+ local scripts = tbl_map(function(s)
+ return s.name
+ end, fn.getscriptinfo())
+ ok(#tbl_filter(function(s)
+ return endswith(s, plugin_file_path)
+ end, scripts) > 0)
-- Check if plugin_file_path is listed in startup profile
local profile_reader = io.open(profiler_file, 'r')
@@ -989,12 +1259,13 @@ describe('runtime:', function()
end)
it('loads plugin/*.lua from site packages', function()
- local nvimdata = is_os('win') and "nvim-data" or "nvim"
- local plugin_path = table.concat({xdata, nvimdata, 'site', 'pack', 'xa', 'start', 'yb'}, pathsep)
- local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep)
- local plugin_after_path = table.concat({plugin_path, 'after', 'plugin'}, pathsep)
- local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep)
- local plugin_after_file_path = table.concat({plugin_after_path, 'helloo.lua'}, pathsep)
+ local nvimdata = is_os('win') and 'nvim-data' or 'nvim'
+ local plugin_path =
+ table.concat({ xdata, nvimdata, 'site', 'pack', 'xa', 'start', 'yb' }, pathsep)
+ local plugin_folder_path = table.concat({ plugin_path, 'plugin' }, pathsep)
+ local plugin_after_path = table.concat({ plugin_path, 'after', 'plugin' }, pathsep)
+ local plugin_file_path = table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep)
+ local plugin_after_file_path = table.concat({ plugin_after_path, 'helloo.lua' }, pathsep)
mkdir_p(plugin_folder_path)
mkdir_p(plugin_after_path)
finally(function()
@@ -1004,49 +1275,64 @@ describe('runtime:', function()
write_file(plugin_file_path, [[table.insert(_G.lista, "unos")]])
write_file(plugin_after_file_path, [[table.insert(_G.lista, "dos")]])
- clear{ args_rm={'-u'}, args={'--cmd', 'lua _G.lista = {}'}, env=xenv }
+ clear { args_rm = { '-u' }, args = { '--cmd', 'lua _G.lista = {}' }, env = xenv }
- eq({'unos', 'dos'}, exec_lua "return _G.lista")
+ eq({ 'unos', 'dos' }, exec_lua 'return _G.lista')
end)
it('no crash setting &rtp in plugins with :packloadall called before #18315', function()
- local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep)
+ local plugin_folder_path = table.concat({ xconfig, 'nvim', 'plugin' }, pathsep)
mkdir_p(plugin_folder_path)
finally(function()
rmdir(plugin_folder_path)
end)
- write_file(table.concat({plugin_folder_path, 'plugin.vim'}, pathsep), [[
+ write_file(
+ table.concat({ plugin_folder_path, 'plugin.vim' }, pathsep),
+ [[
let &runtimepath = &runtimepath
let g:vim_plugin = 1
- ]])
- write_file(table.concat({plugin_folder_path, 'plugin.lua'}, pathsep), [[
+ ]]
+ )
+ write_file(
+ table.concat({ plugin_folder_path, 'plugin.lua' }, pathsep),
+ [[
vim.o.runtimepath = vim.o.runtimepath
vim.g.lua_plugin = 1
- ]])
+ ]]
+ )
- clear{ args_rm={'-u'}, args = {'--cmd', 'packloadall'}, env=xenv }
+ clear { args_rm = { '-u' }, args = { '--cmd', 'packloadall' }, env = xenv }
eq(1, eval('g:vim_plugin'))
eq(1, eval('g:lua_plugin'))
end)
it("loads ftdetect/*.{vim,lua} respecting 'rtp' order", function()
- local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep)
- local after_ftdetect_folder = table.concat({xconfig, 'nvim', 'after', 'ftdetect'}, pathsep)
+ local ftdetect_folder = table.concat({ xconfig, 'nvim', 'ftdetect' }, pathsep)
+ local after_ftdetect_folder = table.concat({ xconfig, 'nvim', 'after', 'ftdetect' }, pathsep)
mkdir_p(ftdetect_folder)
mkdir_p(after_ftdetect_folder)
finally(function()
rmdir(ftdetect_folder)
rmdir(after_ftdetect_folder)
end)
- -- A .lua file is loaded after a .vim file if they only differ in extension.
- -- All files in after/ftdetect/ are loaded after all files in ftdetect/.
- write_file(table.concat({ftdetect_folder, 'new-ft.vim'}, pathsep), [[let g:seq ..= 'A']])
- write_file(table.concat({ftdetect_folder, 'new-ft.lua'}, pathsep), [[vim.g.seq = vim.g.seq .. 'B']])
- write_file(table.concat({after_ftdetect_folder, 'new-ft.vim'}, pathsep), [[let g:seq ..= 'a']])
- write_file(table.concat({after_ftdetect_folder, 'new-ft.lua'}, pathsep), [[vim.g.seq = vim.g.seq .. 'b']])
- clear{ args_rm={'-u'}, args = {'--cmd', 'let g:seq = ""'}, env=xenv }
+ -- A .lua file is loaded after a .vim file if they only differ in extension.
+ -- All files in after/ftdetect/ are loaded after all files in ftdetect/.
+ write_file(table.concat({ ftdetect_folder, 'new-ft.vim' }, pathsep), [[let g:seq ..= 'A']])
+ write_file(
+ table.concat({ ftdetect_folder, 'new-ft.lua' }, pathsep),
+ [[vim.g.seq = vim.g.seq .. 'B']]
+ )
+ write_file(
+ table.concat({ after_ftdetect_folder, 'new-ft.vim' }, pathsep),
+ [[let g:seq ..= 'a']]
+ )
+ write_file(
+ table.concat({ after_ftdetect_folder, 'new-ft.lua' }, pathsep),
+ [[vim.g.seq = vim.g.seq .. 'b']]
+ )
+ clear { args_rm = { '-u' }, args = { '--cmd', 'let g:seq = ""' }, env = xenv }
eq('ABab', eval('g:seq'))
end)
end)
@@ -1054,15 +1340,18 @@ end)
describe('user session', function()
local xhome = 'Xhome'
local pathsep = helpers.get_pathsep()
- local session_file = table.concat({xhome, 'session.lua'}, pathsep)
+ local session_file = table.concat({ xhome, 'session.lua' }, pathsep)
before_each(function()
rmdir(xhome)
mkdir(xhome)
- write_file(session_file, [[
+ write_file(
+ session_file,
+ [[
vim.g.lua_session = 1
- ]])
+ ]]
+ )
end)
after_each(function()
@@ -1070,7 +1359,45 @@ describe('user session', function()
end)
it('loads session from the provided lua file', function()
- clear{ args={'-S', session_file }, env={ HOME=xhome }}
+ clear { args = { '-S', session_file }, env = { HOME = xhome } }
eq(1, eval('g:lua_session'))
end)
end)
+
+describe('inccommand on ex mode', function()
+ it('should not preview', function()
+ clear()
+ local screen
+ screen = Screen.new(60, 10)
+ screen:attach()
+ local id = fn.termopen({
+ nvim_prog,
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '-c',
+ 'set termguicolors background=dark',
+ '-E',
+ 'test/README.md',
+ }, {
+ env = { VIMRUNTIME = os.getenv('VIMRUNTIME') },
+ })
+ fn.chansend(id, '%s/N')
+ screen:expect {
+ grid = [[
+ {1:^ }|
+ {1: }|*6
+ {1:Entering Ex mode. Type "visual" to go to Normal mode. }|
+ {1::%s/N }|
+ |
+ ]],
+ attr_ids = {
+ [1] = {
+ background = Screen.colors.NvimDarkGrey2,
+ foreground = Screen.colors.NvimLightGrey2,
+ },
+ },
+ }
+ end)
+end)