aboutsummaryrefslogtreecommitdiff
path: root/test/functional/vimscript
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /test/functional/vimscript
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-usermarks.tar.gz
rneovim-usermarks.tar.bz2
rneovim-usermarks.zip
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'test/functional/vimscript')
-rw-r--r--test/functional/vimscript/api_functions_spec.lua3
-rw-r--r--test/functional/vimscript/container_functions_spec.lua2
-rw-r--r--test/functional/vimscript/ctx_functions_spec.lua12
-rw-r--r--test/functional/vimscript/eval_spec.lua80
-rw-r--r--test/functional/vimscript/executable_spec.lua28
-rw-r--r--test/functional/vimscript/execute_spec.lua4
-rw-r--r--test/functional/vimscript/exepath_spec.lua19
-rw-r--r--test/functional/vimscript/fnamemodify_spec.lua6
-rw-r--r--test/functional/vimscript/functions_spec.lua4
-rw-r--r--test/functional/vimscript/has_spec.lua4
-rw-r--r--test/functional/vimscript/hostname_spec.lua6
-rw-r--r--test/functional/vimscript/input_spec.lua77
-rw-r--r--test/functional/vimscript/json_functions_spec.lua2
-rw-r--r--test/functional/vimscript/map_functions_spec.lua69
-rw-r--r--test/functional/vimscript/msgpack_functions_spec.lua4
-rw-r--r--test/functional/vimscript/null_spec.lua2
-rw-r--r--test/functional/vimscript/server_spec.lua30
-rw-r--r--test/functional/vimscript/system_spec.lua65
-rw-r--r--test/functional/vimscript/timer_spec.lua12
-rw-r--r--test/functional/vimscript/writefile_spec.lua20
20 files changed, 366 insertions, 83 deletions
diff --git a/test/functional/vimscript/api_functions_spec.lua b/test/functional/vimscript/api_functions_spec.lua
index 8ca245f61a..c032ac3030 100644
--- a/test/functional/vimscript/api_functions_spec.lua
+++ b/test/functional/vimscript/api_functions_spec.lua
@@ -5,6 +5,7 @@ local neq, eq, command = helpers.neq, helpers.eq, helpers.command
local clear, curbufmeths = helpers.clear, helpers.curbufmeths
local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval
local insert, pcall_err = helpers.insert, helpers.pcall_err
+local matches = helpers.matches
local meths = helpers.meths
describe('eval-API', function()
@@ -49,7 +50,7 @@ describe('eval-API', function()
it('cannot change texts if textlocked', function()
command("autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])")
- eq('Vim(call):E5555: API call: E565: Not allowed to change text or change window',
+ matches('Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$',
pcall_err(command, "normal! yy"))
end)
diff --git a/test/functional/vimscript/container_functions_spec.lua b/test/functional/vimscript/container_functions_spec.lua
index 04a3248c49..5bef3fce05 100644
--- a/test/functional/vimscript/container_functions_spec.lua
+++ b/test/functional/vimscript/container_functions_spec.lua
@@ -8,7 +8,7 @@ local clear = helpers.clear
before_each(clear)
describe('extend()', function()
- it('suceeds to extend list with itself', function()
+ it('succeeds to extend list with itself', function()
meths.set_var('l', {1, {}})
eq({1, {}, 1, {}}, eval('extend(l, l)'))
eq({1, {}, 1, {}}, meths.get_var('l'))
diff --git a/test/functional/vimscript/ctx_functions_spec.lua b/test/functional/vimscript/ctx_functions_spec.lua
index d92a81c55b..5ee84a6d13 100644
--- a/test/functional/vimscript/ctx_functions_spec.lua
+++ b/test/functional/vimscript/ctx_functions_spec.lua
@@ -173,9 +173,9 @@ describe('context functions', function()
call('SaveSFuncs')
call('DeleteSFuncs')
- eq('Vim(call):E117: Unknown function: s:greet',
+ eq('function Greet, line 1: Vim(call):E117: Unknown function: s:greet',
pcall_err(command, [[call Greet('World')]]))
- eq('Vim(call):E117: Unknown function: s:greet_all',
+ eq('function GreetAll, line 1: Vim(call):E117: Unknown function: s:greet_all',
pcall_err(command, [[call GreetAll('World', 'One', 'Two', 'Three')]]))
call('RestoreFuncs')
@@ -287,9 +287,11 @@ describe('context functions', function()
local with_jumps = {
['jumps'] = eval(([[
- filter(map(getjumplist()[0], 'filter(
- { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
- { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
+ filter(map(add(
+ getjumplist()[0], { 'bufnr': bufnr('%'), 'lnum': getcurpos()[1] }),
+ 'filter(
+ { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
+ { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
]]):gsub('\n', ''))
}
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua
index 0c2ca8de78..a8a901042b 100644
--- a/test/functional/vimscript/eval_spec.lua
+++ b/test/functional/vimscript/eval_spec.lua
@@ -10,16 +10,22 @@
-- test/functional/vimscript/functions_spec.lua
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local lfs = require('lfs')
local clear = helpers.clear
local eq = helpers.eq
local exc_exec = helpers.exc_exec
+local exec_lua = helpers.exec_lua
+local exec_capture = helpers.exec_capture
local eval = helpers.eval
local command = helpers.command
local write_file = helpers.write_file
local meths = helpers.meths
local sleep = helpers.sleep
+local matches = helpers.matches
+local pcall_err = helpers.pcall_err
+local assert_alive = helpers.assert_alive
local poke_eventloop = helpers.poke_eventloop
local feed = helpers.feed
@@ -65,13 +71,13 @@ describe("backtick expansion", function()
end)
it("with default 'shell'", function()
- if helpers.iswin() then
+ if helpers.is_os('win') then
command(":silent args `dir /b *2`")
else
command(":silent args `echo ***2`")
end
eq({ "file2", }, eval("argv()"))
- if helpers.iswin() then
+ if helpers.is_os('win') then
command(":silent args `dir /s/b *4`")
eq({ "subdir\\file4", }, eval("map(argv(), 'fnamemodify(v:val, \":.\")')"))
else
@@ -144,3 +150,73 @@ describe('List support code', function()
end
end)
end)
+
+describe("uncaught exception", function()
+ before_each(clear)
+ after_each(function()
+ os.remove('throw1.vim')
+ os.remove('throw2.vim')
+ os.remove('throw3.vim')
+ end)
+
+ it('is not forgotten #13490', function()
+ command('autocmd BufWinEnter * throw "i am error"')
+ eq('i am error', exc_exec('try | new | endtry'))
+
+ -- Like Vim, throwing here aborts the processing of the script, but does not stop :runtime!
+ -- from processing the others.
+ -- Only the first thrown exception should be rethrown from the :try below, though.
+ for i = 1, 3 do
+ write_file('throw' .. i .. '.vim', ([[
+ let result ..= '%d'
+ throw 'throw%d'
+ let result ..= 'X'
+ ]]):format(i, i))
+ end
+ command('set runtimepath+=. | let result = ""')
+ eq('throw1', exc_exec('try | runtime! throw*.vim | endtry'))
+ eq('123', eval('result'))
+ end)
+end)
+
+describe('listing functions using :function', function()
+ before_each(clear)
+
+ it('works for lambda functions with <lambda> #20466', function()
+ command('let A = {-> 1}')
+ local num = exec_capture('echo A'):match("function%('<lambda>(%d+)'%)")
+ eq(([[
+ function <lambda>%s(...)
+1 return 1
+ endfunction]]):format(num), exec_capture(('function <lambda>%s'):format(num)))
+ end)
+
+ -- FIXME: If the same function is deleted, the crash still happens. #20790
+ it('does not crash if another function is deleted while listing', function()
+ local screen = Screen.new(80, 24)
+ screen:attach()
+ matches('Vim%(function%):E454: function list was modified', pcall_err(exec_lua, [=[
+ vim.cmd([[
+ func Func1()
+ endfunc
+ func Func2()
+ endfunc
+ func Func3()
+ endfunc
+ ]])
+
+ local ns = vim.api.nvim_create_namespace('test')
+
+ vim.ui_attach(ns, { ext_messages = true }, function(event, _, content)
+ if event == 'msg_show' and content[1][2] == 'function Func1()' then
+ vim.cmd('delfunc Func3')
+ end
+ end)
+
+ vim.cmd('function')
+
+ vim.ui_detach(ns)
+ ]=]))
+ assert_alive()
+ end)
+end)
diff --git a/test/functional/vimscript/executable_spec.lua b/test/functional/vimscript/executable_spec.lua
index b4162b2336..43e4a29e1a 100644
--- a/test/functional/vimscript/executable_spec.lua
+++ b/test/functional/vimscript/executable_spec.lua
@@ -1,15 +1,16 @@
local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, call, iswin, write_file, command =
- helpers.eq, helpers.clear, helpers.call, helpers.iswin, helpers.write_file,
+local eq, clear, call, write_file, command =
+ helpers.eq, helpers.clear, helpers.call, helpers.write_file,
helpers.command
local exc_exec = helpers.exc_exec
local eval = helpers.eval
+local is_os = helpers.is_os
describe('executable()', function()
before_each(clear)
it('returns 1 for commands in $PATH', function()
- local exe = iswin() and 'ping' or 'ls'
+ local exe = is_os('win') and 'ping' or 'ls'
eq(1, call('executable', exe))
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
eq(1, call('executable', 'null'))
@@ -17,7 +18,7 @@ describe('executable()', function()
eq(1, call('executable', 'false'))
end)
- if iswin() then
+ if is_os('win') then
it('exepath respects shellslash', function()
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
eq([[test\functional\fixtures\bin\null.CMD]], call('fnamemodify', call('exepath', 'null'), ':.'))
@@ -34,11 +35,13 @@ describe('executable()', function()
it('fails for invalid values', function()
for _, input in ipairs({'v:null', 'v:true', 'v:false', '{}', '[]'}) do
- eq('Vim(call):E928: String required', exc_exec('call executable('..input..')'))
+ eq('Vim(call):E1174: String required for argument 1',
+ exc_exec('call executable('..input..')'))
end
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
for _, input in ipairs({'v:null', 'v:true', 'v:false'}) do
- eq('Vim(call):E928: String required', exc_exec('call executable('..input..')'))
+ eq('Vim(call):E1174: String required for argument 1',
+ exc_exec('call executable('..input..')'))
end
end)
@@ -54,8 +57,8 @@ describe('executable()', function()
-- Some executable in build/bin/, *not* in $PATH nor CWD.
local sibling_exe = 'printargs-test'
-- Windows: siblings are in Nvim's "pseudo-$PATH".
- local expected = iswin() and 1 or 0
- if iswin() then
+ local expected = is_os('win') and 1 or 0
+ if is_os('win') then
eq('arg1=lemon;arg2=sky;arg3=tree;',
call('system', sibling_exe..' lemon sky tree'))
end
@@ -67,7 +70,7 @@ describe('executable()', function()
clear()
write_file('Xtest_not_executable', 'non-executable file')
write_file('Xtest_executable', 'executable file (exec-bit set)')
- if not iswin() then -- N/A for Windows.
+ if not is_os('win') then -- N/A for Windows.
call('system', {'chmod', '-x', 'Xtest_not_executable'})
call('system', {'chmod', '+x', 'Xtest_executable'})
end
@@ -88,14 +91,17 @@ describe('executable()', function()
end)
it('set, qualified as a path', function()
- local expected = iswin() and 0 or 1
+ local expected = is_os('win') and 0 or 1
eq(expected, call('executable', './Xtest_executable'))
end)
end)
end)
describe('executable() (Windows)', function()
- if not iswin() then return end -- N/A for Unix.
+ if not is_os('win') then
+ pending('N/A for non-windows')
+ return
+ end
local exts = {'bat', 'exe', 'com', 'cmd'}
setup(function()
diff --git a/test/functional/vimscript/execute_spec.lua b/test/functional/vimscript/execute_spec.lua
index a733b098f5..5fe3d787cb 100644
--- a/test/functional/vimscript/execute_spec.lua
+++ b/test/functional/vimscript/execute_spec.lua
@@ -8,7 +8,7 @@ local funcs = helpers.funcs
local Screen = require('test.functional.ui.screen')
local command = helpers.command
local feed = helpers.feed
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('execute()', function()
before_each(clear)
@@ -265,7 +265,7 @@ describe('execute()', function()
-- This deviates from vim behavior, but is consistent
-- with how nvim currently displays the output.
it('captures shell-command output', function()
- local win_lf = iswin() and '\13' or ''
+ local win_lf = is_os('win') and '\13' or ''
eq('\n:!echo foo\r\n\nfoo'..win_lf..'\n', funcs.execute('!echo foo'))
end)
diff --git a/test/functional/vimscript/exepath_spec.lua b/test/functional/vimscript/exepath_spec.lua
index bbca954511..056f67e0ad 100644
--- a/test/functional/vimscript/exepath_spec.lua
+++ b/test/functional/vimscript/exepath_spec.lua
@@ -1,19 +1,20 @@
local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, call, iswin =
- helpers.eq, helpers.clear, helpers.call, helpers.iswin
+local eq, clear, call =
+ helpers.eq, helpers.clear, helpers.call
local command = helpers.command
local exc_exec = helpers.exc_exec
local matches = helpers.matches
+local is_os = helpers.is_os
describe('exepath()', function()
before_each(clear)
it('returns 1 for commands in $PATH', function()
- local exe = iswin() and 'ping' or 'ls'
- local ext_pat = iswin() and '%.EXE$' or '$'
+ local exe = is_os('win') and 'ping' or 'ls'
+ local ext_pat = is_os('win') and '%.EXE$' or '$'
matches(exe .. ext_pat, call('exepath', exe))
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
- ext_pat = iswin() and '%.CMD$' or '$'
+ ext_pat = is_os('win') and '%.CMD$' or '$'
matches('null' .. ext_pat, call('exepath', 'null'))
matches('true' .. ext_pat, call('exepath', 'true'))
matches('false' .. ext_pat, call('exepath', 'false'))
@@ -21,16 +22,16 @@ describe('exepath()', function()
it('fails for invalid values', function()
for _, input in ipairs({'v:null', 'v:true', 'v:false', '{}', '[]'}) do
- eq('Vim(call):E928: String required', exc_exec('call exepath('..input..')'))
+ eq('Vim(call):E1174: String required for argument 1', exc_exec('call exepath('..input..')'))
end
- eq('Vim(call):E1142: Non-empty string required', exc_exec('call exepath("")'))
+ eq('Vim(call):E1175: Non-empty string required for argument 1', exc_exec('call exepath("")'))
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
for _, input in ipairs({'v:null', 'v:true', 'v:false'}) do
- eq('Vim(call):E928: String required', exc_exec('call exepath('..input..')'))
+ eq('Vim(call):E1174: String required for argument 1', exc_exec('call exepath('..input..')'))
end
end)
- if iswin() then
+ if is_os('win') then
it('append extension if omitted', function()
local filename = 'cmd'
local pathext = '.exe'
diff --git a/test/functional/vimscript/fnamemodify_spec.lua b/test/functional/vimscript/fnamemodify_spec.lua
index d54a6db417..c3ecdd853c 100644
--- a/test/functional/vimscript/fnamemodify_spec.lua
+++ b/test/functional/vimscript/fnamemodify_spec.lua
@@ -1,12 +1,12 @@
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
-local iswin = helpers.iswin
local fnamemodify = helpers.funcs.fnamemodify
local getcwd = helpers.funcs.getcwd
local command = helpers.command
local write_file = helpers.write_file
local alter_slashes = helpers.alter_slashes
+local is_os = helpers.is_os
local function eq_slashconvert(expected, got)
eq(alter_slashes(expected), alter_slashes(got))
@@ -27,7 +27,7 @@ describe('fnamemodify()', function()
local root = helpers.pathroot()
eq(root, fnamemodify([[/]], ':p:h'))
eq(root, fnamemodify([[/]], ':p'))
- if iswin() then
+ if is_os('win') then
eq(root, fnamemodify([[\]], ':p:h'))
eq(root, fnamemodify([[\]], ':p'))
command('set shellslash')
@@ -114,7 +114,7 @@ describe('fnamemodify()', function()
it('handles shell escape', function()
local expected
- if iswin() then
+ if is_os('win') then
-- we expand with double-quotes on Windows
expected = [["hello there! quote ' newline]] .. '\n' .. [["]]
else
diff --git a/test/functional/vimscript/functions_spec.lua b/test/functional/vimscript/functions_spec.lua
index 20c1400030..09b3334989 100644
--- a/test/functional/vimscript/functions_spec.lua
+++ b/test/functional/vimscript/functions_spec.lua
@@ -9,12 +9,12 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eval = helpers.eval
-local iswin = helpers.iswin
local matches = helpers.matches
+local is_os = helpers.is_os
before_each(clear)
it('windowsversion()', function()
clear()
- matches(iswin() and '^%d+%.%d+$' or '^$', eval('windowsversion()'))
+ matches(is_os('win') and '^%d+%.%d+$' or '^$', eval('windowsversion()'))
end)
diff --git a/test/functional/vimscript/has_spec.lua b/test/functional/vimscript/has_spec.lua
index 4d9b226434..2e26d603b3 100644
--- a/test/functional/vimscript/has_spec.lua
+++ b/test/functional/vimscript/has_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local clear = helpers.clear
local funcs = helpers.funcs
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('has()', function()
before_each(clear)
@@ -51,7 +51,7 @@ describe('has()', function()
end)
it('"unnamedplus"', function()
- if (not iswin()) and funcs.has("clipboard") == 1 then
+ if (not is_os('win')) and funcs.has("clipboard") == 1 then
eq(1, funcs.has("unnamedplus"))
else
eq(0, funcs.has("unnamedplus"))
diff --git a/test/functional/vimscript/hostname_spec.lua b/test/functional/vimscript/hostname_spec.lua
index 6112cf64e3..7d4baa7213 100644
--- a/test/functional/vimscript/hostname_spec.lua
+++ b/test/functional/vimscript/hostname_spec.lua
@@ -3,7 +3,7 @@ local eq = helpers.eq
local ok = helpers.ok
local call = helpers.call
local clear = helpers.clear
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('hostname()', function()
before_each(clear)
@@ -13,8 +13,8 @@ describe('hostname()', function()
ok(string.len(actual) > 0)
if call('executable', 'hostname') == 1 then
local expected = string.gsub(call('system', 'hostname'), '[\n\r]', '')
- eq((iswin() and expected:upper() or expected),
- (iswin() and actual:upper() or actual))
+ eq((is_os('win') and expected:upper() or expected),
+ (is_os('win') and actual:upper() or actual))
end
end)
end)
diff --git a/test/functional/vimscript/input_spec.lua b/test/functional/vimscript/input_spec.lua
index 554d15e550..f50b39c2c5 100644
--- a/test/functional/vimscript/input_spec.lua
+++ b/test/functional/vimscript/input_spec.lua
@@ -8,7 +8,8 @@ local clear = helpers.clear
local source = helpers.source
local command = helpers.command
local exc_exec = helpers.exc_exec
-local nvim_async = helpers.nvim_async
+local pcall_err = helpers.pcall_err
+local async_meths = helpers.async_meths
local NIL = helpers.NIL
local screen
@@ -449,6 +450,78 @@ describe('inputdialog()', function()
end)
describe('confirm()', function()
+ -- oldtest: Test_confirm()
+ it('works', function()
+ meths.set_option('more', false) -- Avoid hit-enter prompt
+ meths.set_option('laststatus', 2)
+ -- screen:expect() calls are needed to avoid feeding input too early
+ screen:expect({any = '%[No Name%]'})
+
+ async_meths.command([[let a = confirm('Press O to proceed')]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('o')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+
+ async_meths.command([[let a = 'Are you sure?'->confirm("&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('y')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('n')
+ screen:expect({any = '%[No Name%]'})
+ eq(2, meths.get_var('a'))
+
+ -- Not possible to match Vim's CTRL-C test here as CTRL-C always sets got_int in Nvim.
+
+ -- confirm() should return 0 when pressing ESC.
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<Esc>')
+ screen:expect({any = '%[No Name%]'})
+ eq(0, meths.get_var('a'))
+
+ -- Default choice is returned when pressing <CR>.
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No")]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<CR>')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No", 2)]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<CR>')
+ screen:expect({any = '%[No Name%]'})
+ eq(2, meths.get_var('a'))
+
+ async_meths.command([[let a = confirm('Are you sure?', "&Yes\n&No", 0)]])
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('<CR>')
+ screen:expect({any = '%[No Name%]'})
+ eq(0, meths.get_var('a'))
+
+ -- Test with the {type} 4th argument
+ for _, type in ipairs({'Error', 'Question', 'Info', 'Warning', 'Generic'}) do
+ async_meths.command(([[let a = confirm('Are you sure?', "&Yes\n&No", 1, '%s')]]):format(type))
+ screen:expect({any = '{CONFIRM:.+: }'})
+ feed('y')
+ screen:expect({any = '%[No Name%]'})
+ eq(1, meths.get_var('a'))
+ end
+
+ eq('Vim(call):E730: using List as a String',
+ pcall_err(command, 'call confirm([])'))
+ eq('Vim(call):E730: using List as a String',
+ pcall_err(command, 'call confirm("Are you sure?", [])'))
+ eq('Vim(call):E745: Using a List as a Number',
+ pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", [])'))
+ eq('Vim(call):E730: using List as a String',
+ pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", 0, [])'))
+ end)
+
it("shows dialog even if :silent #8788", function()
command("autocmd BufNewFile * call confirm('test')")
@@ -483,7 +556,7 @@ describe('confirm()', function()
feed(':call nvim_command("edit x")<cr>')
check_and_clear(':call nvim_command("edit |\n')
- nvim_async('command', 'edit x')
+ async_meths.command('edit x')
check_and_clear(' |\n')
end)
end)
diff --git a/test/functional/vimscript/json_functions_spec.lua b/test/functional/vimscript/json_functions_spec.lua
index 5d1597f53d..70d0934756 100644
--- a/test/functional/vimscript/json_functions_spec.lua
+++ b/test/functional/vimscript/json_functions_spec.lua
@@ -343,7 +343,7 @@ describe('json_decode() function', function()
exc_exec('call json_decode("\\t\\"abc\\\\u0000")'))
end)
- it('fails to parse unknown escape sequnces', function()
+ it('fails to parse unknown escape sequences', function()
eq('Vim(call):E474: Unknown escape sequence: \\a"',
exc_exec('call json_decode("\\t\\"\\\\a\\"")'))
end)
diff --git a/test/functional/vimscript/map_functions_spec.lua b/test/functional/vimscript/map_functions_spec.lua
index aa64006de0..ba1b4d7a76 100644
--- a/test/functional/vimscript/map_functions_spec.lua
+++ b/test/functional/vimscript/map_functions_spec.lua
@@ -3,6 +3,8 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local eq = helpers.eq
local eval = helpers.eval
+local exec = helpers.exec
+local exec_lua = helpers.exec_lua
local expect = helpers.expect
local feed = helpers.feed
local funcs = helpers.funcs
@@ -10,6 +12,8 @@ local meths = helpers.meths
local nvim = helpers.nvim
local source = helpers.source
local command = helpers.command
+local exec_capture = helpers.exec_capture
+local pcall_err = helpers.pcall_err
describe('maparg()', function()
before_each(clear)
@@ -172,14 +176,12 @@ describe('mapset()', function()
it('can restore mapping description from the dict returned by maparg()', function()
meths.set_keymap('n', 'lhs', 'rhs', {desc = 'map description'})
- eq('\nn lhs rhs\n map description',
- helpers.exec_capture("nmap lhs"))
+ eq('\nn lhs rhs\n map description', exec_capture("nmap lhs"))
local mapargs = funcs.maparg('lhs', 'n', false, true)
- meths.del_keymap('n', 'lhs')
- eq('\nNo mapping found', helpers.exec_capture("nmap lhs"))
+ meths.set_keymap('n', 'lhs', 'rhs', {desc = 'MAP DESCRIPTION'})
+ eq('\nn lhs rhs\n MAP DESCRIPTION', exec_capture("nmap lhs"))
funcs.mapset('n', false, mapargs)
- eq('\nn lhs rhs\n map description',
- helpers.exec_capture("nmap lhs"))
+ eq('\nn lhs rhs\n map description', exec_capture("nmap lhs"))
end)
it('can restore "replace_keycodes" from the dict returned by maparg()', function()
@@ -194,4 +196,59 @@ describe('mapset()', function()
feed('foo')
expect('<<lt><')
end)
+
+ it('replaces an abbreviation of the same lhs #20320', function()
+ command('inoreabbr foo bar')
+ eq('\ni foo * bar', exec_capture('iabbr foo'))
+ feed('ifoo ')
+ expect('bar ')
+ local mapargs = funcs.maparg('foo', 'i', true, true)
+ command('inoreabbr foo BAR')
+ eq('\ni foo * BAR', exec_capture('iabbr foo'))
+ feed('foo ')
+ expect('bar BAR ')
+ funcs.mapset('i', true, mapargs)
+ eq('\ni foo * bar', exec_capture('iabbr foo'))
+ feed('foo<Esc>')
+ expect('bar BAR bar')
+ end)
+
+ it('can restore Lua callback from the dict returned by maparg()', function()
+ eq(0, exec_lua([[
+ GlobalCount = 0
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 1 end })
+ return GlobalCount
+ ]]))
+ feed('asdf')
+ eq(1, exec_lua([[return GlobalCount]]))
+
+ exec_lua([[
+ _G.saved_asdf_map = vim.fn.maparg('asdf', 'n', false, true)
+ vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 10 end })
+ ]])
+ feed('asdf')
+ eq(11, exec_lua([[return GlobalCount]]))
+
+ exec_lua([[vim.fn.mapset('n', false, _G.saved_asdf_map)]])
+ feed('asdf')
+ eq(12, exec_lua([[return GlobalCount]]))
+
+ exec([[
+ let g:saved_asdf_map = maparg('asdf', 'n', v:false, v:true)
+ lua vim.api.nvim_set_keymap('n', 'asdf', '', {callback = function() GlobalCount = GlobalCount + 10 end })
+ ]])
+ feed('asdf')
+ eq(22, exec_lua([[return GlobalCount]]))
+
+ command([[call mapset('n', v:false, g:saved_asdf_map)]])
+ feed('asdf')
+ eq(23, exec_lua([[return GlobalCount]]))
+ end)
+
+ it('does not leak memory if lhs is missing', function()
+ eq('Vim:E460: entries missing in mapset() dict argument',
+ pcall_err(exec_lua, [[vim.fn.mapset('n', false, {rhs = 'foo'})]]))
+ eq('Vim:E460: entries missing in mapset() dict argument',
+ pcall_err(exec_lua, [[vim.fn.mapset('n', false, {callback = function() end})]]))
+ end)
end)
diff --git a/test/functional/vimscript/msgpack_functions_spec.lua b/test/functional/vimscript/msgpack_functions_spec.lua
index cab67d77e4..de5a721efe 100644
--- a/test/functional/vimscript/msgpack_functions_spec.lua
+++ b/test/functional/vimscript/msgpack_functions_spec.lua
@@ -5,7 +5,7 @@ local eval, eq = helpers.eval, helpers.eq
local command = helpers.command
local nvim = helpers.nvim
local exc_exec = helpers.exc_exec
-local iswin = helpers.iswin
+local is_os = helpers.is_os
describe('msgpack*() functions', function()
before_each(clear)
@@ -467,7 +467,7 @@ describe('msgpackparse() function', function()
eval(cmd)
eval(cmd) -- do it again (try to force segfault)
local api_info = eval(cmd) -- do it again
- if iswin() then
+ if is_os('win') then
helpers.assert_alive()
pending('msgpackparse() has a bug on windows')
return
diff --git a/test/functional/vimscript/null_spec.lua b/test/functional/vimscript/null_spec.lua
index 2451da983e..1153baac46 100644
--- a/test/functional/vimscript/null_spec.lua
+++ b/test/functional/vimscript/null_spec.lua
@@ -69,7 +69,7 @@ describe('NULL', function()
null_expr_test('can be splice-indexed', 'L[:]', 0, {})
null_expr_test('is not locked', 'islocked("v:_null_list")', 0, 0)
null_test('is accepted by :for', 'for x in L|throw x|endfor', 0)
- null_expr_test('does not crash append()', 'append(1, L)', 0, 0, function()
+ null_expr_test('does not crash append()', 'append(0, L)', 0, 0, function()
eq({''}, curbufmeths.get_lines(0, -1, false))
end)
null_expr_test('does not crash setline()', 'setline(1, L)', 0, 0, function()
diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua
index 6e95459630..c89a0c4e93 100644
--- a/test/functional/vimscript/server_spec.lua
+++ b/test/functional/vimscript/server_spec.lua
@@ -1,11 +1,14 @@
local helpers = require('test.functional.helpers')(after_each)
+local assert_log = helpers.assert_log
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
-local iswin = helpers.iswin
local ok = helpers.ok
local matches = helpers.matches
local pcall_err = helpers.pcall_err
local mkdir = helpers.mkdir
+local is_os = helpers.is_os
+
+local testlog = 'Xtest-server-log'
local function clear_serverlist()
for _, server in pairs(funcs.serverlist()) do
@@ -14,12 +17,16 @@ local function clear_serverlist()
end
describe('server', function()
+ after_each(function()
+ os.remove(testlog)
+ end)
+
it('serverstart() stores sockets in $XDG_RUNTIME_DIR', function()
local dir = 'Xtest_xdg_run'
mkdir(dir)
clear({ env={ XDG_RUNTIME_DIR=dir } })
matches(dir, funcs.stdpath('run'))
- if not iswin() then
+ if not is_os('win') then
matches(dir, funcs.serverstart())
end
end)
@@ -65,7 +72,7 @@ describe('server', function()
eq('', meths.get_vvar('servername'))
-- v:servername and $NVIM take the next available server.
- local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
+ local servername = (is_os('win') and [[\\.\pipe\Xtest-functional-server-pipe]]
or './Xtest-functional-server-socket')
funcs.serverstart(servername)
eq(servername, meths.get_vvar('servername'))
@@ -74,13 +81,20 @@ describe('server', function()
end)
it('serverstop() returns false for invalid input', function()
- clear()
+ clear{env={
+ NVIM_LOG_FILE=testlog,
+ NVIM_LISTEN_ADDRESS='.',
+ }}
eq(0, eval("serverstop('')"))
eq(0, eval("serverstop('bogus-socket-name')"))
+ assert_log('Not listening on bogus%-socket%-name', testlog, 10)
end)
it('parses endpoints', function()
- clear()
+ clear{env={
+ NVIM_LOG_FILE=testlog,
+ NVIM_LISTEN_ADDRESS='.',
+ }}
clear_serverlist()
eq({}, funcs.serverlist())
@@ -104,6 +118,7 @@ describe('server', function()
if status then
table.insert(expected, v4)
pcall(funcs.serverstart, v4) -- exists already; ignore
+ assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10)
end
local v6 = '::1:12345'
@@ -111,6 +126,7 @@ describe('server', function()
if status then
table.insert(expected, v6)
pcall(funcs.serverstart, v6) -- exists already; ignore
+ assert_log('Failed to start server: address already in use: ::1', testlog, 10)
end
eq(expected, funcs.serverlist())
clear_serverlist()
@@ -130,7 +146,7 @@ describe('server', function()
local n = eval('len(serverlist())')
-- Add some servers.
- local servs = (iswin()
+ local servs = (is_os('win')
and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] })
for _, s in ipairs(servs) do
@@ -164,7 +180,7 @@ describe('startup --listen', function()
end)
it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
- local addr = (iswin() and [[\\.\pipe\Xtest-listen-pipe]]
+ local addr = (is_os('win') and [[\\.\pipe\Xtest-listen-pipe]]
or './Xtest-listen-pipe')
clear({ env={ NVIM_LISTEN_ADDRESS='./Xtest-env-pipe' },
args={ '--listen', addr } })
diff --git a/test/functional/vimscript/system_spec.lua b/test/functional/vimscript/system_spec.lua
index a778e2f435..7ada1c4bea 100644
--- a/test/functional/vimscript/system_spec.lua
+++ b/test/functional/vimscript/system_spec.lua
@@ -1,3 +1,5 @@
+-- Tests for system() and :! shell.
+
local helpers = require('test.functional.helpers')(after_each)
local assert_alive = helpers.assert_alive
@@ -9,9 +11,9 @@ local command = helpers.command
local insert = helpers.insert
local expect = helpers.expect
local exc_exec = helpers.exc_exec
-local iswin = helpers.iswin
local os_kill = helpers.os_kill
local pcall_err = helpers.pcall_err
+local is_os = helpers.is_os
local Screen = require('test.functional.ui.screen')
@@ -85,7 +87,7 @@ describe('system()', function()
end)
it('does NOT run in shell', function()
- if iswin() then
+ if is_os('win') then
eq("%PATH%\n", eval("system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])"))
else
eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])"))
@@ -94,7 +96,7 @@ describe('system()', function()
end)
it('sets v:shell_error', function()
- if iswin() then
+ if is_os('win') then
eval([[system("cmd.exe /c exit")]])
eq(0, eval('v:shell_error'))
eval([[system("cmd.exe /c exit 1")]])
@@ -123,7 +125,7 @@ describe('system()', function()
screen:attach()
end)
- if iswin() then
+ if is_os('win') then
local function test_more()
eq('root = true', eval([[get(split(system('"more" ".editorconfig"'), "\n"), 0, '')]]))
end
@@ -184,7 +186,7 @@ describe('system()', function()
-- * on Windows, expected to default to Western European enc
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
- eq(iswin() and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]]))
+ eq(is_os('win') and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]]))
end)
it('`echo` and waits for its return', function()
@@ -213,7 +215,7 @@ describe('system()', function()
screen:try_resize(72, 14)
feed(':4verbose echo system("echo hi")<cr>')
- if iswin() then
+ if is_os('win') then
screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]]}
else
screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]]}
@@ -243,7 +245,7 @@ describe('system()', function()
end)
it('`yes` interrupted with CTRL-C', function()
- feed(':call system("' .. (iswin()
+ feed(':call system("' .. (is_os('win')
and 'for /L %I in (1,0,2) do @echo y'
or 'yes') .. '")<cr>')
screen:expect([[
@@ -260,7 +262,7 @@ describe('system()', function()
~ |
~ |
~ |
-]] .. (iswin()
+]] .. (is_os('win')
and [[
:call system("for /L %I in (1,0,2) do @echo y") |]]
or [[
@@ -286,7 +288,7 @@ describe('system()', function()
it('`yes` interrupted with mapped CTRL-C', function()
command('nnoremap <C-C> i')
- feed(':call system("' .. (iswin()
+ feed(':call system("' .. (is_os('win')
and 'for /L %I in (1,0,2) do @echo y'
or 'yes') .. '")<cr>')
screen:expect([[
@@ -303,7 +305,7 @@ describe('system()', function()
~ |
~ |
~ |
-]] .. (iswin()
+]] .. (is_os('win')
and [[
:call system("for /L %I in (1,0,2) do @echo y") |]]
or [[
@@ -330,7 +332,7 @@ describe('system()', function()
describe('passing no input', function()
it('returns the program output', function()
- if iswin() then
+ if is_os('win') then
eq("echoed\n", eval('system("echo echoed")'))
else
eq("echoed", eval('system("echo -n echoed")'))
@@ -438,7 +440,7 @@ describe('systemlist()', function()
before_each(clear)
it('sets v:shell_error', function()
- if iswin() then
+ if is_os('win') then
eval([[systemlist("cmd.exe /c exit")]])
eq(0, eval('v:shell_error'))
eval([[systemlist("cmd.exe /c exit 1")]])
@@ -617,12 +619,12 @@ describe('systemlist()', function()
return
end
helpers.set_shell_powershell()
- eq({iswin() and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
+ eq({is_os('win') and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
-- Sanity test w/ default encoding
-- * on Windows, expected to default to Western European enc
-- * on Linux, expected to default to UTF8
command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
- eq({iswin() and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
+ eq({is_os('win') and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
end)
end)
@@ -639,15 +641,15 @@ describe('shell :!', function()
1
4
2]])
- if iswin() then
+ if is_os('win') then
feed(':4verbose %!sort /R<cr>')
screen:expect{
- any=[[Executing command: .?Start%-Process sort %-ArgumentList "/R" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ any=[[Executing command: .?& { Get%-Content .* | & sort /R } 2>&1 | Out%-File %-Encoding UTF8 .*; exit $LastExitCode"]]
}
else
feed(':4verbose %!sort -r<cr>')
screen:expect{
- any=[[Executing command: .?Start%-Process sort %-ArgumentList "%-r" %-RedirectStandardInput .* %-RedirectStandardOutput .* %-NoNewWindow %-Wait]]
+ any=[[Executing command: .?& { Get%-Content .* | & sort %-r } 2>&1 | Out%-File %-Encoding UTF8 .*; exit $LastExitCode"]]
}
end
feed('<CR>')
@@ -660,4 +662,33 @@ describe('shell :!', function()
1]])
end
end)
+
+ it(':{range}! without redirecting to buffer', function()
+ local screen = Screen.new(500, 10)
+ screen:attach()
+ insert([[
+ 3
+ 1
+ 4
+ 2]])
+ feed(':4verbose %w !sort<cr>')
+ if is_os('win') then
+ screen:expect{
+ any=[[Executing command: .?sort %< .*]]
+ }
+ else
+ screen:expect{
+ any=[[Executing command: .?%(sort%) %< .*]]
+
+ }
+ end
+ feed('<CR>')
+ helpers.set_shell_powershell(true)
+ feed(':4verbose %w !sort<cr>')
+ screen:expect{
+ any=[[Executing command: .?& { Get%-Content .* | & sort }]]
+ }
+ feed('<CR>')
+ helpers.expect_exit(command, 'qall!')
+ end)
end)
diff --git a/test/functional/vimscript/timer_spec.lua b/test/functional/vimscript/timer_spec.lua
index 5463cfb234..1818a71ea2 100644
--- a/test/functional/vimscript/timer_spec.lua
+++ b/test/functional/vimscript/timer_spec.lua
@@ -131,34 +131,34 @@ describe('timers', function()
nvim_async("command", "call timer_start("..load_adjust(100)..", 'AddItem', {'repeat': -1})")
screen:expect([[
- ITEM 1 |
+ ^ITEM 1 |
ITEM 2 |
{1:~ }|
{1:~ }|
{1:~ }|
- ^ |
+ |
]])
nvim_async("command", "let g:cont = 1")
screen:expect([[
- ITEM 1 |
+ ^ITEM 1 |
ITEM 2 |
ITEM 3 |
{1:~ }|
{1:~ }|
- ^ |
+ |
]])
feed("3")
eq(51, eval("g:c2"))
- screen:expect([[
+ screen:expect{grid=[[
^ITEM 1 |
ITEM 2 |
ITEM 3 |
{1:~ }|
{1:~ }|
|
- ]])
+ ]], unchanged=true}
end)
it('can be stopped', function()
diff --git a/test/functional/vimscript/writefile_spec.lua b/test/functional/vimscript/writefile_spec.lua
index 5f693249a9..8c8da9dc88 100644
--- a/test/functional/vimscript/writefile_spec.lua
+++ b/test/functional/vimscript/writefile_spec.lua
@@ -111,6 +111,26 @@ describe('writefile()', function()
pcall_err(command, ('call writefile([42], %s)'):format(ddname_tail)))
end)
+ it('writefile(..., "p") creates missing parent directories', function()
+ os.remove(dname)
+ eq(nil, read_file(dfname))
+ eq(0, funcs.writefile({'abc', 'def', 'ghi'}, dfname, 'p'))
+ eq('abc\ndef\nghi\n', read_file(dfname))
+ os.remove(dfname)
+ os.remove(dname)
+ eq(nil, read_file(dfname))
+ eq(0, funcs.writefile({'\na\nb\n'}, dfname, 'pb'))
+ eq('\0a\0b\0', read_file(dfname))
+ os.remove(dfname)
+ os.remove(dname)
+ eq('Vim(call):E32: No file name',
+ pcall_err(command, ('call writefile([], "%s", "p")'):format(dfname .. '.d/')))
+ eq(('Vim(call):E482: Can\'t open file ./ for writing: illegal operation on a directory'),
+ pcall_err(command, 'call writefile([], "./", "p")'))
+ eq(('Vim(call):E482: Can\'t open file . for writing: illegal operation on a directory'),
+ pcall_err(command, 'call writefile([], ".", "p")'))
+ end)
+
it('errors out with invalid arguments', function()
write_file(fname, 'TEST')
eq('Vim(call):E119: Not enough arguments for function: writefile',