mirror of
https://github.com/neovim/neovim.git
synced 2025-11-17 15:51:32 +00:00
refactor: format test/*
This commit is contained in:
@@ -11,24 +11,24 @@ local feed = helpers.feed
|
||||
describe('eval-API', function()
|
||||
before_each(clear)
|
||||
|
||||
it("work", function()
|
||||
it('work', function()
|
||||
command("call nvim_command('let g:test = 1')")
|
||||
eq(1, eval("nvim_get_var('test')"))
|
||||
|
||||
local buf = eval("nvim_get_current_buf()")
|
||||
command("call nvim_buf_set_lines("..buf..", 0, -1, v:true, ['aa', 'bb'])")
|
||||
local buf = eval('nvim_get_current_buf()')
|
||||
command('call nvim_buf_set_lines(' .. buf .. ", 0, -1, v:true, ['aa', 'bb'])")
|
||||
expect([[
|
||||
aa
|
||||
bb]])
|
||||
|
||||
command("call nvim_win_set_cursor(0, [1, 1])")
|
||||
command('call nvim_win_set_cursor(0, [1, 1])')
|
||||
command("call nvim_input('ax<esc>')")
|
||||
expect([[
|
||||
aax
|
||||
bb]])
|
||||
end)
|
||||
|
||||
it("throw errors for invalid arguments", function()
|
||||
it('throw errors for invalid arguments', function()
|
||||
local err = exc_exec('call nvim_get_current_buf("foo")')
|
||||
eq('Vim(call):E118: Too many arguments for function: nvim_get_current_buf', err)
|
||||
|
||||
@@ -36,100 +36,121 @@ describe('eval-API', function()
|
||||
eq('Vim(call):E119: Not enough arguments for function: nvim_set_option_value', err)
|
||||
|
||||
err = exc_exec('call nvim_buf_set_lines(1, 0, -1, [], ["list"])')
|
||||
eq('Vim(call):E5555: API call: Wrong type for argument 4 when calling nvim_buf_set_lines, expecting Boolean', err)
|
||||
eq(
|
||||
'Vim(call):E5555: API call: Wrong type for argument 4 when calling nvim_buf_set_lines, expecting Boolean',
|
||||
err
|
||||
)
|
||||
|
||||
err = exc_exec('call nvim_buf_set_lines(0, 0, -1, v:true, "string")')
|
||||
eq('Vim(call):E5555: API call: Wrong type for argument 5 when calling nvim_buf_set_lines, expecting ArrayOf(String)', err)
|
||||
eq(
|
||||
'Vim(call):E5555: API call: Wrong type for argument 5 when calling nvim_buf_set_lines, expecting ArrayOf(String)',
|
||||
err
|
||||
)
|
||||
|
||||
err = exc_exec('call nvim_buf_get_number("0")')
|
||||
eq('Vim(call):E5555: API call: Wrong type for argument 1 when calling nvim_buf_get_number, expecting Buffer', err)
|
||||
eq(
|
||||
'Vim(call):E5555: API call: Wrong type for argument 1 when calling nvim_buf_get_number, expecting Buffer',
|
||||
err
|
||||
)
|
||||
|
||||
err = exc_exec('call nvim_buf_line_count(17)')
|
||||
eq('Vim(call):E5555: API call: Invalid buffer id: 17', err)
|
||||
end)
|
||||
|
||||
it('cannot change text or window if textlocked', function()
|
||||
command("autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])")
|
||||
matches('Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$',
|
||||
pcall_err(command, "normal! yy"))
|
||||
command('autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])')
|
||||
matches(
|
||||
'Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$',
|
||||
pcall_err(command, 'normal! yy')
|
||||
)
|
||||
|
||||
command("autocmd TextYankPost <buffer> ++once call nvim_open_term(0, {})")
|
||||
matches('Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$',
|
||||
pcall_err(command, "normal! yy"))
|
||||
command('autocmd TextYankPost <buffer> ++once call nvim_open_term(0, {})')
|
||||
matches(
|
||||
'Vim%(call%):E5555: API call: E565: Not allowed to change text or change window$',
|
||||
pcall_err(command, 'normal! yy')
|
||||
)
|
||||
|
||||
-- Functions checking textlock should also not be usable from <expr> mappings.
|
||||
command("inoremap <expr> <f2> nvim_win_close(0, 1)")
|
||||
eq('Vim(normal):E5555: API call: E565: Not allowed to change text or change window',
|
||||
pcall_err(command, [[execute "normal i\<f2>"]]))
|
||||
command('inoremap <expr> <f2> nvim_win_close(0, 1)')
|
||||
eq(
|
||||
'Vim(normal):E5555: API call: E565: Not allowed to change text or change window',
|
||||
pcall_err(command, [[execute "normal i\<f2>"]])
|
||||
)
|
||||
|
||||
-- Text-changing functions gave a "Failed to save undo information" error when called from an
|
||||
-- <expr> mapping outside do_cmdline() (msg_list == NULL), so use feed() to test this.
|
||||
command("inoremap <expr> <f2> nvim_buf_set_text(0, 0, 0, 0, 0, ['hi'])")
|
||||
meths.set_vvar('errmsg', '')
|
||||
feed("i<f2><esc>")
|
||||
eq('E5555: API call: E565: Not allowed to change text or change window',
|
||||
meths.get_vvar('errmsg'))
|
||||
feed('i<f2><esc>')
|
||||
eq(
|
||||
'E5555: API call: E565: Not allowed to change text or change window',
|
||||
meths.get_vvar('errmsg')
|
||||
)
|
||||
|
||||
-- Some functions checking textlock (usually those that may change the current window or buffer)
|
||||
-- also ought to not be usable in the cmdwin.
|
||||
local old_win = meths.get_current_win()
|
||||
feed("q:")
|
||||
eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits',
|
||||
pcall_err(meths.set_current_win, old_win))
|
||||
feed('q:')
|
||||
eq(
|
||||
'E11: Invalid in command-line window; <CR> executes, CTRL-C quits',
|
||||
pcall_err(meths.set_current_win, old_win)
|
||||
)
|
||||
|
||||
-- But others, like nvim_buf_set_lines(), which just changes text, is OK.
|
||||
curbufmeths.set_lines(0, -1, 1, {"wow!"})
|
||||
eq({'wow!'}, curbufmeths.get_lines(0, -1, 1))
|
||||
curbufmeths.set_lines(0, -1, 1, { 'wow!' })
|
||||
eq({ 'wow!' }, curbufmeths.get_lines(0, -1, 1))
|
||||
|
||||
-- Turning the cmdwin buffer into a terminal buffer would be pretty weird.
|
||||
eq('E11: Invalid in command-line window; <CR> executes, CTRL-C quits',
|
||||
pcall_err(meths.open_term, 0, {}))
|
||||
eq(
|
||||
'E11: Invalid in command-line window; <CR> executes, CTRL-C quits',
|
||||
pcall_err(meths.open_term, 0, {})
|
||||
)
|
||||
|
||||
-- But turning a different buffer into a terminal from the cmdwin is OK.
|
||||
local term_buf = meths.create_buf(false, true)
|
||||
meths.open_term(term_buf, {})
|
||||
eq('terminal', meths.get_option_value("buftype", {buf = term_buf}))
|
||||
eq('terminal', meths.get_option_value('buftype', { buf = term_buf }))
|
||||
end)
|
||||
|
||||
it("use buffer numbers and windows ids as handles", function()
|
||||
it('use buffer numbers and windows ids as handles', function()
|
||||
local screen = Screen.new(40, 8)
|
||||
screen:attach()
|
||||
local bnr = eval("bufnr('')")
|
||||
local bhnd = eval("nvim_get_current_buf()")
|
||||
local wid = eval("win_getid()")
|
||||
local whnd = eval("nvim_get_current_win()")
|
||||
local bhnd = eval('nvim_get_current_buf()')
|
||||
local wid = eval('win_getid()')
|
||||
local whnd = eval('nvim_get_current_win()')
|
||||
eq(bnr, bhnd)
|
||||
eq(wid, whnd)
|
||||
|
||||
command("new") -- creates new buffer and new window
|
||||
command('new') -- creates new buffer and new window
|
||||
local bnr2 = eval("bufnr('')")
|
||||
local bhnd2 = eval("nvim_get_current_buf()")
|
||||
local wid2 = eval("win_getid()")
|
||||
local whnd2 = eval("nvim_get_current_win()")
|
||||
local bhnd2 = eval('nvim_get_current_buf()')
|
||||
local wid2 = eval('win_getid()')
|
||||
local whnd2 = eval('nvim_get_current_win()')
|
||||
eq(bnr2, bhnd2)
|
||||
eq(wid2, whnd2)
|
||||
neq(bnr, bnr2)
|
||||
neq(wid, wid2)
|
||||
-- 0 is synonymous to the current buffer
|
||||
eq(bnr2, eval("nvim_buf_get_number(0)"))
|
||||
eq(bnr2, eval('nvim_buf_get_number(0)'))
|
||||
|
||||
command("bn") -- show old buffer in new window
|
||||
eq(bnr, eval("nvim_get_current_buf()"))
|
||||
command('bn') -- show old buffer in new window
|
||||
eq(bnr, eval('nvim_get_current_buf()'))
|
||||
eq(bnr, eval("bufnr('')"))
|
||||
eq(bnr, eval("nvim_buf_get_number(0)"))
|
||||
eq(wid2, eval("win_getid()"))
|
||||
eq(whnd2, eval("nvim_get_current_win()"))
|
||||
eq(bnr, eval('nvim_buf_get_number(0)'))
|
||||
eq(wid2, eval('win_getid()'))
|
||||
eq(whnd2, eval('nvim_get_current_win()'))
|
||||
end)
|
||||
|
||||
it("get_lines and set_lines use NL to represent NUL", function()
|
||||
curbufmeths.set_lines(0, -1, true, {"aa\0", "b\0b"})
|
||||
eq({'aa\n', 'b\nb'}, eval("nvim_buf_get_lines(0, 0, -1, 1)"))
|
||||
it('get_lines and set_lines use NL to represent NUL', function()
|
||||
curbufmeths.set_lines(0, -1, true, { 'aa\0', 'b\0b' })
|
||||
eq({ 'aa\n', 'b\nb' }, eval('nvim_buf_get_lines(0, 0, -1, 1)'))
|
||||
|
||||
command('call nvim_buf_set_lines(0, 1, 2, v:true, ["xx", "\\nyy"])')
|
||||
eq({'aa\0', 'xx', '\0yy'}, curbufmeths.get_lines(0, -1, 1))
|
||||
eq({ 'aa\0', 'xx', '\0yy' }, curbufmeths.get_lines(0, -1, 1))
|
||||
end)
|
||||
|
||||
it("that are FUNC_ATTR_NOEVAL cannot be called", function()
|
||||
it('that are FUNC_ATTR_NOEVAL cannot be called', function()
|
||||
-- Deprecated vim_ prefix is not exported.
|
||||
local err = exc_exec('call vim_get_current_buffer("foo")')
|
||||
eq('Vim(call):E117: Unknown function: vim_get_current_buffer', err)
|
||||
@@ -149,25 +170,24 @@ describe('eval-API', function()
|
||||
end)
|
||||
|
||||
it('have metadata accessible with api_info()', function()
|
||||
local api_keys = eval("sort(keys(api_info()))")
|
||||
eq({'error_types', 'functions', 'types',
|
||||
'ui_events', 'ui_options', 'version'}, api_keys)
|
||||
local api_keys = eval('sort(keys(api_info()))')
|
||||
eq({ 'error_types', 'functions', 'types', 'ui_events', 'ui_options', 'version' }, api_keys)
|
||||
end)
|
||||
|
||||
it('are highlighted by vim.vim syntax file', function()
|
||||
local screen = Screen.new(40, 8)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids({
|
||||
[1] = {bold = true, foreground = Screen.colors.Brown},
|
||||
[2] = {foreground = Screen.colors.DarkCyan},
|
||||
[3] = {foreground = Screen.colors.SlateBlue},
|
||||
[4] = {foreground = Screen.colors.Fuchsia},
|
||||
[5] = {bold = true, foreground = Screen.colors.Blue},
|
||||
[1] = { bold = true, foreground = Screen.colors.Brown },
|
||||
[2] = { foreground = Screen.colors.DarkCyan },
|
||||
[3] = { foreground = Screen.colors.SlateBlue },
|
||||
[4] = { foreground = Screen.colors.Fuchsia },
|
||||
[5] = { bold = true, foreground = Screen.colors.Blue },
|
||||
})
|
||||
|
||||
command("set ft=vim")
|
||||
command("set rtp^=build/runtime/")
|
||||
command("syntax on")
|
||||
command('set ft=vim')
|
||||
command('set rtp^=build/runtime/')
|
||||
command('syntax on')
|
||||
insert([[
|
||||
call bufnr('%')
|
||||
call nvim_input('typing...')
|
||||
@@ -183,9 +203,11 @@ describe('eval-API', function()
|
||||
end)
|
||||
|
||||
it('cannot be called from sandbox', function()
|
||||
eq('Vim(call):E48: Not allowed in sandbox',
|
||||
pcall_err(command, "sandbox call nvim_input('ievil')"))
|
||||
eq({''}, meths.buf_get_lines(0, 0, -1, true))
|
||||
eq(
|
||||
'Vim(call):E48: Not allowed in sandbox',
|
||||
pcall_err(command, "sandbox call nvim_input('ievil')")
|
||||
)
|
||||
eq({ '' }, meths.buf_get_lines(0, 0, -1, true))
|
||||
end)
|
||||
|
||||
it('converts blobs to API strings', function()
|
||||
|
||||
@@ -23,30 +23,47 @@ local dirname = fname .. '.d'
|
||||
|
||||
before_each(clear)
|
||||
|
||||
for _, func in ipairs({'bufname(%s)', 'bufnr(%s)', 'bufwinnr(%s)',
|
||||
'getbufline(%s, 1)', 'getbufvar(%s, "changedtick")',
|
||||
'setbufvar(%s, "f", 0)'}) do
|
||||
for _, func in ipairs({
|
||||
'bufname(%s)',
|
||||
'bufnr(%s)',
|
||||
'bufwinnr(%s)',
|
||||
'getbufline(%s, 1)',
|
||||
'getbufvar(%s, "changedtick")',
|
||||
'setbufvar(%s, "f", 0)',
|
||||
}) do
|
||||
local funcname = func:match('%w+')
|
||||
describe(funcname .. '() function', function()
|
||||
it('errors out when receives v:true/v:false/v:null', function()
|
||||
-- Not compatible with Vim: in Vim it always results in buffer not found
|
||||
-- without any error messages.
|
||||
for _, var in ipairs({'v:true', 'v:false'}) do
|
||||
eq('Vim(call):E5299: Expected a Number or a String, Boolean found',
|
||||
exc_exec('call ' .. func:format(var)))
|
||||
for _, var in ipairs({ 'v:true', 'v:false' }) do
|
||||
eq(
|
||||
'Vim(call):E5299: Expected a Number or a String, Boolean found',
|
||||
exc_exec('call ' .. func:format(var))
|
||||
)
|
||||
end
|
||||
eq('Vim(call):E5300: Expected a Number or a String',
|
||||
exc_exec('call ' .. func:format('v:null')))
|
||||
eq(
|
||||
'Vim(call):E5300: Expected a Number or a String',
|
||||
exc_exec('call ' .. func:format('v:null'))
|
||||
)
|
||||
end)
|
||||
it('errors out when receives invalid argument', function()
|
||||
eq('Vim(call):E745: Expected a Number or a String, List found',
|
||||
exc_exec('call ' .. func:format('[]')))
|
||||
eq('Vim(call):E728: Expected a Number or a String, Dictionary found',
|
||||
exc_exec('call ' .. func:format('{}')))
|
||||
eq('Vim(call):E805: Expected a Number or a String, Float found',
|
||||
exc_exec('call ' .. func:format('0.0')))
|
||||
eq('Vim(call):E703: Expected a Number or a String, Funcref found',
|
||||
exc_exec('call ' .. func:format('function("tr")')))
|
||||
eq(
|
||||
'Vim(call):E745: Expected a Number or a String, List found',
|
||||
exc_exec('call ' .. func:format('[]'))
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E728: Expected a Number or a String, Dictionary found',
|
||||
exc_exec('call ' .. func:format('{}'))
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E805: Expected a Number or a String, Float found',
|
||||
exc_exec('call ' .. func:format('0.0'))
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E703: Expected a Number or a String, Funcref found',
|
||||
exc_exec('call ' .. func:format('function("tr")'))
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -68,12 +85,12 @@ describe('bufname() function', function()
|
||||
rmdir(dirname)
|
||||
end)
|
||||
it('returns expected buffer name', function()
|
||||
eq('', funcs.bufname('%')) -- Buffer has no name yet
|
||||
eq('', funcs.bufname('%')) -- Buffer has no name yet
|
||||
command('file ' .. fname)
|
||||
local wd = luv.cwd()
|
||||
local sep = get_pathsep()
|
||||
local curdirname = funcs.fnamemodify(wd, ':t')
|
||||
for _, arg in ipairs({'%', 1, 'X', wd}) do
|
||||
for _, arg in ipairs({ '%', 1, 'X', wd }) do
|
||||
eq(fname, funcs.bufname(arg))
|
||||
meths.set_current_dir('..')
|
||||
eq(curdirname .. sep .. fname, funcs.bufname(arg))
|
||||
@@ -139,7 +156,7 @@ describe('bufwinnr() function', function()
|
||||
eq(-1, funcs.bufwinnr(2))
|
||||
eq(-1, funcs.bufwinnr('non-existent-buffer'))
|
||||
eq(-1, funcs.bufwinnr('#'))
|
||||
command('split ' .. fname2) -- It would be OK if there was one window
|
||||
command('split ' .. fname2) -- It would be OK if there was one window
|
||||
eq(2, funcs.bufnr('%'))
|
||||
eq(-1, funcs.bufwinnr('X'))
|
||||
end)
|
||||
@@ -181,7 +198,7 @@ describe('getbufline() function', function()
|
||||
end)
|
||||
it('returns empty list when range is invalid', function()
|
||||
eq({}, funcs.getbufline(1, 0))
|
||||
curbufmeths.set_lines(0, 1, false, {'foo', 'bar', 'baz'})
|
||||
curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'baz' })
|
||||
eq({}, funcs.getbufline(1, 2, 1))
|
||||
eq({}, funcs.getbufline(1, -10, -20))
|
||||
eq({}, funcs.getbufline(1, -2, -1))
|
||||
@@ -190,14 +207,14 @@ describe('getbufline() function', function()
|
||||
it('returns expected lines', function()
|
||||
meths.set_option_value('hidden', true, {})
|
||||
command('file ' .. fname)
|
||||
curbufmeths.set_lines(0, 1, false, {'foo\0', '\0bar', 'baz'})
|
||||
curbufmeths.set_lines(0, 1, false, { 'foo\0', '\0bar', 'baz' })
|
||||
command('edit ' .. fname2)
|
||||
curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'})
|
||||
eq({'foo\n', '\nbar', 'baz'}, funcs.getbufline(1, 1, 9999))
|
||||
eq({'abc\n', '\ndef', 'ghi'}, funcs.getbufline(2, 1, 9999))
|
||||
eq({'foo\n', '\nbar', 'baz'}, funcs.getbufline(1, 1, '$'))
|
||||
eq({'baz'}, funcs.getbufline(1, '$', '$'))
|
||||
eq({'baz'}, funcs.getbufline(1, '$', 9999))
|
||||
curbufmeths.set_lines(0, 1, false, { 'abc\0', '\0def', 'ghi' })
|
||||
eq({ 'foo\n', '\nbar', 'baz' }, funcs.getbufline(1, 1, 9999))
|
||||
eq({ 'abc\n', '\ndef', 'ghi' }, funcs.getbufline(2, 1, 9999))
|
||||
eq({ 'foo\n', '\nbar', 'baz' }, funcs.getbufline(1, 1, '$'))
|
||||
eq({ 'baz' }, funcs.getbufline(1, '$', '$'))
|
||||
eq({ 'baz' }, funcs.getbufline(1, '$', 9999))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -230,9 +247,9 @@ describe('getbufvar() function', function()
|
||||
eq(0, funcs.getbufvar(1, '&g:number'))
|
||||
command('new')
|
||||
-- But with window-local options it probably does not what you expect
|
||||
command("setl number")
|
||||
command('setl number')
|
||||
-- (note that current window’s buffer is 2, but getbufvar() receives 1)
|
||||
eq({id=2}, curwinmeths.get_buf())
|
||||
eq({ id = 2 }, curwinmeths.get_buf())
|
||||
eq(1, funcs.getbufvar(1, '&number'))
|
||||
eq(1, funcs.getbufvar(1, '&l:number'))
|
||||
-- You can get global value though, if you find this useful.
|
||||
@@ -240,31 +257,33 @@ describe('getbufvar() function', function()
|
||||
end)
|
||||
it('returns expected variable value', function()
|
||||
eq(2, funcs.getbufvar(1, 'changedtick'))
|
||||
curbufmeths.set_lines(0, 1, false, {'abc\0', '\0def', 'ghi'})
|
||||
curbufmeths.set_lines(0, 1, false, { 'abc\0', '\0def', 'ghi' })
|
||||
eq(3, funcs.getbufvar(1, 'changedtick'))
|
||||
curbufmeths.set_var('test', true)
|
||||
eq(true, funcs.getbufvar(1, 'test'))
|
||||
eq({test=true, changedtick=3}, funcs.getbufvar(1, ''))
|
||||
eq({ test = true, changedtick = 3 }, funcs.getbufvar(1, ''))
|
||||
command('new')
|
||||
eq(3, funcs.getbufvar(1, 'changedtick'))
|
||||
eq(true, funcs.getbufvar(1, 'test'))
|
||||
eq({test=true, changedtick=3}, funcs.getbufvar(1, ''))
|
||||
eq({ test = true, changedtick = 3 }, funcs.getbufvar(1, ''))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('setbufvar() function', function()
|
||||
it('throws the error or ignores the input when buffer was not found', function()
|
||||
command('file ' .. fname)
|
||||
eq(0,
|
||||
exc_exec('call setbufvar(2, "&autoindent", 0)'))
|
||||
eq('Vim(call):E94: No matching buffer for non-existent-buffer',
|
||||
exc_exec('call setbufvar("non-existent-buffer", "&autoindent", 0)'))
|
||||
eq(0,
|
||||
exc_exec('call setbufvar("#", "&autoindent", 0)'))
|
||||
eq(0, exc_exec('call setbufvar(2, "&autoindent", 0)'))
|
||||
eq(
|
||||
'Vim(call):E94: No matching buffer for non-existent-buffer',
|
||||
exc_exec('call setbufvar("non-existent-buffer", "&autoindent", 0)')
|
||||
)
|
||||
eq(0, exc_exec('call setbufvar("#", "&autoindent", 0)'))
|
||||
command('edit ' .. fname2)
|
||||
eq(2, funcs.bufnr('%'))
|
||||
eq('Vim(call):E93: More than one match for X',
|
||||
exc_exec('call setbufvar("X", "&autoindent", 0)'))
|
||||
eq(
|
||||
'Vim(call):E93: More than one match for X',
|
||||
exc_exec('call setbufvar("X", "&autoindent", 0)')
|
||||
)
|
||||
end)
|
||||
it('may set options, including window-local and global values', function()
|
||||
local buf1 = meths.get_current_buf()
|
||||
@@ -274,21 +293,19 @@ describe('setbufvar() function', function()
|
||||
eq(2, bufmeths.get_number(curwinmeths.get_buf()))
|
||||
funcs.setbufvar(1, '&number', true)
|
||||
local windows = curtabmeths.list_wins()
|
||||
eq(false, meths.get_option_value('number', {win=windows[1].id}))
|
||||
eq(true, meths.get_option_value('number', {win=windows[2].id}))
|
||||
eq(false, meths.get_option_value('number', {win=windows[3].id}))
|
||||
eq(false, meths.get_option_value('number', {win=meths.get_current_win().id}))
|
||||
|
||||
eq(false, meths.get_option_value('number', { win = windows[1].id }))
|
||||
eq(true, meths.get_option_value('number', { win = windows[2].id }))
|
||||
eq(false, meths.get_option_value('number', { win = windows[3].id }))
|
||||
eq(false, meths.get_option_value('number', { win = meths.get_current_win().id }))
|
||||
|
||||
eq(true, meths.get_option_value('hidden', {}))
|
||||
funcs.setbufvar(1, '&hidden', 0)
|
||||
eq(false, meths.get_option_value('hidden', {}))
|
||||
|
||||
eq(false, meths.get_option_value('autoindent', {buf=buf1.id}))
|
||||
eq(false, meths.get_option_value('autoindent', { buf = buf1.id }))
|
||||
funcs.setbufvar(1, '&autoindent', true)
|
||||
eq(true, meths.get_option_value('autoindent', {buf=buf1.id}))
|
||||
eq('Vim(call):E355: Unknown option: xxx',
|
||||
exc_exec('call setbufvar(1, "&xxx", 0)'))
|
||||
eq(true, meths.get_option_value('autoindent', { buf = buf1.id }))
|
||||
eq('Vim(call):E355: Unknown option: xxx', exc_exec('call setbufvar(1, "&xxx", 0)'))
|
||||
end)
|
||||
it('may set variables', function()
|
||||
local buf1 = meths.get_current_buf()
|
||||
@@ -297,15 +314,15 @@ describe('setbufvar() function', function()
|
||||
eq(2, curbufmeths.get_number())
|
||||
funcs.setbufvar(1, 'number', true)
|
||||
eq(true, bufmeths.get_var(buf1, 'number'))
|
||||
eq('Vim(call):E461: Illegal variable name: b:',
|
||||
exc_exec('call setbufvar(1, "", 0)'))
|
||||
eq('Vim(call):E461: Illegal variable name: b:', exc_exec('call setbufvar(1, "", 0)'))
|
||||
eq(true, bufmeths.get_var(buf1, 'number'))
|
||||
eq('Vim:E46: Cannot change read-only variable "b:changedtick"',
|
||||
pcall_err(funcs.setbufvar, 1, 'changedtick', true))
|
||||
eq(
|
||||
'Vim:E46: Cannot change read-only variable "b:changedtick"',
|
||||
pcall_err(funcs.setbufvar, 1, 'changedtick', true)
|
||||
)
|
||||
eq(2, funcs.getbufvar(1, 'changedtick'))
|
||||
end)
|
||||
it('throws error when setting a string option to a boolean value vim-patch:9.0.0090', function()
|
||||
eq('Vim:E928: String required',
|
||||
pcall_err(funcs.setbufvar, '', '&errorformat', true))
|
||||
eq('Vim:E928: String required', pcall_err(funcs.setbufvar, '', '&errorformat', true))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -29,7 +29,7 @@ end
|
||||
|
||||
describe('b:changedtick', function()
|
||||
-- Ported tests from Vim-8.0.333
|
||||
it('increments', function() -- Test_changedtick_increments
|
||||
it('increments', function() -- Test_changedtick_increments
|
||||
-- New buffer has an empty line, tick starts at 2
|
||||
eq(2, changedtick())
|
||||
funcs.setline(1, 'hello')
|
||||
@@ -56,35 +56,55 @@ describe('b:changedtick', function()
|
||||
local ct = changedtick()
|
||||
local ctn = ct + 100500
|
||||
eq(0, exc_exec('let d = b:'))
|
||||
eq('Vim(let):E46: Cannot change read-only variable "b:changedtick"',
|
||||
pcall_err(command, 'let b:changedtick = ' .. ctn))
|
||||
eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] = ' .. ctn))
|
||||
eq('Vim(let):E46: Cannot change read-only variable "b:.changedtick"',
|
||||
pcall_err(command, 'let b:.changedtick = ' .. ctn))
|
||||
eq('Vim(let):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'let d.changedtick = ' .. ctn))
|
||||
eq('Key is read-only: changedtick',
|
||||
pcall_err(curbufmeths.set_var, 'changedtick', ctn))
|
||||
eq(
|
||||
'Vim(let):E46: Cannot change read-only variable "b:changedtick"',
|
||||
pcall_err(command, 'let b:changedtick = ' .. ctn)
|
||||
)
|
||||
eq(
|
||||
'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] = ' .. ctn)
|
||||
)
|
||||
eq(
|
||||
'Vim(let):E46: Cannot change read-only variable "b:.changedtick"',
|
||||
pcall_err(command, 'let b:.changedtick = ' .. ctn)
|
||||
)
|
||||
eq(
|
||||
'Vim(let):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'let d.changedtick = ' .. ctn)
|
||||
)
|
||||
eq('Key is read-only: changedtick', pcall_err(curbufmeths.set_var, 'changedtick', ctn))
|
||||
|
||||
eq('Vim(unlet):E795: Cannot delete variable b:changedtick',
|
||||
pcall_err(command, 'unlet b:changedtick'))
|
||||
eq('Vim(unlet):E46: Cannot change read-only variable "b:.changedtick"',
|
||||
pcall_err(command, 'unlet b:.changedtick'))
|
||||
eq('Vim(unlet):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'unlet b:["changedtick"]'))
|
||||
eq('Vim(unlet):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'unlet d.changedtick'))
|
||||
eq('Key is read-only: changedtick',
|
||||
pcall_err(curbufmeths.del_var, 'changedtick'))
|
||||
eq(
|
||||
'Vim(unlet):E795: Cannot delete variable b:changedtick',
|
||||
pcall_err(command, 'unlet b:changedtick')
|
||||
)
|
||||
eq(
|
||||
'Vim(unlet):E46: Cannot change read-only variable "b:.changedtick"',
|
||||
pcall_err(command, 'unlet b:.changedtick')
|
||||
)
|
||||
eq(
|
||||
'Vim(unlet):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'unlet b:["changedtick"]')
|
||||
)
|
||||
eq(
|
||||
'Vim(unlet):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'unlet d.changedtick')
|
||||
)
|
||||
eq('Key is read-only: changedtick', pcall_err(curbufmeths.del_var, 'changedtick'))
|
||||
eq(ct, changedtick())
|
||||
|
||||
eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] += ' .. ctn))
|
||||
eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] -= ' .. ctn))
|
||||
eq('Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] .= ' .. ctn))
|
||||
eq(
|
||||
'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] += ' .. ctn)
|
||||
)
|
||||
eq(
|
||||
'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] -= ' .. ctn)
|
||||
)
|
||||
eq(
|
||||
'Vim(let):E46: Cannot change read-only variable "b:["changedtick"]"',
|
||||
pcall_err(command, 'let b:["changedtick"] .= ' .. ctn)
|
||||
)
|
||||
|
||||
eq(ct, changedtick())
|
||||
|
||||
@@ -99,16 +119,24 @@ describe('b:changedtick', function()
|
||||
eq(0, exc_exec('let d = b:'))
|
||||
eq(0, funcs.islocked('b:changedtick'))
|
||||
eq(0, funcs.islocked('d.changedtick'))
|
||||
eq('Vim(unlockvar):E940: Cannot lock or unlock variable b:changedtick',
|
||||
pcall_err(command, 'unlockvar b:changedtick'))
|
||||
eq('Vim(unlockvar):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'unlockvar d.changedtick'))
|
||||
eq(
|
||||
'Vim(unlockvar):E940: Cannot lock or unlock variable b:changedtick',
|
||||
pcall_err(command, 'unlockvar b:changedtick')
|
||||
)
|
||||
eq(
|
||||
'Vim(unlockvar):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'unlockvar d.changedtick')
|
||||
)
|
||||
eq(0, funcs.islocked('b:changedtick'))
|
||||
eq(0, funcs.islocked('d.changedtick'))
|
||||
eq('Vim(lockvar):E940: Cannot lock or unlock variable b:changedtick',
|
||||
pcall_err(command, 'lockvar b:changedtick'))
|
||||
eq('Vim(lockvar):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'lockvar d.changedtick'))
|
||||
eq(
|
||||
'Vim(lockvar):E940: Cannot lock or unlock variable b:changedtick',
|
||||
pcall_err(command, 'lockvar b:changedtick')
|
||||
)
|
||||
eq(
|
||||
'Vim(lockvar):E46: Cannot change read-only variable "d.changedtick"',
|
||||
pcall_err(command, 'lockvar d.changedtick')
|
||||
)
|
||||
eq(0, funcs.islocked('b:changedtick'))
|
||||
eq(0, funcs.islocked('d.changedtick'))
|
||||
end)
|
||||
@@ -118,18 +146,26 @@ describe('b:changedtick', function()
|
||||
end)
|
||||
it('cannot be changed by filter() or map()', function()
|
||||
eq(2, changedtick())
|
||||
eq('Vim(call):E795: Cannot delete variable filter() argument',
|
||||
pcall_err(command, 'call filter(b:, 0)'))
|
||||
eq('Vim(call):E742: Cannot change value of map() argument',
|
||||
pcall_err(command, 'call map(b:, 0)'))
|
||||
eq('Vim(call):E742: Cannot change value of map() argument',
|
||||
pcall_err(command, 'call map(b:, "v:val")'))
|
||||
eq(
|
||||
'Vim(call):E795: Cannot delete variable filter() argument',
|
||||
pcall_err(command, 'call filter(b:, 0)')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E742: Cannot change value of map() argument',
|
||||
pcall_err(command, 'call map(b:, 0)')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E742: Cannot change value of map() argument',
|
||||
pcall_err(command, 'call map(b:, "v:val")')
|
||||
)
|
||||
eq(2, changedtick())
|
||||
end)
|
||||
it('cannot be remove()d', function()
|
||||
eq(2, changedtick())
|
||||
eq('Vim(call):E795: Cannot delete variable remove() argument',
|
||||
pcall_err(command, 'call remove(b:, "changedtick")'))
|
||||
eq(
|
||||
'Vim(call):E795: Cannot delete variable remove() argument',
|
||||
pcall_err(command, 'call remove(b:, "changedtick")')
|
||||
)
|
||||
eq(2, changedtick())
|
||||
end)
|
||||
it('does not inherit VAR_FIXED when copying dictionary over', function()
|
||||
|
||||
@@ -9,16 +9,16 @@ before_each(clear)
|
||||
|
||||
describe('extend()', 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'))
|
||||
meths.set_var('l', { 1, {} })
|
||||
eq({ 1, {}, 1, {} }, eval('extend(l, l)'))
|
||||
eq({ 1, {}, 1, {} }, meths.get_var('l'))
|
||||
|
||||
meths.set_var('l', {1, {}})
|
||||
eq({1, {}, 1, {}}, eval('extend(l, l, 0)'))
|
||||
eq({1, {}, 1, {}}, meths.get_var('l'))
|
||||
meths.set_var('l', { 1, {} })
|
||||
eq({ 1, {}, 1, {} }, eval('extend(l, l, 0)'))
|
||||
eq({ 1, {}, 1, {} }, meths.get_var('l'))
|
||||
|
||||
meths.set_var('l', {1, {}})
|
||||
eq({1, 1, {}, {}}, eval('extend(l, l, 1)'))
|
||||
eq({1, 1, {}, {}}, meths.get_var('l'))
|
||||
meths.set_var('l', { 1, {} })
|
||||
eq({ 1, 1, {}, {} }, eval('extend(l, l, 1)'))
|
||||
eq({ 1, 1, {}, {} }, meths.get_var('l'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -18,13 +18,12 @@ local pcall_err = helpers.pcall_err
|
||||
describe('context functions', function()
|
||||
local fname1 = 'Xtest-functional-eval-ctx1'
|
||||
local fname2 = 'Xtest-functional-eval-ctx2'
|
||||
local outofbounds =
|
||||
'Vim:E475: Invalid value for argument index: out of bounds'
|
||||
local outofbounds = 'Vim:E475: Invalid value for argument index: out of bounds'
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
write_file(fname1, "1\n2\n3")
|
||||
write_file(fname2, "a\nb\nc")
|
||||
write_file(fname1, '1\n2\n3')
|
||||
write_file(fname2, 'a\nb\nc')
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
@@ -34,78 +33,105 @@ describe('context functions', function()
|
||||
|
||||
describe('ctxpush/ctxpop', function()
|
||||
it('saves and restores registers properly', function()
|
||||
local regs = {'1', '2', '3', 'a'}
|
||||
local vals = {'1', '2', '3', 'hjkl'}
|
||||
local regs = { '1', '2', '3', 'a' }
|
||||
local vals = { '1', '2', '3', 'hjkl' }
|
||||
feed('i1<cr>2<cr>3<c-[>ddddddqahjklq')
|
||||
eq(vals, map(function(r) return trim(call('getreg', r)) end, regs))
|
||||
eq(
|
||||
vals,
|
||||
map(function(r)
|
||||
return trim(call('getreg', r))
|
||||
end, regs)
|
||||
)
|
||||
call('ctxpush')
|
||||
call('ctxpush', {'regs'})
|
||||
call('ctxpush', { 'regs' })
|
||||
|
||||
map(function(r) call('setreg', r, {}) end, regs)
|
||||
eq({'', '', '', ''},
|
||||
map(function(r) return trim(call('getreg', r)) end, regs))
|
||||
map(function(r)
|
||||
call('setreg', r, {})
|
||||
end, regs)
|
||||
eq(
|
||||
{ '', '', '', '' },
|
||||
map(function(r)
|
||||
return trim(call('getreg', r))
|
||||
end, regs)
|
||||
)
|
||||
|
||||
call('ctxpop')
|
||||
eq(vals, map(function(r) return trim(call('getreg', r)) end, regs))
|
||||
eq(
|
||||
vals,
|
||||
map(function(r)
|
||||
return trim(call('getreg', r))
|
||||
end, regs)
|
||||
)
|
||||
|
||||
map(function(r) call('setreg', r, {}) end, regs)
|
||||
eq({'', '', '', ''},
|
||||
map(function(r) return trim(call('getreg', r)) end, regs))
|
||||
map(function(r)
|
||||
call('setreg', r, {})
|
||||
end, regs)
|
||||
eq(
|
||||
{ '', '', '', '' },
|
||||
map(function(r)
|
||||
return trim(call('getreg', r))
|
||||
end, regs)
|
||||
)
|
||||
|
||||
call('ctxpop')
|
||||
eq(vals, map(function(r) return trim(call('getreg', r)) end, regs))
|
||||
eq(
|
||||
vals,
|
||||
map(function(r)
|
||||
return trim(call('getreg', r))
|
||||
end, regs)
|
||||
)
|
||||
end)
|
||||
|
||||
it('saves and restores jumplist properly', function()
|
||||
command('edit '..fname1)
|
||||
command('edit ' .. fname1)
|
||||
feed('G')
|
||||
feed('gg')
|
||||
command('edit '..fname2)
|
||||
command('edit ' .. fname2)
|
||||
local jumplist = call('getjumplist')
|
||||
call('ctxpush')
|
||||
call('ctxpush', {'jumps'})
|
||||
call('ctxpush', { 'jumps' })
|
||||
|
||||
command('clearjumps')
|
||||
eq({{}, 0}, call('getjumplist'))
|
||||
eq({ {}, 0 }, call('getjumplist'))
|
||||
|
||||
call('ctxpop')
|
||||
eq(jumplist, call('getjumplist'))
|
||||
|
||||
command('clearjumps')
|
||||
eq({{}, 0}, call('getjumplist'))
|
||||
eq({ {}, 0 }, call('getjumplist'))
|
||||
|
||||
call('ctxpop')
|
||||
eq(jumplist, call('getjumplist'))
|
||||
end)
|
||||
|
||||
it('saves and restores buffer list properly', function()
|
||||
command('edit '..fname1)
|
||||
command('edit '..fname2)
|
||||
command('edit ' .. fname1)
|
||||
command('edit ' .. fname2)
|
||||
command('edit TEST')
|
||||
local bufs = call('map', call('getbufinfo'), 'v:val.name')
|
||||
call('ctxpush')
|
||||
call('ctxpush', {'bufs'})
|
||||
call('ctxpush', { 'bufs' })
|
||||
|
||||
command('%bwipeout')
|
||||
eq({''}, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
eq({ '' }, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
|
||||
call('ctxpop')
|
||||
eq({'', unpack(bufs)}, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
eq({ '', unpack(bufs) }, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
|
||||
command('%bwipeout')
|
||||
eq({''}, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
eq({ '' }, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
|
||||
call('ctxpop')
|
||||
eq({'', unpack(bufs)}, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
eq({ '', unpack(bufs) }, call('map', call('getbufinfo'), 'v:val.name'))
|
||||
end)
|
||||
|
||||
it('saves and restores global variables properly', function()
|
||||
nvim('set_var', 'one', 1)
|
||||
nvim('set_var', 'Two', 2)
|
||||
nvim('set_var', 'THREE', 3)
|
||||
eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]'))
|
||||
call('ctxpush')
|
||||
call('ctxpush', {'gvars'})
|
||||
call('ctxpush', { 'gvars' })
|
||||
|
||||
nvim('del_var', 'one')
|
||||
nvim('del_var', 'Two')
|
||||
@@ -115,7 +141,7 @@ describe('context functions', function()
|
||||
eq('Vim:E121: Undefined variable: g:THREE', pcall_err(eval, 'g:THREE'))
|
||||
|
||||
call('ctxpop')
|
||||
eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]'))
|
||||
|
||||
nvim('del_var', 'one')
|
||||
nvim('del_var', 'Two')
|
||||
@@ -125,7 +151,7 @@ describe('context functions', function()
|
||||
eq('Vim:E121: Undefined variable: g:THREE', pcall_err(eval, 'g:THREE'))
|
||||
|
||||
call('ctxpop')
|
||||
eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]'))
|
||||
end)
|
||||
|
||||
it('saves and restores script functions properly', function()
|
||||
@@ -164,28 +190,30 @@ describe('context functions', function()
|
||||
]])
|
||||
|
||||
eq('Hello, World!', exec_capture([[call Greet('World')]]))
|
||||
eq('Hello, World!'..
|
||||
'\nHello, One!'..
|
||||
'\nHello, Two!'..
|
||||
'\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]))
|
||||
eq(
|
||||
'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])
|
||||
)
|
||||
|
||||
call('SaveSFuncs')
|
||||
call('DeleteSFuncs')
|
||||
|
||||
eq('function Greet, line 1: Vim(call):E117: Unknown function: s:greet',
|
||||
pcall_err(command, [[call Greet('World')]]))
|
||||
eq('function GreetAll, line 1: Vim(call):E117: Unknown function: s:greet_all',
|
||||
pcall_err(command, [[call GreetAll('World', 'One', 'Two', 'Three')]]))
|
||||
eq(
|
||||
'function Greet, line 1: Vim(call):E117: Unknown function: s:greet',
|
||||
pcall_err(command, [[call Greet('World')]])
|
||||
)
|
||||
eq(
|
||||
'function GreetAll, line 1: Vim(call):E117: Unknown function: s:greet_all',
|
||||
pcall_err(command, [[call GreetAll('World', 'One', 'Two', 'Three')]])
|
||||
)
|
||||
|
||||
call('RestoreFuncs')
|
||||
|
||||
eq('Hello, World!', exec_capture([[call Greet('World')]]))
|
||||
eq('Hello, World!'..
|
||||
'\nHello, One!'..
|
||||
'\nHello, Two!'..
|
||||
'\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]))
|
||||
eq(
|
||||
'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])
|
||||
)
|
||||
end)
|
||||
|
||||
it('saves and restores functions properly', function()
|
||||
@@ -203,28 +231,28 @@ describe('context functions', function()
|
||||
]])
|
||||
|
||||
eq('Hello, World!', exec_capture([[call Greet('World')]]))
|
||||
eq('Hello, World!'..
|
||||
'\nHello, One!'..
|
||||
'\nHello, Two!'..
|
||||
'\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]))
|
||||
eq(
|
||||
'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])
|
||||
)
|
||||
|
||||
call('ctxpush', {'funcs'})
|
||||
call('ctxpush', { 'funcs' })
|
||||
command('delfunction Greet')
|
||||
command('delfunction GreetAll')
|
||||
|
||||
eq('Vim:E117: Unknown function: Greet', pcall_err(call, 'Greet', 'World'))
|
||||
eq('Vim:E117: Unknown function: GreetAll',
|
||||
pcall_err(call, 'GreetAll', 'World', 'One', 'Two', 'Three'))
|
||||
eq(
|
||||
'Vim:E117: Unknown function: GreetAll',
|
||||
pcall_err(call, 'GreetAll', 'World', 'One', 'Two', 'Three')
|
||||
)
|
||||
|
||||
call('ctxpop')
|
||||
|
||||
eq('Hello, World!', exec_capture([[call Greet('World')]]))
|
||||
eq('Hello, World!'..
|
||||
'\nHello, One!'..
|
||||
'\nHello, Two!'..
|
||||
'\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]]))
|
||||
eq(
|
||||
'Hello, World!' .. '\nHello, One!' .. '\nHello, Two!' .. '\nHello, Three!',
|
||||
exec_capture([[call GreetAll('World', 'One', 'Two', 'Three')]])
|
||||
)
|
||||
end)
|
||||
|
||||
it('errors out when context stack is empty', function()
|
||||
@@ -268,21 +296,21 @@ describe('context functions', function()
|
||||
|
||||
it('returns context dictionary at index in context stack', function()
|
||||
feed('i1<cr>2<cr>3<c-[>ddddddqahjklq')
|
||||
command('edit! '..fname1)
|
||||
command('edit! ' .. fname1)
|
||||
feed('G')
|
||||
feed('gg')
|
||||
command('edit '..fname2)
|
||||
command('edit ' .. fname2)
|
||||
nvim('set_var', 'one', 1)
|
||||
nvim('set_var', 'Two', 2)
|
||||
nvim('set_var', 'THREE', 3)
|
||||
|
||||
local with_regs = {
|
||||
['regs'] = {
|
||||
{['rt'] = 1, ['rc'] = {'1'}, ['n'] = 49, ['ru'] = true},
|
||||
{['rt'] = 1, ['rc'] = {'2'}, ['n'] = 50},
|
||||
{['rt'] = 1, ['rc'] = {'3'}, ['n'] = 51},
|
||||
{['rc'] = {'hjkl'}, ['n'] = 97},
|
||||
}
|
||||
{ ['rt'] = 1, ['rc'] = { '1' }, ['n'] = 49, ['ru'] = true },
|
||||
{ ['rt'] = 1, ['rc'] = { '2' }, ['n'] = 50 },
|
||||
{ ['rt'] = 1, ['rc'] = { '3' }, ['n'] = 51 },
|
||||
{ ['rc'] = { 'hjkl' }, ['n'] = 97 },
|
||||
},
|
||||
}
|
||||
|
||||
local with_jumps = {
|
||||
@@ -292,17 +320,17 @@ describe('context functions', function()
|
||||
'filter(
|
||||
{ "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
|
||||
{ k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
|
||||
]]):gsub('\n', ''))
|
||||
]]):gsub('\n', '')),
|
||||
}
|
||||
|
||||
local with_bufs = {
|
||||
['bufs'] = eval([[
|
||||
filter(map(getbufinfo(), '{ "f": v:val.name }'), '!empty(v:val.f)')
|
||||
]])
|
||||
]]),
|
||||
}
|
||||
|
||||
local with_gvars = {
|
||||
['gvars'] = {{'one', 1}, {'Two', 2}, {'THREE', 3}}
|
||||
['gvars'] = { { 'one', 1 }, { 'Two', 2 }, { 'THREE', 3 } },
|
||||
}
|
||||
|
||||
local with_all = {
|
||||
@@ -316,25 +344,25 @@ describe('context functions', function()
|
||||
eq(with_all, parse_context(call('ctxget')))
|
||||
eq(with_all, parse_context(call('ctxget', 0)))
|
||||
|
||||
call('ctxpush', {'gvars'})
|
||||
call('ctxpush', { 'gvars' })
|
||||
eq(with_gvars, parse_context(call('ctxget')))
|
||||
eq(with_gvars, parse_context(call('ctxget', 0)))
|
||||
eq(with_all, parse_context(call('ctxget', 1)))
|
||||
|
||||
call('ctxpush', {'bufs'})
|
||||
call('ctxpush', { 'bufs' })
|
||||
eq(with_bufs, parse_context(call('ctxget')))
|
||||
eq(with_bufs, parse_context(call('ctxget', 0)))
|
||||
eq(with_gvars, parse_context(call('ctxget', 1)))
|
||||
eq(with_all, parse_context(call('ctxget', 2)))
|
||||
|
||||
call('ctxpush', {'jumps'})
|
||||
call('ctxpush', { 'jumps' })
|
||||
eq(with_jumps, parse_context(call('ctxget')))
|
||||
eq(with_jumps, parse_context(call('ctxget', 0)))
|
||||
eq(with_bufs, parse_context(call('ctxget', 1)))
|
||||
eq(with_gvars, parse_context(call('ctxget', 2)))
|
||||
eq(with_all, parse_context(call('ctxget', 3)))
|
||||
|
||||
call('ctxpush', {'regs'})
|
||||
call('ctxpush', { 'regs' })
|
||||
eq(with_regs, parse_context(call('ctxget')))
|
||||
eq(with_regs, parse_context(call('ctxget', 0)))
|
||||
eq(with_jumps, parse_context(call('ctxget', 1)))
|
||||
@@ -368,17 +396,19 @@ describe('context functions', function()
|
||||
|
||||
describe('ctxset()', function()
|
||||
it('errors out when index is out of bounds', function()
|
||||
eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}))
|
||||
eq(outofbounds, pcall_err(call, 'ctxset', { dummy = 1 }))
|
||||
call('ctxpush')
|
||||
eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 1))
|
||||
eq(outofbounds, pcall_err(call, 'ctxset', { dummy = 1 }, 1))
|
||||
call('ctxpop')
|
||||
eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 0))
|
||||
eq(outofbounds, pcall_err(call, 'ctxset', { dummy = 1 }, 0))
|
||||
end)
|
||||
|
||||
it('errors when context dictionary is invalid', function()
|
||||
call('ctxpush')
|
||||
eq('Vim:E474: Failed to convert list to msgpack string buffer',
|
||||
pcall_err(call, 'ctxset', { regs = { {} }, jumps = { {} } }))
|
||||
eq(
|
||||
'Vim:E474: Failed to convert list to msgpack string buffer',
|
||||
pcall_err(call, 'ctxset', { regs = { {} }, jumps = { {} } })
|
||||
)
|
||||
end)
|
||||
|
||||
it('sets context dictionary at index in context stack', function()
|
||||
@@ -394,17 +424,17 @@ describe('context functions', function()
|
||||
call('ctxpush')
|
||||
local ctx2 = call('ctxget')
|
||||
|
||||
eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 'a', 'b', 'c' }, eval('[g:one, g:Two, g:THREE]'))
|
||||
call('ctxset', ctx1)
|
||||
call('ctxset', ctx2, 2)
|
||||
call('ctxpop')
|
||||
eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 1, 2, 3 }, eval('[g:one, g:Two, g:THREE]'))
|
||||
call('ctxpop')
|
||||
eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 'a', 'b', 'c' }, eval('[g:one, g:Two, g:THREE]'))
|
||||
nvim('set_var', 'one', 1.5)
|
||||
eq({1.5, 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 1.5, 'b', 'c' }, eval('[g:one, g:Two, g:THREE]'))
|
||||
call('ctxpop')
|
||||
eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
|
||||
eq({ 'a', 'b', 'c' }, eval('[g:one, g:Two, g:THREE]'))
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -11,13 +11,13 @@ local setenv = helpers.funcs.setenv
|
||||
|
||||
describe('environment variables', function()
|
||||
it('environ() handles empty env variable', function()
|
||||
clear({env={EMPTY_VAR=""}})
|
||||
eq("", environ()['EMPTY_VAR'])
|
||||
clear({ env = { EMPTY_VAR = '' } })
|
||||
eq('', environ()['EMPTY_VAR'])
|
||||
eq(nil, environ()['DOES_NOT_EXIST'])
|
||||
end)
|
||||
|
||||
it('exists() handles empty env variable', function()
|
||||
clear({env={EMPTY_VAR=""}})
|
||||
clear({ env = { EMPTY_VAR = '' } })
|
||||
eq(1, exists('$EMPTY_VAR'))
|
||||
eq(0, exists('$DOES_NOT_EXIST'))
|
||||
end)
|
||||
@@ -46,23 +46,32 @@ describe('empty $HOME', function()
|
||||
end
|
||||
|
||||
local function write_and_test_tilde()
|
||||
system({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
|
||||
'-c', 'write test_empty_home', '+q'})
|
||||
system({
|
||||
nvim_prog,
|
||||
'-u',
|
||||
'NONE',
|
||||
'-i',
|
||||
'NONE',
|
||||
'--headless',
|
||||
'-c',
|
||||
'write test_empty_home',
|
||||
'+q',
|
||||
})
|
||||
eq(false, tilde_in_cwd())
|
||||
end
|
||||
|
||||
it("'~' folder not created in cwd if $HOME and related env not defined", function()
|
||||
command("unlet $HOME")
|
||||
command('unlet $HOME')
|
||||
write_and_test_tilde()
|
||||
|
||||
command("let $HOMEDRIVE='C:'")
|
||||
command("let $USERPROFILE='C:\\'")
|
||||
write_and_test_tilde()
|
||||
|
||||
command("unlet $HOMEDRIVE")
|
||||
command('unlet $HOMEDRIVE')
|
||||
write_and_test_tilde()
|
||||
|
||||
command("unlet $USERPROFILE")
|
||||
command('unlet $USERPROFILE')
|
||||
write_and_test_tilde()
|
||||
|
||||
command("let $HOME='%USERPROFILE%'")
|
||||
|
||||
@@ -24,10 +24,10 @@ describe('setqflist()', function()
|
||||
end)
|
||||
|
||||
it('sets w:quickfix_title', function()
|
||||
setqflist({''}, 'r', 'foo')
|
||||
setqflist({ '' }, 'r', 'foo')
|
||||
command('copen')
|
||||
eq('foo', get_cur_win_var('quickfix_title'))
|
||||
setqflist({}, 'r', {['title'] = 'qf_title'})
|
||||
setqflist({}, 'r', { ['title'] = 'qf_title' })
|
||||
eq('qf_title', get_cur_win_var('quickfix_title'))
|
||||
end)
|
||||
|
||||
@@ -38,7 +38,10 @@ describe('setqflist()', function()
|
||||
end)
|
||||
|
||||
it('requires a dict for {what}', function()
|
||||
eq('Vim(call):E715: Dictionary required', exc_exec('call setqflist([], "r", function("function"))'))
|
||||
eq(
|
||||
'Vim(call):E715: Dictionary required',
|
||||
exc_exec('call setqflist([], "r", function("function"))')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -73,11 +76,11 @@ describe('setloclist()', function()
|
||||
helpers.insert([[
|
||||
hello world]])
|
||||
|
||||
command("vsplit")
|
||||
command("autocmd WinLeave * :call nvim_win_close(0, v:true)")
|
||||
command('vsplit')
|
||||
command('autocmd WinLeave * :call nvim_win_close(0, v:true)')
|
||||
|
||||
command("call setloclist(0, [])")
|
||||
command("lopen")
|
||||
command('call setloclist(0, [])')
|
||||
command('lopen')
|
||||
|
||||
helpers.assert_alive()
|
||||
end)
|
||||
|
||||
@@ -32,7 +32,7 @@ local feed = helpers.feed
|
||||
local expect_exit = helpers.expect_exit
|
||||
|
||||
describe('Up to MAX_FUNC_ARGS arguments are handled by', function()
|
||||
local max_func_args = 20 -- from eval.h
|
||||
local max_func_args = 20 -- from eval.h
|
||||
local range = helpers.funcs.range
|
||||
|
||||
before_each(clear)
|
||||
@@ -41,7 +41,7 @@ describe('Up to MAX_FUNC_ARGS arguments are handled by', function()
|
||||
local printf = helpers.funcs.printf
|
||||
local rep = helpers.funcs['repeat']
|
||||
local expected = '2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,'
|
||||
eq(expected, printf(rep('%d,', max_func_args-1), unpack(range(2, max_func_args))))
|
||||
eq(expected, printf(rep('%d,', max_func_args - 1), unpack(range(2, max_func_args))))
|
||||
local ret = exc_exec('call printf("", 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)')
|
||||
eq('Vim(call):E740: Too many arguments for function printf', ret)
|
||||
end)
|
||||
@@ -55,15 +55,15 @@ describe('Up to MAX_FUNC_ARGS arguments are handled by', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("backtick expansion", function()
|
||||
describe('backtick expansion', function()
|
||||
setup(function()
|
||||
clear()
|
||||
mkdir("test-backticks")
|
||||
write_file("test-backticks/file1", "test file 1")
|
||||
write_file("test-backticks/file2", "test file 2")
|
||||
write_file("test-backticks/file3", "test file 3")
|
||||
mkdir("test-backticks/subdir")
|
||||
write_file("test-backticks/subdir/file4", "test file 4")
|
||||
mkdir('test-backticks')
|
||||
write_file('test-backticks/file1', 'test file 1')
|
||||
write_file('test-backticks/file2', 'test file 2')
|
||||
write_file('test-backticks/file3', 'test file 3')
|
||||
mkdir('test-backticks/subdir')
|
||||
write_file('test-backticks/subdir/file4', 'test file 4')
|
||||
-- Long path might cause "Press ENTER" prompt; use :silent to avoid it.
|
||||
command('silent cd test-backticks')
|
||||
end)
|
||||
@@ -74,30 +74,30 @@ describe("backtick expansion", function()
|
||||
|
||||
it("with default 'shell'", function()
|
||||
if helpers.is_os('win') then
|
||||
command(":silent args `dir /b *2`")
|
||||
command(':silent args `dir /b *2`')
|
||||
else
|
||||
command(":silent args `echo ***2`")
|
||||
command(':silent args `echo ***2`')
|
||||
end
|
||||
eq({ "file2", }, eval("argv()"))
|
||||
eq({ 'file2' }, eval('argv()'))
|
||||
if helpers.is_os('win') then
|
||||
command(":silent args `dir /s/b *4`")
|
||||
eq({ "subdir\\file4", }, eval("map(argv(), 'fnamemodify(v:val, \":.\")')"))
|
||||
command(':silent args `dir /s/b *4`')
|
||||
eq({ 'subdir\\file4' }, eval('map(argv(), \'fnamemodify(v:val, ":.")\')'))
|
||||
else
|
||||
command(":silent args `echo */*4`")
|
||||
eq({ "subdir/file4", }, eval("argv()"))
|
||||
command(':silent args `echo */*4`')
|
||||
eq({ 'subdir/file4' }, eval('argv()'))
|
||||
end
|
||||
end)
|
||||
|
||||
it("with shell=fish", function()
|
||||
it('with shell=fish', function()
|
||||
if eval("executable('fish')") == 0 then
|
||||
pending('missing "fish" command')
|
||||
return
|
||||
end
|
||||
command("set shell=fish")
|
||||
command(":silent args `echo ***2`")
|
||||
eq({ "file2", }, eval("argv()"))
|
||||
command(":silent args `echo */*4`")
|
||||
eq({ "subdir/file4", }, eval("argv()"))
|
||||
command('set shell=fish')
|
||||
command(':silent args `echo ***2`')
|
||||
eq({ 'file2' }, eval('argv()'))
|
||||
command(':silent args `echo */*4`')
|
||||
eq({ 'subdir/file4' }, eval('argv()'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -106,7 +106,9 @@ describe('List support code', function()
|
||||
local min_dur = 8
|
||||
local len = 131072
|
||||
|
||||
if not pending('does not actually allows interrupting with just got_int', function() end) then return end
|
||||
if not pending('does not actually allows interrupting with just got_int', function() end) then
|
||||
return
|
||||
end
|
||||
-- The following tests are confirmed to work with os_breakcheck() just before
|
||||
-- `if (got_int) {break;}` in tv_list_copy and list_join_inner() and not to
|
||||
-- work without.
|
||||
@@ -153,7 +155,7 @@ describe('List support code', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("uncaught exception", function()
|
||||
describe('uncaught exception', function()
|
||||
before_each(clear)
|
||||
|
||||
it('is not forgotten #13490', function()
|
||||
@@ -164,11 +166,14 @@ describe("uncaught exception", function()
|
||||
-- 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', ([[
|
||||
write_file(
|
||||
'throw' .. i .. '.vim',
|
||||
([[
|
||||
let result ..= '%d'
|
||||
throw 'throw%d'
|
||||
let result ..= 'X'
|
||||
]]):format(i, i))
|
||||
]]):format(i, i)
|
||||
)
|
||||
end
|
||||
finally(function()
|
||||
for i = 1, 3 do
|
||||
@@ -184,9 +189,9 @@ describe("uncaught exception", function()
|
||||
it('multiline exception remains multiline #25350', function()
|
||||
local screen = Screen.new(80, 11)
|
||||
screen:set_default_attr_ids({
|
||||
[1] = {bold = true, reverse = true}; -- MsgSeparator
|
||||
[2] = {foreground = Screen.colors.White, background = Screen.colors.Red}; -- ErrorMsg
|
||||
[3] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg
|
||||
[1] = { bold = true, reverse = true }, -- MsgSeparator
|
||||
[2] = { foreground = Screen.colors.White, background = Screen.colors.Red }, -- ErrorMsg
|
||||
[3] = { bold = true, foreground = Screen.colors.SeaGreen }, -- MoreMsg
|
||||
})
|
||||
screen:attach()
|
||||
exec_lua([[
|
||||
@@ -195,7 +200,8 @@ describe("uncaught exception", function()
|
||||
end
|
||||
]])
|
||||
feed(':try\rlua _G.Oops()\rendtry\r')
|
||||
screen:expect{grid=[[
|
||||
screen:expect {
|
||||
grid = [[
|
||||
{1: }|
|
||||
:try |
|
||||
: lua _G.Oops() |
|
||||
@@ -207,7 +213,8 @@ describe("uncaught exception", function()
|
||||
{2: [string "<nvim>"]:2: in function 'Oops'} |
|
||||
{2: [string ":lua"]:1: in main chunk} |
|
||||
{3:Press ENTER or type command to continue}^ |
|
||||
]]}
|
||||
]],
|
||||
}
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -217,16 +224,23 @@ describe('listing functions using :function', function()
|
||||
it('works for lambda functions with <lambda> #20466', function()
|
||||
command('let A = {-> 1}')
|
||||
local num = exec_capture('echo A'):match("function%('<lambda>(%d+)'%)")
|
||||
eq(([[
|
||||
eq(
|
||||
([[
|
||||
function <lambda>%s(...)
|
||||
1 return 1
|
||||
endfunction]]):format(num), exec_capture(('function <lambda>%s'):format(num)))
|
||||
endfunction]]):format(num),
|
||||
exec_capture(('function <lambda>%s'):format(num))
|
||||
)
|
||||
end)
|
||||
|
||||
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, [=[
|
||||
matches(
|
||||
'Vim%(function%):E454: Function list was modified$',
|
||||
pcall_err(
|
||||
exec_lua,
|
||||
[=[
|
||||
vim.cmd([[
|
||||
func Func1()
|
||||
endfunc
|
||||
@@ -247,14 +261,20 @@ describe('listing functions using :function', function()
|
||||
vim.cmd('function')
|
||||
|
||||
vim.ui_detach(ns)
|
||||
]=]))
|
||||
]=]
|
||||
)
|
||||
)
|
||||
assert_alive()
|
||||
end)
|
||||
|
||||
it('does not crash if the same 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, [=[
|
||||
matches(
|
||||
'Vim%(function%):E454: Function list was modified$',
|
||||
pcall_err(
|
||||
exec_lua,
|
||||
[=[
|
||||
vim.cmd([[
|
||||
func Func1()
|
||||
endfunc
|
||||
@@ -275,7 +295,9 @@ describe('listing functions using :function', function()
|
||||
vim.cmd('function')
|
||||
|
||||
vim.ui_detach(ns)
|
||||
]=]))
|
||||
]=]
|
||||
)
|
||||
)
|
||||
assert_alive()
|
||||
end)
|
||||
end)
|
||||
@@ -283,7 +305,9 @@ end)
|
||||
it('no double-free in garbage collection #16287', function()
|
||||
clear()
|
||||
-- Don't use exec() here as using a named script reproduces the issue better.
|
||||
write_file('Xgarbagecollect.vim', [[
|
||||
write_file(
|
||||
'Xgarbagecollect.vim',
|
||||
[[
|
||||
func Foo() abort
|
||||
let s:args = [a:000]
|
||||
let foo0 = ""
|
||||
@@ -306,7 +330,8 @@ it('no double-free in garbage collection #16287', function()
|
||||
set updatetime=1
|
||||
call Foo()
|
||||
call Foo()
|
||||
]])
|
||||
]]
|
||||
)
|
||||
finally(function()
|
||||
os.remove('Xgarbagecollect.vim')
|
||||
end)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local eq, clear, call, write_file, command =
|
||||
helpers.eq, helpers.clear, helpers.call, helpers.write_file,
|
||||
helpers.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
|
||||
@@ -21,9 +20,15 @@ describe('executable()', function()
|
||||
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'), ':.'))
|
||||
eq(
|
||||
[[test\functional\fixtures\bin\null.CMD]],
|
||||
call('fnamemodify', call('exepath', 'null'), ':.')
|
||||
)
|
||||
command('set shellslash')
|
||||
eq('test/functional/fixtures/bin/null.CMD', call('fnamemodify', call('exepath', 'null'), ':.'))
|
||||
eq(
|
||||
'test/functional/fixtures/bin/null.CMD',
|
||||
call('fnamemodify', call('exepath', 'null'), ':.')
|
||||
)
|
||||
end)
|
||||
|
||||
it('stdpath respects shellslash', function()
|
||||
@@ -34,14 +39,18 @@ describe('executable()', function()
|
||||
end
|
||||
|
||||
it('fails for invalid values', function()
|
||||
for _, input in ipairs({'v:null', 'v:true', 'v:false', '{}', '[]'}) do
|
||||
eq('Vim(call):E1174: String required for argument 1',
|
||||
exc_exec('call executable('..input..')'))
|
||||
for _, input in ipairs({ 'v:null', 'v:true', 'v:false', '{}', '[]' }) do
|
||||
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):E1174: String required for argument 1',
|
||||
exc_exec('call executable('..input..')'))
|
||||
for _, input in ipairs({ 'v:null', 'v:true', 'v:false' }) do
|
||||
eq(
|
||||
'Vim(call):E1174: String required for argument 1',
|
||||
exc_exec('call executable(' .. input .. ')')
|
||||
)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -59,8 +68,7 @@ describe('executable()', function()
|
||||
-- Windows: siblings are in Nvim's "pseudo-$PATH".
|
||||
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'))
|
||||
eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', sibling_exe .. ' lemon sky tree'))
|
||||
end
|
||||
eq(expected, call('executable', sibling_exe))
|
||||
end)
|
||||
@@ -70,9 +78,9 @@ describe('executable()', function()
|
||||
clear()
|
||||
write_file('Xtest_not_executable', 'non-executable file')
|
||||
write_file('Xtest_executable', 'executable file (exec-bit set)')
|
||||
if not is_os('win') then -- N/A for Windows.
|
||||
call('system', {'chmod', '-x', 'Xtest_not_executable'})
|
||||
call('system', {'chmod', '+x', 'Xtest_executable'})
|
||||
if not is_os('win') then -- N/A for Windows.
|
||||
call('system', { 'chmod', '-x', 'Xtest_not_executable' })
|
||||
call('system', { 'chmod', '+x', 'Xtest_executable' })
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -103,144 +111,142 @@ describe('executable() (Windows)', function()
|
||||
return
|
||||
end
|
||||
|
||||
local exts = {'bat', 'exe', 'com', 'cmd'}
|
||||
local exts = { 'bat', 'exe', 'com', 'cmd' }
|
||||
setup(function()
|
||||
for _, ext in ipairs(exts) do
|
||||
write_file('test_executable_'..ext..'.'..ext, '')
|
||||
write_file('test_executable_' .. ext .. '.' .. ext, '')
|
||||
end
|
||||
write_file('test_executable_zzz.zzz', '')
|
||||
end)
|
||||
|
||||
teardown(function()
|
||||
for _, ext in ipairs(exts) do
|
||||
os.remove('test_executable_'..ext..'.'..ext)
|
||||
os.remove('test_executable_' .. ext .. '.' .. ext)
|
||||
end
|
||||
os.remove('test_executable_zzz.zzz')
|
||||
end)
|
||||
|
||||
it('tries default extensions on a filename if $PATHEXT is empty', function()
|
||||
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
||||
clear({env={PATHEXT=''}})
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_'..ext))
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_' .. ext))
|
||||
end
|
||||
eq(0, call('executable', 'test_executable_zzz'))
|
||||
end)
|
||||
|
||||
it('tries default extensions on a filepath if $PATHEXT is empty', function()
|
||||
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
||||
clear({env={PATHEXT=''}})
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(1, call('executable', '.\\test_executable_'..ext))
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(1, call('executable', '.\\test_executable_' .. ext))
|
||||
end
|
||||
eq(0, call('executable', '.\\test_executable_zzz'))
|
||||
end)
|
||||
|
||||
it('system([…]), jobstart([…]) use $PATHEXT #9569', function()
|
||||
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
||||
clear({env={PATHEXT=''}})
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
-- Invoking `cmdscript` should find/execute `cmdscript.cmd`.
|
||||
eq('much success\n', call('system', {'test/functional/fixtures/cmdscript'}))
|
||||
assert(0 < call('jobstart', {'test/functional/fixtures/cmdscript'}))
|
||||
eq('much success\n', call('system', { 'test/functional/fixtures/cmdscript' }))
|
||||
assert(0 < call('jobstart', { 'test/functional/fixtures/cmdscript' }))
|
||||
end)
|
||||
|
||||
it('full path with extension', function()
|
||||
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
||||
clear({env={PATHEXT=''}})
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
-- Some executable we can expect in the test env.
|
||||
local exe = 'printargs-test'
|
||||
local exedir = eval("fnamemodify(v:progpath, ':h')")
|
||||
local exepath = exedir..'/'..exe..'.exe'
|
||||
local exepath = exedir .. '/' .. exe .. '.exe'
|
||||
eq(1, call('executable', exepath))
|
||||
eq('arg1=lemon;arg2=sky;arg3=tree;',
|
||||
call('system', exepath..' lemon sky tree'))
|
||||
eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', exepath .. ' lemon sky tree'))
|
||||
end)
|
||||
|
||||
it('full path without extension', function()
|
||||
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
||||
clear({env={PATHEXT=''}})
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
-- Some executable we can expect in the test env.
|
||||
local exe = 'printargs-test'
|
||||
local exedir = eval("fnamemodify(v:progpath, ':h')")
|
||||
local exepath = exedir..'/'..exe
|
||||
eq('arg1=lemon;arg2=sky;arg3=tree;',
|
||||
call('system', exepath..' lemon sky tree'))
|
||||
eq(1, call('executable', exepath))
|
||||
local exepath = exedir .. '/' .. exe
|
||||
eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', exepath .. ' lemon sky tree'))
|
||||
eq(1, call('executable', exepath))
|
||||
end)
|
||||
|
||||
it('respects $PATHEXT when trying extensions on a filename', function()
|
||||
clear({env={PATHEXT='.zzz'}})
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(0, call('executable', 'test_executable_'..ext))
|
||||
clear({ env = { PATHEXT = '.zzz' } })
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(0, call('executable', 'test_executable_' .. ext))
|
||||
end
|
||||
eq(1, call('executable', 'test_executable_zzz'))
|
||||
end)
|
||||
|
||||
it('respects $PATHEXT when trying extensions on a filepath', function()
|
||||
clear({env={PATHEXT='.zzz'}})
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(0, call('executable', '.\\test_executable_'..ext))
|
||||
clear({ env = { PATHEXT = '.zzz' } })
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(0, call('executable', '.\\test_executable_' .. ext))
|
||||
end
|
||||
eq(1, call('executable', '.\\test_executable_zzz'))
|
||||
end)
|
||||
|
||||
it("with weird $PATHEXT", function()
|
||||
clear({env={PATHEXT=';'}})
|
||||
it('with weird $PATHEXT', function()
|
||||
clear({ env = { PATHEXT = ';' } })
|
||||
eq(0, call('executable', '.\\test_executable_zzz'))
|
||||
clear({env={PATHEXT=';;;.zzz;;'}})
|
||||
clear({ env = { PATHEXT = ';;;.zzz;;' } })
|
||||
eq(1, call('executable', '.\\test_executable_zzz'))
|
||||
end)
|
||||
|
||||
it("unqualified filename, Unix-style 'shell'", function()
|
||||
clear({env={PATHEXT=''}})
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
command('set shell=sh')
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_'..ext..'.'..ext))
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext))
|
||||
end
|
||||
eq(1, call('executable', 'test_executable_zzz.zzz'))
|
||||
end)
|
||||
|
||||
it("relative path, Unix-style 'shell' (backslashes)", function()
|
||||
clear({env={PATHEXT=''}})
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
command('set shell=bash.exe')
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(1, call('executable', '.\\test_executable_'..ext..'.'..ext))
|
||||
eq(1, call('executable', './test_executable_'..ext..'.'..ext))
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(1, call('executable', '.\\test_executable_' .. ext .. '.' .. ext))
|
||||
eq(1, call('executable', './test_executable_' .. ext .. '.' .. ext))
|
||||
end
|
||||
eq(1, call('executable', '.\\test_executable_zzz.zzz'))
|
||||
eq(1, call('executable', './test_executable_zzz.zzz'))
|
||||
end)
|
||||
|
||||
it('unqualified filename, $PATHEXT contains dot', function()
|
||||
clear({env={PATHEXT='.;.zzz'}})
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_'..ext..'.'..ext))
|
||||
clear({ env = { PATHEXT = '.;.zzz' } })
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext))
|
||||
end
|
||||
eq(1, call('executable', 'test_executable_zzz.zzz'))
|
||||
clear({env={PATHEXT='.zzz;.'}})
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_'..ext..'.'..ext))
|
||||
clear({ env = { PATHEXT = '.zzz;.' } })
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext))
|
||||
end
|
||||
eq(1, call('executable', 'test_executable_zzz.zzz'))
|
||||
end)
|
||||
|
||||
it('relative path, $PATHEXT contains dot (backslashes)', function()
|
||||
clear({env={PATHEXT='.;.zzz'}})
|
||||
for _,ext in ipairs(exts) do
|
||||
eq(1, call('executable', '.\\test_executable_'..ext..'.'..ext))
|
||||
eq(1, call('executable', './test_executable_'..ext..'.'..ext))
|
||||
clear({ env = { PATHEXT = '.;.zzz' } })
|
||||
for _, ext in ipairs(exts) do
|
||||
eq(1, call('executable', '.\\test_executable_' .. ext .. '.' .. ext))
|
||||
eq(1, call('executable', './test_executable_' .. ext .. '.' .. ext))
|
||||
end
|
||||
eq(1, call('executable', '.\\test_executable_zzz.zzz'))
|
||||
eq(1, call('executable', './test_executable_zzz.zzz'))
|
||||
end)
|
||||
|
||||
it('ignores case of extension', function()
|
||||
clear({env={PATHEXT='.ZZZ'}})
|
||||
clear({ env = { PATHEXT = '.ZZZ' } })
|
||||
eq(1, call('executable', 'test_executable_zzz.zzz'))
|
||||
end)
|
||||
|
||||
it('relative path does not search $PATH', function()
|
||||
clear({env={PATHEXT=''}})
|
||||
clear({ env = { PATHEXT = '' } })
|
||||
eq(0, call('executable', './System32/notepad.exe'))
|
||||
eq(0, call('executable', '.\\System32\\notepad.exe'))
|
||||
eq(0, call('executable', '../notepad.exe'))
|
||||
|
||||
@@ -26,8 +26,8 @@ describe('execute()', function()
|
||||
end)
|
||||
|
||||
it('captures the concatenated outputs of a List of commands', function()
|
||||
eq("foobar", funcs.execute({'echon "foo"', 'echon "bar"'}))
|
||||
eq("\nfoo\nbar", funcs.execute({'echo "foo"', 'echo "bar"'}))
|
||||
eq('foobar', funcs.execute({ 'echon "foo"', 'echon "bar"' }))
|
||||
eq('\nfoo\nbar', funcs.execute({ 'echo "foo"', 'echo "bar"' }))
|
||||
end)
|
||||
|
||||
it('supports nested execute("execute(...)")', function()
|
||||
@@ -104,26 +104,31 @@ describe('execute()', function()
|
||||
end)
|
||||
|
||||
it('captures output with highlights', function()
|
||||
eq('\nErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red',
|
||||
eval('execute("hi ErrorMsg")'))
|
||||
eq(
|
||||
'\nErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red',
|
||||
eval('execute("hi ErrorMsg")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not corrupt the command display #5422', function()
|
||||
local screen = Screen.new(70, 7)
|
||||
screen:attach()
|
||||
feed(':echo execute("hi ErrorMsg")<CR>')
|
||||
screen:expect([[
|
||||
screen:expect(
|
||||
[[
|
||||
|
|
||||
{1:~ }|*2
|
||||
{2: }|
|
||||
|
|
||||
ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red |
|
||||
{3:Press ENTER or type command to continue}^ |
|
||||
]], {
|
||||
[1] = {bold = true, foreground = Screen.colors.Blue1},
|
||||
[2] = {bold = true, reverse = true},
|
||||
[3] = {bold = true, foreground = Screen.colors.SeaGreen4},
|
||||
})
|
||||
]],
|
||||
{
|
||||
[1] = { bold = true, foreground = Screen.colors.Blue1 },
|
||||
[2] = { bold = true, reverse = true },
|
||||
[3] = { bold = true, foreground = Screen.colors.SeaGreen4 },
|
||||
}
|
||||
)
|
||||
feed('<CR>')
|
||||
end)
|
||||
|
||||
@@ -250,7 +255,7 @@ describe('execute()', function()
|
||||
-- with how nvim currently displays the output.
|
||||
it('captures shell-command output', function()
|
||||
local win_lf = is_os('win') and '\13' or ''
|
||||
eq('\n:!echo foo\r\n\nfoo'..win_lf..'\n', funcs.execute('!echo foo'))
|
||||
eq('\n:!echo foo\r\n\nfoo' .. win_lf .. '\n', funcs.execute('!echo foo'))
|
||||
end)
|
||||
|
||||
describe('{silent} argument', function()
|
||||
@@ -268,10 +273,14 @@ describe('execute()', function()
|
||||
|
||||
it('gives E493 instead of prompting on backwards range for ""', function()
|
||||
command('split')
|
||||
eq('Vim(windo):E493: Backwards range given: 2,1windo echo',
|
||||
pcall_err(funcs.execute, '2,1windo echo', ''))
|
||||
eq('Vim(windo):E493: Backwards range given: 2,1windo echo',
|
||||
pcall_err(funcs.execute, {'2,1windo echo'}, ''))
|
||||
eq(
|
||||
'Vim(windo):E493: Backwards range given: 2,1windo echo',
|
||||
pcall_err(funcs.execute, '2,1windo echo', '')
|
||||
)
|
||||
eq(
|
||||
'Vim(windo):E493: Backwards range given: 2,1windo echo',
|
||||
pcall_err(funcs.execute, { '2,1windo echo' }, '')
|
||||
)
|
||||
end)
|
||||
|
||||
it('captures but does not display output for "silent"', function()
|
||||
@@ -286,11 +295,14 @@ describe('execute()', function()
|
||||
eq('42', eval('g:mes'))
|
||||
|
||||
command('let g:mes = execute("echon 13", "silent")')
|
||||
screen:expect{grid=[[
|
||||
screen:expect {
|
||||
grid = [[
|
||||
^ |
|
||||
~ |*3
|
||||
|
|
||||
]], unchanged=true}
|
||||
]],
|
||||
unchanged = true,
|
||||
}
|
||||
eq('13', eval('g:mes'))
|
||||
end)
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local eq, clear, call =
|
||||
helpers.eq, helpers.clear, helpers.call
|
||||
local eq, clear, call = helpers.eq, helpers.clear, helpers.call
|
||||
local command = helpers.command
|
||||
local exc_exec = helpers.exc_exec
|
||||
local matches = helpers.matches
|
||||
@@ -14,20 +13,26 @@ local find_dummies = function(ext_pat)
|
||||
matches('null' .. ext_pat, call('exepath', 'null'))
|
||||
matches('true' .. ext_pat, call('exepath', 'true'))
|
||||
matches('false' .. ext_pat, call('exepath', 'false'))
|
||||
command("let $PATH = '"..tmp_path.."'")
|
||||
command("let $PATH = '" .. tmp_path .. "'")
|
||||
end
|
||||
|
||||
describe('exepath()', function()
|
||||
before_each(clear)
|
||||
|
||||
it('fails for invalid values', function()
|
||||
for _, input in ipairs({'v:null', 'v:true', 'v:false', '{}', '[]'}) do
|
||||
eq('Vim(call):E1174: String required for argument 1', exc_exec('call exepath('..input..')'))
|
||||
for _, input in ipairs({ 'v:null', 'v:true', 'v:false', '{}', '[]' }) do
|
||||
eq(
|
||||
'Vim(call):E1174: String required for argument 1',
|
||||
exc_exec('call exepath(' .. input .. ')')
|
||||
)
|
||||
end
|
||||
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):E1174: String required for argument 1', exc_exec('call exepath('..input..')'))
|
||||
for _, input in ipairs({ 'v:null', 'v:true', 'v:false' }) do
|
||||
eq(
|
||||
'Vim(call):E1174: String required for argument 1',
|
||||
exc_exec('call exepath(' .. input .. ')')
|
||||
)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -40,24 +45,30 @@ describe('exepath()', function()
|
||||
it('append extension if omitted', function()
|
||||
local filename = 'cmd'
|
||||
local pathext = '.exe'
|
||||
clear({env={PATHEXT=pathext}})
|
||||
eq(call('exepath', filename..pathext), call('exepath', filename))
|
||||
clear({ env = { PATHEXT = pathext } })
|
||||
eq(call('exepath', filename .. pathext), call('exepath', filename))
|
||||
end)
|
||||
|
||||
it('returns file WITH extension if files both with and without extension exist in $PATH', function()
|
||||
local ext_pat = '%.CMD$'
|
||||
find_dummies(ext_pat)
|
||||
set_shell_powershell()
|
||||
find_dummies(ext_pat)
|
||||
end)
|
||||
it(
|
||||
'returns file WITH extension if files both with and without extension exist in $PATH',
|
||||
function()
|
||||
local ext_pat = '%.CMD$'
|
||||
find_dummies(ext_pat)
|
||||
set_shell_powershell()
|
||||
find_dummies(ext_pat)
|
||||
end
|
||||
)
|
||||
else
|
||||
it('returns 1 for commands in $PATH (not Windows)', function()
|
||||
local exe = 'ls'
|
||||
matches(exe .. '$', call('exepath', exe))
|
||||
end)
|
||||
|
||||
it('returns file WITHOUT extension if files both with and without extension exist in $PATH', function()
|
||||
find_dummies('$')
|
||||
end)
|
||||
it(
|
||||
'returns file WITHOUT extension if files both with and without extension exist in $PATH',
|
||||
function()
|
||||
find_dummies('$')
|
||||
end
|
||||
)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -31,7 +31,7 @@ describe('fnamemodify()', function()
|
||||
eq(root, fnamemodify([[\]], ':p:h'))
|
||||
eq(root, fnamemodify([[\]], ':p'))
|
||||
command('set shellslash')
|
||||
root = string.sub(root, 1, -2)..'/'
|
||||
root = string.sub(root, 1, -2) .. '/'
|
||||
eq(root, fnamemodify([[\]], ':p:h'))
|
||||
eq(root, fnamemodify([[\]], ':p'))
|
||||
eq(root, fnamemodify([[/]], ':p:h'))
|
||||
@@ -44,7 +44,7 @@ describe('fnamemodify()', function()
|
||||
end)
|
||||
|
||||
it('handles examples from ":help filename-modifiers"', function()
|
||||
local filename = "src/version.c"
|
||||
local filename = 'src/version.c'
|
||||
local cwd = getcwd()
|
||||
|
||||
eq_slashconvert(cwd .. '/src/version.c', fnamemodify(filename, ':p'))
|
||||
@@ -70,7 +70,7 @@ describe('fnamemodify()', function()
|
||||
end)
|
||||
|
||||
it('handles advanced examples from ":help filename-modifiers"', function()
|
||||
local filename = "src/version.c.gz"
|
||||
local filename = 'src/version.c.gz'
|
||||
|
||||
eq('gz', fnamemodify(filename, ':e'))
|
||||
eq('c.gz', fnamemodify(filename, ':e:e'))
|
||||
|
||||
@@ -8,7 +8,7 @@ local expect = helpers.expect
|
||||
describe('getline()', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
call('setline', 1, {'a', 'b', 'c'})
|
||||
call('setline', 1, { 'a', 'b', 'c' })
|
||||
expect([[
|
||||
a
|
||||
b
|
||||
@@ -33,7 +33,7 @@ describe('getline()', function()
|
||||
end)
|
||||
|
||||
it('returns value of valid range', function()
|
||||
eq({'a', 'b'}, call('getline', 1, 2))
|
||||
eq({'a', 'b', 'c'}, call('getline', 1, 4))
|
||||
eq({ 'a', 'b' }, call('getline', 1, 2))
|
||||
eq({ 'a', 'b', 'c' }, call('getline', 1, 4))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -17,9 +17,9 @@ end)
|
||||
|
||||
describe('glob()', function()
|
||||
it("glob('.*') returns . and .. ", function()
|
||||
eq({'.', '..'}, eval("glob('.*', 0, 1)"))
|
||||
eq({ '.', '..' }, eval("glob('.*', 0, 1)"))
|
||||
-- Do it again to verify scandir_next_with_dots() internal state.
|
||||
eq({'.', '..'}, eval("glob('.*', 0, 1)"))
|
||||
eq({ '.', '..' }, eval("glob('.*', 0, 1)"))
|
||||
end)
|
||||
it("glob('*') returns an empty list ", function()
|
||||
eq({}, eval("glob('*', 0, 1)"))
|
||||
|
||||
@@ -11,60 +11,59 @@ describe('has()', function()
|
||||
before_each(clear)
|
||||
|
||||
it('"nvim-x.y.z"', function()
|
||||
eq(0, funcs.has("nvim-"))
|
||||
eq(0, funcs.has("nvim- "))
|
||||
eq(0, funcs.has("nvim- \t "))
|
||||
eq(0, funcs.has("nvim-0. 1. 1"))
|
||||
eq(0, funcs.has("nvim-0. 1.1"))
|
||||
eq(0, funcs.has("nvim-0.1. 1"))
|
||||
eq(0, funcs.has("nvim-a"))
|
||||
eq(0, funcs.has("nvim-a.b.c"))
|
||||
eq(0, funcs.has("nvim-0.b.c"))
|
||||
eq(0, funcs.has("nvim-0.0.c"))
|
||||
eq(0, funcs.has("nvim-0.b.0"))
|
||||
eq(0, funcs.has("nvim-a.b.0"))
|
||||
eq(0, funcs.has("nvim-.0.0.0"))
|
||||
eq(0, funcs.has("nvim-.0"))
|
||||
eq(0, funcs.has("nvim-0."))
|
||||
eq(0, funcs.has("nvim-0.."))
|
||||
eq(0, funcs.has("nvim-."))
|
||||
eq(0, funcs.has("nvim-.."))
|
||||
eq(0, funcs.has("nvim-..."))
|
||||
eq(0, funcs.has("nvim-42"))
|
||||
eq(0, funcs.has("nvim-9999"))
|
||||
eq(0, funcs.has("nvim-99.001.05"))
|
||||
eq(0, funcs.has('nvim-'))
|
||||
eq(0, funcs.has('nvim- '))
|
||||
eq(0, funcs.has('nvim- \t '))
|
||||
eq(0, funcs.has('nvim-0. 1. 1'))
|
||||
eq(0, funcs.has('nvim-0. 1.1'))
|
||||
eq(0, funcs.has('nvim-0.1. 1'))
|
||||
eq(0, funcs.has('nvim-a'))
|
||||
eq(0, funcs.has('nvim-a.b.c'))
|
||||
eq(0, funcs.has('nvim-0.b.c'))
|
||||
eq(0, funcs.has('nvim-0.0.c'))
|
||||
eq(0, funcs.has('nvim-0.b.0'))
|
||||
eq(0, funcs.has('nvim-a.b.0'))
|
||||
eq(0, funcs.has('nvim-.0.0.0'))
|
||||
eq(0, funcs.has('nvim-.0'))
|
||||
eq(0, funcs.has('nvim-0.'))
|
||||
eq(0, funcs.has('nvim-0..'))
|
||||
eq(0, funcs.has('nvim-.'))
|
||||
eq(0, funcs.has('nvim-..'))
|
||||
eq(0, funcs.has('nvim-...'))
|
||||
eq(0, funcs.has('nvim-42'))
|
||||
eq(0, funcs.has('nvim-9999'))
|
||||
eq(0, funcs.has('nvim-99.001.05'))
|
||||
|
||||
eq(1, funcs.has("nvim"))
|
||||
eq(1, funcs.has("nvim-0"))
|
||||
eq(1, funcs.has("nvim-0.1"))
|
||||
eq(1, funcs.has("nvim-0.0.0"))
|
||||
eq(1, funcs.has("nvim-0.1.1."))
|
||||
eq(1, funcs.has("nvim-0.1.1.abc"))
|
||||
eq(1, funcs.has("nvim-0.1.1.."))
|
||||
eq(1, funcs.has("nvim-0.1.1.. .."))
|
||||
eq(1, funcs.has("nvim-0.1.1.... "))
|
||||
eq(1, funcs.has("nvim-0.0.0"))
|
||||
eq(1, funcs.has("nvim-0.0.1"))
|
||||
eq(1, funcs.has("nvim-0.1.0"))
|
||||
eq(1, funcs.has("nvim-0.1.1"))
|
||||
eq(1, funcs.has("nvim-0.1.5"))
|
||||
eq(1, funcs.has("nvim-0000.001.05"))
|
||||
eq(1, funcs.has("nvim-0.01.005"))
|
||||
eq(1, funcs.has("nvim-00.001.05"))
|
||||
eq(1, funcs.has('nvim'))
|
||||
eq(1, funcs.has('nvim-0'))
|
||||
eq(1, funcs.has('nvim-0.1'))
|
||||
eq(1, funcs.has('nvim-0.0.0'))
|
||||
eq(1, funcs.has('nvim-0.1.1.'))
|
||||
eq(1, funcs.has('nvim-0.1.1.abc'))
|
||||
eq(1, funcs.has('nvim-0.1.1..'))
|
||||
eq(1, funcs.has('nvim-0.1.1.. ..'))
|
||||
eq(1, funcs.has('nvim-0.1.1.... '))
|
||||
eq(1, funcs.has('nvim-0.0.0'))
|
||||
eq(1, funcs.has('nvim-0.0.1'))
|
||||
eq(1, funcs.has('nvim-0.1.0'))
|
||||
eq(1, funcs.has('nvim-0.1.1'))
|
||||
eq(1, funcs.has('nvim-0.1.5'))
|
||||
eq(1, funcs.has('nvim-0000.001.05'))
|
||||
eq(1, funcs.has('nvim-0.01.005'))
|
||||
eq(1, funcs.has('nvim-00.001.05'))
|
||||
end)
|
||||
|
||||
it('"unnamedplus"', function()
|
||||
if (not is_os('win')) and funcs.has("clipboard") == 1 then
|
||||
eq(1, funcs.has("unnamedplus"))
|
||||
if (not is_os('win')) and funcs.has('clipboard') == 1 then
|
||||
eq(1, funcs.has('unnamedplus'))
|
||||
else
|
||||
eq(0, funcs.has("unnamedplus"))
|
||||
eq(0, funcs.has('unnamedplus'))
|
||||
end
|
||||
end)
|
||||
|
||||
it('"wsl"', function()
|
||||
local luv = require('luv')
|
||||
local is_wsl =
|
||||
luv.os_uname()['release']:lower():match('microsoft') and true or false
|
||||
local is_wsl = luv.os_uname()['release']:lower():match('microsoft') and true or false
|
||||
if is_wsl then
|
||||
eq(1, funcs.has('wsl'))
|
||||
else
|
||||
@@ -74,12 +73,12 @@ describe('has()', function()
|
||||
|
||||
it('"gui_running"', function()
|
||||
eq(0, funcs.has('gui_running'))
|
||||
local tui = Screen.new(50,15)
|
||||
local tui = Screen.new(50, 15)
|
||||
local gui_session = connect(funcs.serverstart())
|
||||
local gui = Screen.new(50,15)
|
||||
local gui = Screen.new(50, 15)
|
||||
eq(0, funcs.has('gui_running'))
|
||||
tui:attach({ext_linegrid=true, rgb=true, stdin_tty=true, stdout_tty=true})
|
||||
gui:attach({ext_multigrid=true, rgb=true}, gui_session)
|
||||
tui:attach({ ext_linegrid = true, rgb = true, stdin_tty = true, stdout_tty = true })
|
||||
gui:attach({ ext_multigrid = true, rgb = true }, gui_session)
|
||||
eq(1, funcs.has('gui_running'))
|
||||
tui:detach()
|
||||
eq(1, funcs.has('gui_running'))
|
||||
@@ -88,7 +87,7 @@ describe('has()', function()
|
||||
end)
|
||||
|
||||
it('does not change v:shell_error', function()
|
||||
funcs.system({nvim_prog, '-es', '+73cquit'})
|
||||
funcs.system({ nvim_prog, '-es', '+73cquit' })
|
||||
funcs.has('python3') -- use a call whose implementation shells out
|
||||
eq(73, funcs.eval('v:shell_error'))
|
||||
end)
|
||||
|
||||
@@ -13,8 +13,10 @@ describe('hostname()', function()
|
||||
ok(string.len(actual) > 0)
|
||||
if call('executable', 'hostname') == 1 then
|
||||
local expected = string.gsub(call('system', 'hostname'), '[\n\r]', '')
|
||||
eq((is_os('win') and expected:upper() or expected),
|
||||
(is_os('win') 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)
|
||||
|
||||
@@ -55,14 +55,14 @@ before_each(function()
|
||||
endfunction
|
||||
]])
|
||||
screen:set_default_attr_ids({
|
||||
EOB={bold = true, foreground = Screen.colors.Blue1},
|
||||
T={foreground=Screen.colors.Red},
|
||||
RBP1={background=Screen.colors.Red},
|
||||
RBP2={background=Screen.colors.Yellow},
|
||||
RBP3={background=Screen.colors.Green},
|
||||
RBP4={background=Screen.colors.Blue},
|
||||
SEP={bold = true, reverse = true},
|
||||
CONFIRM={bold = true, foreground = Screen.colors.SeaGreen4},
|
||||
EOB = { bold = true, foreground = Screen.colors.Blue1 },
|
||||
T = { foreground = Screen.colors.Red },
|
||||
RBP1 = { background = Screen.colors.Red },
|
||||
RBP2 = { background = Screen.colors.Yellow },
|
||||
RBP3 = { background = Screen.colors.Green },
|
||||
RBP4 = { background = Screen.colors.Blue },
|
||||
SEP = { bold = true, reverse = true },
|
||||
CONFIRM = { bold = true, foreground = Screen.colors.SeaGreen4 },
|
||||
})
|
||||
end)
|
||||
|
||||
@@ -110,7 +110,7 @@ describe('input()', function()
|
||||
end)
|
||||
it('allows unequal numeric values when using {opts} dictionary', function()
|
||||
command('echohl Test')
|
||||
meths.set_var('opts', {prompt=1, default=2, cancelreturn=3})
|
||||
meths.set_var('opts', { prompt = 1, default = 2, cancelreturn = 3 })
|
||||
feed([[:echo input(opts)<CR>]])
|
||||
screen:expect([[
|
||||
|
|
||||
@@ -132,7 +132,7 @@ describe('input()', function()
|
||||
end)
|
||||
it('works with redraw', function()
|
||||
command('echohl Test')
|
||||
meths.set_var('opts', {prompt='Foo>', default='Bar'})
|
||||
meths.set_var('opts', { prompt = 'Foo>', default = 'Bar' })
|
||||
feed([[:echo inputdialog(opts)<CR>]])
|
||||
screen:expect([[
|
||||
|
|
||||
@@ -140,11 +140,14 @@ describe('input()', function()
|
||||
{T:Foo>}Bar^ |
|
||||
]])
|
||||
command('mode')
|
||||
screen:expect{grid=[[
|
||||
screen:expect {
|
||||
grid = [[
|
||||
|
|
||||
{EOB:~ }|*3
|
||||
{T:Foo>}Bar^ |
|
||||
]], reset=true}
|
||||
]],
|
||||
reset = true,
|
||||
}
|
||||
feed('<BS>')
|
||||
screen:expect([[
|
||||
|
|
||||
@@ -152,11 +155,14 @@ describe('input()', function()
|
||||
{T:Foo>}Ba^ |
|
||||
]])
|
||||
command('mode')
|
||||
screen:expect{grid=[[
|
||||
screen:expect {
|
||||
grid = [[
|
||||
|
|
||||
{EOB:~ }|*3
|
||||
{T:Foo>}Ba^ |
|
||||
]], reset=true}
|
||||
]],
|
||||
reset = true,
|
||||
}
|
||||
end)
|
||||
it('allows omitting everything with dictionary argument', function()
|
||||
command('echohl Test')
|
||||
@@ -200,22 +206,17 @@ describe('input()', function()
|
||||
eq('DEF2', meths.get_var('var'))
|
||||
end)
|
||||
it('errors out on invalid inputs', function()
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call input([])'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call input("", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call input("", "", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call input({"prompt": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call input({"default": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call input({"completion": []})'))
|
||||
eq('Vim(call):E5050: {opts} must be the only argument',
|
||||
exc_exec('call input({}, "default")'))
|
||||
eq('Vim(call):E118: Too many arguments for function: input',
|
||||
exc_exec('call input("prompt> ", "default", "file", "extra")'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call input([])'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call input("", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call input("", "", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call input({"prompt": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call input({"default": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call input({"completion": []})'))
|
||||
eq('Vim(call):E5050: {opts} must be the only argument', exc_exec('call input({}, "default")'))
|
||||
eq(
|
||||
'Vim(call):E118: Too many arguments for function: input',
|
||||
exc_exec('call input("prompt> ", "default", "file", "extra")')
|
||||
)
|
||||
end)
|
||||
it('supports highlighting', function()
|
||||
command('nnoremap <expr> X input({"highlight": "RainBowParens"})[-1]')
|
||||
@@ -291,7 +292,7 @@ describe('inputdialog()', function()
|
||||
end)
|
||||
it('allows unequal numeric values when using {opts} dictionary', function()
|
||||
command('echohl Test')
|
||||
meths.set_var('opts', {prompt=1, default=2, cancelreturn=3})
|
||||
meths.set_var('opts', { prompt = 1, default = 2, cancelreturn = 3 })
|
||||
feed([[:echo input(opts)<CR>]])
|
||||
screen:expect([[
|
||||
|
|
||||
@@ -313,7 +314,7 @@ describe('inputdialog()', function()
|
||||
end)
|
||||
it('works with redraw', function()
|
||||
command('echohl Test')
|
||||
meths.set_var('opts', {prompt='Foo>', default='Bar'})
|
||||
meths.set_var('opts', { prompt = 'Foo>', default = 'Bar' })
|
||||
feed([[:echo input(opts)<CR>]])
|
||||
screen:expect([[
|
||||
|
|
||||
@@ -321,11 +322,14 @@ describe('inputdialog()', function()
|
||||
{T:Foo>}Bar^ |
|
||||
]])
|
||||
command('mode')
|
||||
screen:expect{grid=[[
|
||||
screen:expect {
|
||||
grid = [[
|
||||
|
|
||||
{EOB:~ }|*3
|
||||
{T:Foo>}Bar^ |
|
||||
]], reset=true}
|
||||
]],
|
||||
reset = true,
|
||||
}
|
||||
feed('<BS>')
|
||||
screen:expect([[
|
||||
|
|
||||
@@ -333,11 +337,14 @@ describe('inputdialog()', function()
|
||||
{T:Foo>}Ba^ |
|
||||
]])
|
||||
command('mode')
|
||||
screen:expect{grid=[[
|
||||
screen:expect {
|
||||
grid = [[
|
||||
|
|
||||
{EOB:~ }|*3
|
||||
{T:Foo>}Ba^ |
|
||||
]], reset=true}
|
||||
]],
|
||||
reset = true,
|
||||
}
|
||||
end)
|
||||
it('allows omitting everything with dictionary argument', function()
|
||||
command('echohl Test')
|
||||
@@ -372,22 +379,20 @@ describe('inputdialog()', function()
|
||||
eq('DEF2', meths.get_var('var'))
|
||||
end)
|
||||
it('errors out on invalid inputs', function()
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call inputdialog([])'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call inputdialog("", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call inputdialog("", "", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call inputdialog({"prompt": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call inputdialog({"default": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
exc_exec('call inputdialog({"completion": []})'))
|
||||
eq('Vim(call):E5050: {opts} must be the only argument',
|
||||
exc_exec('call inputdialog({}, "default")'))
|
||||
eq('Vim(call):E118: Too many arguments for function: inputdialog',
|
||||
exc_exec('call inputdialog("prompt> ", "default", "file", "extra")'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog([])'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog("", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog("", "", [])'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog({"prompt": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog({"default": []})'))
|
||||
eq('Vim(call):E730: Using a List as a String', exc_exec('call inputdialog({"completion": []})'))
|
||||
eq(
|
||||
'Vim(call):E5050: {opts} must be the only argument',
|
||||
exc_exec('call inputdialog({}, "default")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E118: Too many arguments for function: inputdialog',
|
||||
exc_exec('call inputdialog("prompt> ", "default", "file", "extra")')
|
||||
)
|
||||
end)
|
||||
it('supports highlighting', function()
|
||||
command('nnoremap <expr> X inputdialog({"highlight": "RainBowParens"})[-1]')
|
||||
@@ -404,84 +409,89 @@ end)
|
||||
describe('confirm()', function()
|
||||
-- oldtest: Test_confirm()
|
||||
it('works', function()
|
||||
meths.set_option_value('more', false, {}) -- Avoid hit-enter prompt
|
||||
meths.set_option_value('more', false, {}) -- Avoid hit-enter prompt
|
||||
meths.set_option_value('laststatus', 2, {})
|
||||
-- screen:expect() calls are needed to avoid feeding input too early
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
screen:expect({ any = '%[No Name%]' })
|
||||
|
||||
async_meths.command([[let a = confirm('Press O to proceed')]])
|
||||
screen:expect({any = '{CONFIRM:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('o')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
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:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('y')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
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:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('n')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
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:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('<Esc>')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
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:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('<CR>')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
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:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('<CR>')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
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:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('<CR>')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
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
|
||||
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:.+: }'})
|
||||
screen:expect({ any = '{CONFIRM:.+: }' })
|
||||
feed('y')
|
||||
screen:expect({any = '%[No Name%]'})
|
||||
screen:expect({ any = '%[No Name%]' })
|
||||
eq(1, meths.get_var('a'))
|
||||
end
|
||||
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
pcall_err(command, 'call confirm([])'))
|
||||
eq('Vim(call):E730: Using a 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 a List as a String',
|
||||
pcall_err(command, 'call confirm("Are you sure?", "&Yes\n&No\n", 0, [])'))
|
||||
eq('Vim(call):E730: Using a List as a String', pcall_err(command, 'call confirm([])'))
|
||||
eq(
|
||||
'Vim(call):E730: Using a 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 a 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()
|
||||
it('shows dialog even if :silent #8788', function()
|
||||
command("autocmd BufNewFile * call confirm('test')")
|
||||
|
||||
local function check_and_clear(edit_line)
|
||||
screen:expect([[
|
||||
|
|
||||
{SEP: }|
|
||||
]]..edit_line..[[
|
||||
]] .. edit_line .. [[
|
||||
{CONFIRM:test} |
|
||||
{CONFIRM:[O]k: }^ |
|
||||
]])
|
||||
|
||||
@@ -63,19 +63,25 @@ describe('json_decode() function', function()
|
||||
end
|
||||
|
||||
it('accepts readfile()-style list', function()
|
||||
eq({Test=1}, funcs.json_decode({
|
||||
'{',
|
||||
'\t"Test": 1',
|
||||
'}',
|
||||
}))
|
||||
eq(
|
||||
{ Test = 1 },
|
||||
funcs.json_decode({
|
||||
'{',
|
||||
'\t"Test": 1',
|
||||
'}',
|
||||
})
|
||||
)
|
||||
end)
|
||||
|
||||
it('accepts strings with newlines', function()
|
||||
eq({Test=1}, funcs.json_decode([[
|
||||
eq(
|
||||
{ Test = 1 },
|
||||
funcs.json_decode([[
|
||||
{
|
||||
"Test": 1
|
||||
}
|
||||
]]))
|
||||
]])
|
||||
)
|
||||
end)
|
||||
|
||||
it('parses null, true, false', function()
|
||||
@@ -85,34 +91,21 @@ describe('json_decode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to parse incomplete null, true, false', function()
|
||||
eq('Vim(call):E474: Expected null: n',
|
||||
exc_exec('call json_decode("n")'))
|
||||
eq('Vim(call):E474: Expected null: nu',
|
||||
exc_exec('call json_decode("nu")'))
|
||||
eq('Vim(call):E474: Expected null: nul',
|
||||
exc_exec('call json_decode("nul")'))
|
||||
eq('Vim(call):E474: Expected null: nul\n\t',
|
||||
exc_exec('call json_decode("nul\\n\\t")'))
|
||||
eq('Vim(call):E474: Expected null: n', exc_exec('call json_decode("n")'))
|
||||
eq('Vim(call):E474: Expected null: nu', exc_exec('call json_decode("nu")'))
|
||||
eq('Vim(call):E474: Expected null: nul', exc_exec('call json_decode("nul")'))
|
||||
eq('Vim(call):E474: Expected null: nul\n\t', exc_exec('call json_decode("nul\\n\\t")'))
|
||||
|
||||
eq('Vim(call):E474: Expected true: t',
|
||||
exc_exec('call json_decode("t")'))
|
||||
eq('Vim(call):E474: Expected true: tr',
|
||||
exc_exec('call json_decode("tr")'))
|
||||
eq('Vim(call):E474: Expected true: tru',
|
||||
exc_exec('call json_decode("tru")'))
|
||||
eq('Vim(call):E474: Expected true: tru\t\n',
|
||||
exc_exec('call json_decode("tru\\t\\n")'))
|
||||
eq('Vim(call):E474: Expected true: t', exc_exec('call json_decode("t")'))
|
||||
eq('Vim(call):E474: Expected true: tr', exc_exec('call json_decode("tr")'))
|
||||
eq('Vim(call):E474: Expected true: tru', exc_exec('call json_decode("tru")'))
|
||||
eq('Vim(call):E474: Expected true: tru\t\n', exc_exec('call json_decode("tru\\t\\n")'))
|
||||
|
||||
eq('Vim(call):E474: Expected false: f',
|
||||
exc_exec('call json_decode("f")'))
|
||||
eq('Vim(call):E474: Expected false: fa',
|
||||
exc_exec('call json_decode("fa")'))
|
||||
eq('Vim(call):E474: Expected false: fal',
|
||||
exc_exec('call json_decode("fal")'))
|
||||
eq('Vim(call):E474: Expected false: fal <',
|
||||
exc_exec('call json_decode(" fal <")'))
|
||||
eq('Vim(call):E474: Expected false: fals',
|
||||
exc_exec('call json_decode("fals")'))
|
||||
eq('Vim(call):E474: Expected false: f', exc_exec('call json_decode("f")'))
|
||||
eq('Vim(call):E474: Expected false: fa', exc_exec('call json_decode("fa")'))
|
||||
eq('Vim(call):E474: Expected false: fal', exc_exec('call json_decode("fal")'))
|
||||
eq('Vim(call):E474: Expected false: fal <', exc_exec('call json_decode(" fal <")'))
|
||||
eq('Vim(call):E474: Expected false: fals', exc_exec('call json_decode("fals")'))
|
||||
end)
|
||||
|
||||
it('parses integer numbers', function()
|
||||
@@ -125,46 +118,41 @@ describe('json_decode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to parse +numbers and .number', function()
|
||||
eq('Vim(call):E474: Unidentified byte: +1000',
|
||||
exc_exec('call json_decode("+1000")'))
|
||||
eq('Vim(call):E474: Unidentified byte: .1000',
|
||||
exc_exec('call json_decode(".1000")'))
|
||||
eq('Vim(call):E474: Unidentified byte: +1000', exc_exec('call json_decode("+1000")'))
|
||||
eq('Vim(call):E474: Unidentified byte: .1000', exc_exec('call json_decode(".1000")'))
|
||||
end)
|
||||
|
||||
it('fails to parse numbers with leading zeroes', function()
|
||||
eq('Vim(call):E474: Leading zeroes are not allowed: 00.1',
|
||||
exc_exec('call json_decode("00.1")'))
|
||||
eq('Vim(call):E474: Leading zeroes are not allowed: 01',
|
||||
exc_exec('call json_decode("01")'))
|
||||
eq('Vim(call):E474: Leading zeroes are not allowed: -01',
|
||||
exc_exec('call json_decode("-01")'))
|
||||
eq('Vim(call):E474: Leading zeroes are not allowed: -001.0',
|
||||
exc_exec('call json_decode("-001.0")'))
|
||||
eq('Vim(call):E474: Leading zeroes are not allowed: 00.1', exc_exec('call json_decode("00.1")'))
|
||||
eq('Vim(call):E474: Leading zeroes are not allowed: 01', exc_exec('call json_decode("01")'))
|
||||
eq('Vim(call):E474: Leading zeroes are not allowed: -01', exc_exec('call json_decode("-01")'))
|
||||
eq(
|
||||
'Vim(call):E474: Leading zeroes are not allowed: -001.0',
|
||||
exc_exec('call json_decode("-001.0")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to parse incomplete numbers', function()
|
||||
eq('Vim(call):E474: Missing number after minus sign: -.1',
|
||||
exc_exec('call json_decode("-.1")'))
|
||||
eq('Vim(call):E474: Missing number after minus sign: -',
|
||||
exc_exec('call json_decode("-")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: -1.',
|
||||
exc_exec('call json_decode("-1.")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 0.',
|
||||
exc_exec('call json_decode("0.")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e',
|
||||
exc_exec('call json_decode("0.0e")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e+',
|
||||
exc_exec('call json_decode("0.0e+")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e-',
|
||||
exc_exec('call json_decode("0.0e-")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e-',
|
||||
exc_exec('call json_decode("0.0e-")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 1.e5',
|
||||
exc_exec('call json_decode("1.e5")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 1.e+5',
|
||||
exc_exec('call json_decode("1.e+5")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 1.e+',
|
||||
exc_exec('call json_decode("1.e+")'))
|
||||
eq('Vim(call):E474: Missing number after minus sign: -.1', exc_exec('call json_decode("-.1")'))
|
||||
eq('Vim(call):E474: Missing number after minus sign: -', exc_exec('call json_decode("-")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: -1.', exc_exec('call json_decode("-1.")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 0.', exc_exec('call json_decode("0.")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e', exc_exec('call json_decode("0.0e")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e+', exc_exec('call json_decode("0.0e+")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e-', exc_exec('call json_decode("0.0e-")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e-', exc_exec('call json_decode("0.0e-")'))
|
||||
eq(
|
||||
'Vim(call):E474: Missing number after decimal dot: 1.e5',
|
||||
exc_exec('call json_decode("1.e5")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Missing number after decimal dot: 1.e+5',
|
||||
exc_exec('call json_decode("1.e+5")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Missing number after decimal dot: 1.e+',
|
||||
exc_exec('call json_decode("1.e+")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('parses floating-point numbers', function()
|
||||
@@ -202,25 +190,23 @@ describe('json_decode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to parse numbers with spaces inside', function()
|
||||
eq('Vim(call):E474: Missing number after minus sign: - 1000',
|
||||
exc_exec('call json_decode("- 1000")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 0. ',
|
||||
exc_exec('call json_decode("0. ")'))
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 0. 0',
|
||||
exc_exec('call json_decode("0. 0")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e 1',
|
||||
exc_exec('call json_decode("0.0e 1")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e+ 1',
|
||||
exc_exec('call json_decode("0.0e+ 1")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e- 1',
|
||||
exc_exec('call json_decode("0.0e- 1")'))
|
||||
eq(
|
||||
'Vim(call):E474: Missing number after minus sign: - 1000',
|
||||
exc_exec('call json_decode("- 1000")')
|
||||
)
|
||||
eq('Vim(call):E474: Missing number after decimal dot: 0. ', exc_exec('call json_decode("0. ")'))
|
||||
eq(
|
||||
'Vim(call):E474: Missing number after decimal dot: 0. 0',
|
||||
exc_exec('call json_decode("0. 0")')
|
||||
)
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e 1', exc_exec('call json_decode("0.0e 1")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e+ 1', exc_exec('call json_decode("0.0e+ 1")'))
|
||||
eq('Vim(call):E474: Missing exponent: 0.0e- 1', exc_exec('call json_decode("0.0e- 1")'))
|
||||
end)
|
||||
|
||||
it('fails to parse "," and ":"', function()
|
||||
eq('Vim(call):E474: Comma not inside container: , ',
|
||||
exc_exec('call json_decode(" , ")'))
|
||||
eq('Vim(call):E474: Colon not inside container: : ',
|
||||
exc_exec('call json_decode(" : ")'))
|
||||
eq('Vim(call):E474: Comma not inside container: , ', exc_exec('call json_decode(" , ")'))
|
||||
eq('Vim(call):E474: Colon not inside container: : ', exc_exec('call json_decode(" : ")'))
|
||||
end)
|
||||
|
||||
it('parses empty containers', function()
|
||||
@@ -229,123 +215,151 @@ describe('json_decode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to parse "[" and "{"', function()
|
||||
eq('Vim(call):E474: Unexpected end of input: {',
|
||||
exc_exec('call json_decode("{")'))
|
||||
eq('Vim(call):E474: Unexpected end of input: [',
|
||||
exc_exec('call json_decode("[")'))
|
||||
eq('Vim(call):E474: Unexpected end of input: {', exc_exec('call json_decode("{")'))
|
||||
eq('Vim(call):E474: Unexpected end of input: [', exc_exec('call json_decode("[")'))
|
||||
end)
|
||||
|
||||
it('fails to parse "}" and "]"', function()
|
||||
eq('Vim(call):E474: No container to close: ]',
|
||||
exc_exec('call json_decode("]")'))
|
||||
eq('Vim(call):E474: No container to close: }',
|
||||
exc_exec('call json_decode("}")'))
|
||||
eq('Vim(call):E474: No container to close: ]', exc_exec('call json_decode("]")'))
|
||||
eq('Vim(call):E474: No container to close: }', exc_exec('call json_decode("}")'))
|
||||
end)
|
||||
|
||||
it('fails to parse containers which are closed by different brackets',
|
||||
function()
|
||||
eq('Vim(call):E474: Closing dictionary with square bracket: ]',
|
||||
exc_exec('call json_decode("{]")'))
|
||||
eq('Vim(call):E474: Closing list with curly bracket: }',
|
||||
exc_exec('call json_decode("[}")'))
|
||||
it('fails to parse containers which are closed by different brackets', function()
|
||||
eq(
|
||||
'Vim(call):E474: Closing dictionary with square bracket: ]',
|
||||
exc_exec('call json_decode("{]")')
|
||||
)
|
||||
eq('Vim(call):E474: Closing list with curly bracket: }', exc_exec('call json_decode("[}")'))
|
||||
end)
|
||||
|
||||
it('fails to parse concat inside container', function()
|
||||
eq('Vim(call):E474: Expected comma before list item: []]',
|
||||
exc_exec('call json_decode("[[][]]")'))
|
||||
eq('Vim(call):E474: Expected comma before list item: {}]',
|
||||
exc_exec('call json_decode("[{}{}]")'))
|
||||
eq('Vim(call):E474: Expected comma before list item: ]',
|
||||
exc_exec('call json_decode("[1 2]")'))
|
||||
eq('Vim(call):E474: Expected comma before dictionary key: ": 4}',
|
||||
exc_exec('call json_decode("{\\"1\\": 2 \\"3\\": 4}")'))
|
||||
eq('Vim(call):E474: Expected colon before dictionary value: , "3" 4}',
|
||||
exc_exec('call json_decode("{\\"1\\" 2, \\"3\\" 4}")'))
|
||||
eq(
|
||||
'Vim(call):E474: Expected comma before list item: []]',
|
||||
exc_exec('call json_decode("[[][]]")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Expected comma before list item: {}]',
|
||||
exc_exec('call json_decode("[{}{}]")')
|
||||
)
|
||||
eq('Vim(call):E474: Expected comma before list item: ]', exc_exec('call json_decode("[1 2]")'))
|
||||
eq(
|
||||
'Vim(call):E474: Expected comma before dictionary key: ": 4}',
|
||||
exc_exec('call json_decode("{\\"1\\": 2 \\"3\\": 4}")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Expected colon before dictionary value: , "3" 4}',
|
||||
exc_exec('call json_decode("{\\"1\\" 2, \\"3\\" 4}")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to parse containers with leading comma or colon', function()
|
||||
eq('Vim(call):E474: Leading comma: ,}',
|
||||
exc_exec('call json_decode("{,}")'))
|
||||
eq('Vim(call):E474: Leading comma: ,]',
|
||||
exc_exec('call json_decode("[,]")'))
|
||||
eq('Vim(call):E474: Using colon not in dictionary: :]',
|
||||
exc_exec('call json_decode("[:]")'))
|
||||
eq('Vim(call):E474: Unexpected colon: :}',
|
||||
exc_exec('call json_decode("{:}")'))
|
||||
eq('Vim(call):E474: Leading comma: ,}', exc_exec('call json_decode("{,}")'))
|
||||
eq('Vim(call):E474: Leading comma: ,]', exc_exec('call json_decode("[,]")'))
|
||||
eq('Vim(call):E474: Using colon not in dictionary: :]', exc_exec('call json_decode("[:]")'))
|
||||
eq('Vim(call):E474: Unexpected colon: :}', exc_exec('call json_decode("{:}")'))
|
||||
end)
|
||||
|
||||
it('fails to parse containers with trailing comma', function()
|
||||
eq('Vim(call):E474: Trailing comma: ]',
|
||||
exc_exec('call json_decode("[1,]")'))
|
||||
eq('Vim(call):E474: Trailing comma: }',
|
||||
exc_exec('call json_decode("{\\"1\\": 2,}")'))
|
||||
eq('Vim(call):E474: Trailing comma: ]', exc_exec('call json_decode("[1,]")'))
|
||||
eq('Vim(call):E474: Trailing comma: }', exc_exec('call json_decode("{\\"1\\": 2,}")'))
|
||||
end)
|
||||
|
||||
it('fails to parse dictionaries with missing value', function()
|
||||
eq('Vim(call):E474: Expected value after colon: }',
|
||||
exc_exec('call json_decode("{\\"1\\":}")'))
|
||||
eq('Vim(call):E474: Expected value: }',
|
||||
exc_exec('call json_decode("{\\"1\\"}")'))
|
||||
eq('Vim(call):E474: Expected value after colon: }', exc_exec('call json_decode("{\\"1\\":}")'))
|
||||
eq('Vim(call):E474: Expected value: }', exc_exec('call json_decode("{\\"1\\"}")'))
|
||||
end)
|
||||
|
||||
it('fails to parse containers with two commas or colons', function()
|
||||
eq('Vim(call):E474: Duplicate comma: , "2": 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1,, \\"2\\": 2}")'))
|
||||
eq('Vim(call):E474: Duplicate comma: , "2", 2]',
|
||||
exc_exec('call json_decode("[\\"1\\", 1,, \\"2\\", 2]")'))
|
||||
eq('Vim(call):E474: Duplicate colon: : 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":: 2}")'))
|
||||
eq('Vim(call):E474: Comma after colon: , 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":, 2}")'))
|
||||
eq('Vim(call):E474: Unexpected colon: : "2": 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1,: \\"2\\": 2}")'))
|
||||
eq('Vim(call):E474: Unexpected colon: :, "2": 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1:, \\"2\\": 2}")'))
|
||||
eq(
|
||||
'Vim(call):E474: Duplicate comma: , "2": 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1,, \\"2\\": 2}")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Duplicate comma: , "2", 2]',
|
||||
exc_exec('call json_decode("[\\"1\\", 1,, \\"2\\", 2]")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Duplicate colon: : 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":: 2}")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Comma after colon: , 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1, \\"2\\":, 2}")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unexpected colon: : "2": 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1,: \\"2\\": 2}")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unexpected colon: :, "2": 2}',
|
||||
exc_exec('call json_decode("{\\"1\\": 1:, \\"2\\": 2}")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to parse concat of two values', function()
|
||||
eq('Vim(call):E474: Trailing characters: []',
|
||||
exc_exec('call json_decode("{}[]")'))
|
||||
eq('Vim(call):E474: Trailing characters: []', exc_exec('call json_decode("{}[]")'))
|
||||
end)
|
||||
|
||||
it('parses containers', function()
|
||||
eq({1}, funcs.json_decode('[1]'))
|
||||
eq({NIL, 1}, funcs.json_decode('[null, 1]'))
|
||||
eq({['1']=2}, funcs.json_decode('{"1": 2}'))
|
||||
eq({['1']=2, ['3']={{['4']={['5']={{}, 1}}}}},
|
||||
funcs.json_decode('{"1": 2, "3": [{"4": {"5": [[], 1]}}]}'))
|
||||
eq({ 1 }, funcs.json_decode('[1]'))
|
||||
eq({ NIL, 1 }, funcs.json_decode('[null, 1]'))
|
||||
eq({ ['1'] = 2 }, funcs.json_decode('{"1": 2}'))
|
||||
eq(
|
||||
{ ['1'] = 2, ['3'] = { { ['4'] = { ['5'] = { {}, 1 } } } } },
|
||||
funcs.json_decode('{"1": 2, "3": [{"4": {"5": [[], 1]}}]}')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to parse incomplete strings', function()
|
||||
eq('Vim(call):E474: Expected string end: \t"',
|
||||
exc_exec('call json_decode("\\t\\"")'))
|
||||
eq('Vim(call):E474: Expected string end: \t"abc',
|
||||
exc_exec('call json_decode("\\t\\"abc")'))
|
||||
eq('Vim(call):E474: Unfinished escape sequence: \t"abc\\',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\")'))
|
||||
eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u")'))
|
||||
eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u0',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u0")'))
|
||||
eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u00',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u00")'))
|
||||
eq('Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u000',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u000")'))
|
||||
eq('Vim(call):E474: Expected four hex digits after \\u: \\u" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u\\" ")'))
|
||||
eq('Vim(call):E474: Expected four hex digits after \\u: \\u0" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u0\\" ")'))
|
||||
eq('Vim(call):E474: Expected four hex digits after \\u: \\u00" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u00\\" ")'))
|
||||
eq('Vim(call):E474: Expected four hex digits after \\u: \\u000" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u000\\" ")'))
|
||||
eq('Vim(call):E474: Expected string end: \t"abc\\u0000',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u0000")'))
|
||||
eq('Vim(call):E474: Expected string end: \t"', exc_exec('call json_decode("\\t\\"")'))
|
||||
eq('Vim(call):E474: Expected string end: \t"abc', exc_exec('call json_decode("\\t\\"abc")'))
|
||||
eq(
|
||||
'Vim(call):E474: Unfinished escape sequence: \t"abc\\',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u0',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u0")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u00',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u00")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unfinished unicode escape sequence: \t"abc\\u000',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u000")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Expected four hex digits after \\u: \\u" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u\\" ")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Expected four hex digits after \\u: \\u0" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u0\\" ")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Expected four hex digits after \\u: \\u00" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u00\\" ")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Expected four hex digits after \\u: \\u000" ',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u000\\" ")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Expected string end: \t"abc\\u0000',
|
||||
exc_exec('call json_decode("\\t\\"abc\\\\u0000")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to parse unknown escape sequences', function()
|
||||
eq('Vim(call):E474: Unknown escape sequence: \\a"',
|
||||
exc_exec('call json_decode("\\t\\"\\\\a\\"")'))
|
||||
eq(
|
||||
'Vim(call):E474: Unknown escape sequence: \\a"',
|
||||
exc_exec('call json_decode("\\t\\"\\\\a\\"")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('parses strings properly', function()
|
||||
@@ -354,64 +368,105 @@ describe('json_decode() function', function()
|
||||
eq('\\/"\t\b\n\r\f', funcs.json_decode([["\\\/\"\t\b\n\r\f"]]))
|
||||
eq('/a', funcs.json_decode([["\/a"]]))
|
||||
-- Unicode characters: 2-byte, 3-byte, 4-byte
|
||||
eq({
|
||||
'«',
|
||||
'ફ',
|
||||
'\240\144\128\128',
|
||||
}, funcs.json_decode({
|
||||
'[',
|
||||
'"«",',
|
||||
'"ફ",',
|
||||
'"\240\144\128\128"',
|
||||
']',
|
||||
}))
|
||||
eq(
|
||||
{
|
||||
'«',
|
||||
'ફ',
|
||||
'\240\144\128\128',
|
||||
},
|
||||
funcs.json_decode({
|
||||
'[',
|
||||
'"«",',
|
||||
'"ફ",',
|
||||
'"\240\144\128\128"',
|
||||
']',
|
||||
})
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails on strings with invalid bytes', function()
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \255"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFF\\"")'))
|
||||
eq('Vim(call):E474: ASCII control characters cannot be present inside string: ',
|
||||
exc_exec('call json_decode(["\\"\\n\\""])'))
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \255"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFF\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: ASCII control characters cannot be present inside string: ',
|
||||
exc_exec('call json_decode(["\\"\\n\\""])')
|
||||
)
|
||||
-- 0xC2 starts 2-byte unicode character
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \194"',
|
||||
exc_exec('call json_decode("\\t\\"\\xC2\\"")'))
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \194"',
|
||||
exc_exec('call json_decode("\\t\\"\\xC2\\"")')
|
||||
)
|
||||
-- 0xE0 0xAA starts 3-byte unicode character
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \224"',
|
||||
exc_exec('call json_decode("\\t\\"\\xE0\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \224\170"',
|
||||
exc_exec('call json_decode("\\t\\"\\xE0\\xAA\\"")'))
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \224"',
|
||||
exc_exec('call json_decode("\\t\\"\\xE0\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \224\170"',
|
||||
exc_exec('call json_decode("\\t\\"\\xE0\\xAA\\"")')
|
||||
)
|
||||
-- 0xF0 0x90 0x80 starts 4-byte unicode character
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \240"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF0\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \240\144"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF0\\x90\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \240\144\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF0\\x90\\x80\\"")'))
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \240"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF0\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \240\144"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF0\\x90\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \240\144\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF0\\x90\\x80\\"")')
|
||||
)
|
||||
-- 0xF9 0x80 0x80 0x80 starts 5-byte unicode character
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \249"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \249\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \249\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \249\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\"")'))
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \249"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \249\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \249\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \249\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\"")')
|
||||
)
|
||||
-- 0xFC 0x90 0x80 0x80 0x80 starts 6-byte unicode character
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \252"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\"")'))
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \252"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \252\144"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \252\144\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 strings allowed: \252\144\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\"")')
|
||||
)
|
||||
-- Specification does not allow unquoted characters above 0x10FFFF
|
||||
eq('Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \249\128\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\x80\\"")'))
|
||||
eq('Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \252\144\128\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\x80\\"")'))
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \249\128\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xF9\\x80\\x80\\x80\\x80\\"")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \252\144\128\128\128\128"',
|
||||
exc_exec('call json_decode("\\t\\"\\xFC\\x90\\x80\\x80\\x80\\x80\\"")')
|
||||
)
|
||||
-- '"\249\128\128\128\128"',
|
||||
-- '"\252\144\128\128\128\128"',
|
||||
end)
|
||||
@@ -445,47 +500,105 @@ describe('json_decode() function', function()
|
||||
end
|
||||
|
||||
it('parses strings with NUL properly', function()
|
||||
sp_decode_eq({_TYPE='string', _VAL={'\n'}}, '"\\u0000"')
|
||||
sp_decode_eq({_TYPE='string', _VAL={'\n', '\n'}}, '"\\u0000\\n\\u0000"')
|
||||
sp_decode_eq({_TYPE='string', _VAL={'\n«\n'}}, '"\\u0000\\u00AB\\u0000"')
|
||||
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n' } }, '"\\u0000"')
|
||||
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n', '\n' } }, '"\\u0000\\n\\u0000"')
|
||||
sp_decode_eq({ _TYPE = 'string', _VAL = { '\n«\n' } }, '"\\u0000\\u00AB\\u0000"')
|
||||
end)
|
||||
|
||||
it('parses dictionaries with duplicate keys to special maps', function()
|
||||
sp_decode_eq({_TYPE='map', _VAL={{'a', 1}, {'a', 2}}},
|
||||
'{"a": 1, "a": 2}')
|
||||
sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'a', 2}}},
|
||||
'{"b": 3, "a": 1, "a": 2}')
|
||||
sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}}},
|
||||
'{"b": 3, "a": 1, "c": 4, "a": 2}')
|
||||
sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}},
|
||||
'{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}')
|
||||
sp_decode_eq({{_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}},
|
||||
'[{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}]')
|
||||
sp_decode_eq({{d={_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}}},
|
||||
'[{"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]')
|
||||
sp_decode_eq({1, {d={_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}}},
|
||||
'[1, {"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]')
|
||||
sp_decode_eq({1, {a={}, d={_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'a', 2}, {'c', 4}}}}},
|
||||
'[1, {"a": [], "d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]')
|
||||
sp_decode_eq({_TYPE='map', _VAL={{'', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {'', 4}}},
|
||||
'{"": 3, "a": 1, "c": 4, "d": 2, "": 4}')
|
||||
sp_decode_eq({{_TYPE='map', _VAL={{'', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {'', 4}}}},
|
||||
'[{"": 3, "a": 1, "c": 4, "d": 2, "": 4}]')
|
||||
sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a', 1 }, { 'a', 2 } } }, '{"a": 1, "a": 2}')
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'a', 2 } } },
|
||||
'{"b": 3, "a": 1, "a": 2}'
|
||||
)
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 } } },
|
||||
'{"b": 3, "a": 1, "c": 4, "a": 2}'
|
||||
)
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } } },
|
||||
'{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}'
|
||||
)
|
||||
sp_decode_eq(
|
||||
{ { _TYPE = 'map', _VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } } } },
|
||||
'[{"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}]'
|
||||
)
|
||||
sp_decode_eq({
|
||||
{
|
||||
d = {
|
||||
_TYPE = 'map',
|
||||
_VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } },
|
||||
},
|
||||
},
|
||||
}, '[{"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]')
|
||||
sp_decode_eq({
|
||||
1,
|
||||
{
|
||||
d = {
|
||||
_TYPE = 'map',
|
||||
_VAL = { { 'b', 3 }, { 'a', 1 }, { 'c', 4 }, { 'a', 2 }, { 'c', 4 } },
|
||||
},
|
||||
},
|
||||
}, '[1, {"d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]')
|
||||
sp_decode_eq({
|
||||
1,
|
||||
{
|
||||
a = {},
|
||||
d = {
|
||||
_TYPE = 'map',
|
||||
_VAL = {
|
||||
{ 'b', 3 },
|
||||
{ 'a', 1 },
|
||||
{ 'c', 4 },
|
||||
{ 'a', 2 },
|
||||
{
|
||||
'c',
|
||||
4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, '[1, {"a": [], "d": {"b": 3, "a": 1, "c": 4, "a": 2, "c": 4}}]')
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { '', 3 }, { 'a', 1 }, { 'c', 4 }, { 'd', 2 }, { '', 4 } } },
|
||||
'{"": 3, "a": 1, "c": 4, "d": 2, "": 4}'
|
||||
)
|
||||
sp_decode_eq(
|
||||
{ { _TYPE = 'map', _VAL = { { '', 3 }, { 'a', 1 }, { 'c', 4 }, { 'd', 2 }, { '', 4 } } } },
|
||||
'[{"": 3, "a": 1, "c": 4, "d": 2, "": 4}]'
|
||||
)
|
||||
end)
|
||||
|
||||
it('parses dictionaries with empty keys', function()
|
||||
eq({[""] = 4}, funcs.json_decode('{"": 4}'))
|
||||
eq({b = 3, a = 1, c = 4, d = 2, [""] = 4},
|
||||
funcs.json_decode('{"b": 3, "a": 1, "c": 4, "d": 2, "": 4}'))
|
||||
eq({ [''] = 4 }, funcs.json_decode('{"": 4}'))
|
||||
eq(
|
||||
{ b = 3, a = 1, c = 4, d = 2, [''] = 4 },
|
||||
funcs.json_decode('{"b": 3, "a": 1, "c": 4, "d": 2, "": 4}')
|
||||
)
|
||||
end)
|
||||
|
||||
it('parses dictionaries with keys with NUL bytes to special maps', function()
|
||||
sp_decode_eq({_TYPE='map', _VAL={{{_TYPE='string', _VAL={'a\n', 'b'}}, 4}}},
|
||||
'{"a\\u0000\\nb": 4}')
|
||||
sp_decode_eq({_TYPE='map', _VAL={{{_TYPE='string', _VAL={'a\n', 'b', ''}}, 4}}},
|
||||
'{"a\\u0000\\nb\\n": 4}')
|
||||
sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {{_TYPE='string', _VAL={'\n'}}, 4}}},
|
||||
'{"b": 3, "a": 1, "c": 4, "d": 2, "\\u0000": 4}')
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b' } }, 4 } } },
|
||||
'{"a\\u0000\\nb": 4}'
|
||||
)
|
||||
sp_decode_eq(
|
||||
{ _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b', '' } }, 4 } } },
|
||||
'{"a\\u0000\\nb\\n": 4}'
|
||||
)
|
||||
sp_decode_eq({
|
||||
_TYPE = 'map',
|
||||
_VAL = {
|
||||
{ 'b', 3 },
|
||||
{ 'a', 1 },
|
||||
{ 'c', 4 },
|
||||
{ 'd', 2 },
|
||||
{
|
||||
{ _TYPE = 'string', _VAL = { '\n' } },
|
||||
4,
|
||||
},
|
||||
},
|
||||
}, '{"b": 3, "a": 1, "c": 4, "d": 2, "\\u0000": 4}')
|
||||
end)
|
||||
|
||||
it('parses U+00C3 correctly', function()
|
||||
@@ -493,32 +606,30 @@ describe('json_decode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to parse empty string', function()
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode("")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode([])'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode([""])'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode(" ")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode("\\t")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode("\\n")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode(" \\t\\n \\n\\t\\t \\n\\t\\n \\n \\t\\n\\t ")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode("")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode([])'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode([""])'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode(" ")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode("\\t")'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string', exc_exec('call json_decode("\\n")'))
|
||||
eq(
|
||||
'Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode(" \\t\\n \\n\\t\\t \\n\\t\\n \\n \\t\\n\\t ")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('accepts all spaces in every position where space may be put', function()
|
||||
local s = ' \t\n\r \t\r\n \n\t\r \n\r\t \r\t\n \r\n\t\t \n\r\t \r\n\t\n \r\t\n\r \t\r \n\t\r\n \n \t\r\n \r\t\n\t \r\n\t\r \n\r \t\n\r\t \r \t\n\r \n\t\r\t \n\r\t\n \r\n \t\r\n\t'
|
||||
local s =
|
||||
' \t\n\r \t\r\n \n\t\r \n\r\t \r\t\n \r\n\t\t \n\r\t \r\n\t\n \r\t\n\r \t\r \n\t\r\n \n \t\r\n \r\t\n\t \r\n\t\r \n\r \t\n\r\t \r \t\n\r \n\t\r\t \n\r\t\n \r\n \t\r\n\t'
|
||||
local str = ('%s{%s"key"%s:%s[%s"val"%s,%s"val2"%s]%s,%s"key2"%s:%s1%s}%s'):gsub('%%s', s)
|
||||
eq({key={'val', 'val2'}, key2=1}, funcs.json_decode(str))
|
||||
eq({ key = { 'val', 'val2' }, key2 = 1 }, funcs.json_decode(str))
|
||||
end)
|
||||
|
||||
it('does not overflow when writing error message about decoding ["", ""]',
|
||||
function()
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
pcall_err(command, 'call json_decode(["", ""])'))
|
||||
it('does not overflow when writing error message about decoding ["", ""]', function()
|
||||
eq(
|
||||
'Vim(call):E474: Attempt to decode a blank string',
|
||||
pcall_err(command, 'call json_decode(["", ""])')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -558,30 +669,35 @@ describe('json_encode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to dump NaN and infinite values', function()
|
||||
eq('Vim(call):E474: Unable to represent NaN value in JSON',
|
||||
exc_exec('call json_encode(str2float("nan"))'))
|
||||
eq('Vim(call):E474: Unable to represent infinity in JSON',
|
||||
exc_exec('call json_encode(str2float("inf"))'))
|
||||
eq('Vim(call):E474: Unable to represent infinity in JSON',
|
||||
exc_exec('call json_encode(-str2float("inf"))'))
|
||||
eq(
|
||||
'Vim(call):E474: Unable to represent NaN value in JSON',
|
||||
exc_exec('call json_encode(str2float("nan"))')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unable to represent infinity in JSON',
|
||||
exc_exec('call json_encode(str2float("inf"))')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Unable to represent infinity in JSON',
|
||||
exc_exec('call json_encode(-str2float("inf"))')
|
||||
)
|
||||
end)
|
||||
|
||||
it('dumps lists', function()
|
||||
eq('[]', funcs.json_encode({}))
|
||||
eq('[[]]', funcs.json_encode({{}}))
|
||||
eq('[[], []]', funcs.json_encode({{}, {}}))
|
||||
eq('[[]]', funcs.json_encode({ {} }))
|
||||
eq('[[], []]', funcs.json_encode({ {}, {} }))
|
||||
end)
|
||||
|
||||
it('dumps dictionaries', function()
|
||||
eq('{}', eval('json_encode({})'))
|
||||
eq('{"d": []}', funcs.json_encode({d={}}))
|
||||
eq('{"d": [], "e": []}', funcs.json_encode({d={}, e={}}))
|
||||
eq('{"d": []}', funcs.json_encode({ d = {} }))
|
||||
eq('{"d": [], "e": []}', funcs.json_encode({ d = {}, e = {} }))
|
||||
-- Empty keys are allowed per JSON spec (and Vim dicts, and msgpack).
|
||||
eq('{"": []}', funcs.json_encode({['']={}}))
|
||||
eq('{"": []}', funcs.json_encode({ [''] = {} }))
|
||||
end)
|
||||
|
||||
it('cannot dump generic mapping with generic mapping keys and values',
|
||||
function()
|
||||
it('cannot dump generic mapping with generic mapping keys and values', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
@@ -674,33 +790,43 @@ describe('json_encode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to dump a function reference', function()
|
||||
eq('Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference',
|
||||
exc_exec('call json_encode(function("tr"))'))
|
||||
eq(
|
||||
'Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference',
|
||||
exc_exec('call json_encode(function("tr"))')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to dump a partial', function()
|
||||
command('function T() dict\nendfunction')
|
||||
eq('Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference',
|
||||
exc_exec('call json_encode(function("T", [1, 2], {}))'))
|
||||
eq(
|
||||
'Vim(call):E474: Error while dumping encode_tv2json() argument, itself: attempt to dump function reference',
|
||||
exc_exec('call json_encode(function("T", [1, 2], {}))')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to dump a function reference in a list', function()
|
||||
eq('Vim(call):E474: Error while dumping encode_tv2json() argument, index 0: attempt to dump function reference',
|
||||
exc_exec('call json_encode([function("tr")])'))
|
||||
eq(
|
||||
'Vim(call):E474: Error while dumping encode_tv2json() argument, index 0: attempt to dump function reference',
|
||||
exc_exec('call json_encode([function("tr")])')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive list', function()
|
||||
command('let todump = [[[]]]')
|
||||
command('call add(todump[0][0], todump)')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
eq(
|
||||
'Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive dict', function()
|
||||
command('let todump = {"d": {"d": {}}}')
|
||||
command('call extend(todump.d.d, {"d": todump})')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode([todump])'))
|
||||
eq(
|
||||
'Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode([todump])')
|
||||
)
|
||||
end)
|
||||
|
||||
it('can dump dict with two same dicts inside', function()
|
||||
@@ -718,40 +844,51 @@ describe('json_encode() function', function()
|
||||
it('fails to dump a recursive list in a special dict', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
command('call add(todump._VAL, todump)')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
eq(
|
||||
'Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) map in a special dict', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
|
||||
command('call add(todump._VAL, ["", todump])')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode([todump])'))
|
||||
eq(
|
||||
'Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode([todump])')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) map in a special dict, _VAL reference', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [["", []]]}')
|
||||
command('call add(todump._VAL[0][1], todump._VAL)')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
eq(
|
||||
'Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails to dump a recursive (val) special list in a special dict',
|
||||
function()
|
||||
it('fails to dump a recursive (val) special list in a special dict', function()
|
||||
command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
|
||||
command('call add(todump._VAL, ["", todump._VAL])')
|
||||
eq('Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)'))
|
||||
eq(
|
||||
'Vim(call):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('call json_encode(todump)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails when called with no arguments', function()
|
||||
eq('Vim(call):E119: Not enough arguments for function: json_encode',
|
||||
exc_exec('call json_encode()'))
|
||||
eq(
|
||||
'Vim(call):E119: Not enough arguments for function: json_encode',
|
||||
exc_exec('call json_encode()')
|
||||
)
|
||||
end)
|
||||
|
||||
it('fails when called with two arguments', function()
|
||||
eq('Vim(call):E118: Too many arguments for function: json_encode',
|
||||
exc_exec('call json_encode(["", ""], 1)'))
|
||||
eq(
|
||||
'Vim(call):E118: Too many arguments for function: json_encode',
|
||||
exc_exec('call json_encode(["", ""], 1)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('ignores improper values in &isprint', function()
|
||||
@@ -761,15 +898,23 @@ describe('json_encode() function', function()
|
||||
end)
|
||||
|
||||
it('fails when using surrogate character in a UTF-8 string', function()
|
||||
eq('Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\160\128',
|
||||
exc_exec('call json_encode("\237\160\128")'))
|
||||
eq('Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\175\191',
|
||||
exc_exec('call json_encode("\237\175\191")'))
|
||||
eq(
|
||||
'Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\160\128',
|
||||
exc_exec('call json_encode("\237\160\128")')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: UTF-8 string contains code point which belongs to a surrogate pair: \237\175\191',
|
||||
exc_exec('call json_encode("\237\175\191")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('dumps control characters as expected', function()
|
||||
eq([["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000B\f\r\u000E\u000F\u0010\u0011\u0012\u0013"]],
|
||||
eval('json_encode({"_TYPE": v:msgpack_types.string, "_VAL": ["\n\1\2\3\4\5\6\7\8\9", "\11\12\13\14\15\16\17\18\19"]})'))
|
||||
eq(
|
||||
[["\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000B\f\r\u000E\u000F\u0010\u0011\u0012\u0013"]],
|
||||
eval(
|
||||
'json_encode({"_TYPE": v:msgpack_types.string, "_VAL": ["\n\1\2\3\4\5\6\7\8\9", "\11\12\13\14\15\16\17\18\19"]})'
|
||||
)
|
||||
)
|
||||
end)
|
||||
|
||||
it('can dump NULL string', function()
|
||||
@@ -789,9 +934,13 @@ describe('json_encode() function', function()
|
||||
end)
|
||||
|
||||
it('fails to parse NULL strings and lists', function()
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode($XXX_UNEXISTENT_VAR_XXX)'))
|
||||
eq('Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode(v:_null_list)'))
|
||||
eq(
|
||||
'Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode($XXX_UNEXISTENT_VAR_XXX)')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E474: Attempt to decode a blank string',
|
||||
exc_exec('call json_decode(v:_null_list)')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('vimscript', function()
|
||||
|
||||
it('parses `<SID>` with turkish locale', function()
|
||||
if exc_exec('lang ctype tr_TR.UTF-8') ~= 0 then
|
||||
pending("Locale tr_TR.UTF-8 not supported")
|
||||
pending('Locale tr_TR.UTF-8 not supported')
|
||||
return
|
||||
end
|
||||
source([[
|
||||
@@ -22,10 +22,10 @@ describe('vimscript', function()
|
||||
|
||||
it('str2float is not affected by locale', function()
|
||||
if exc_exec('lang ctype sv_SE.UTF-8') ~= 0 then
|
||||
pending("Locale sv_SE.UTF-8 not supported")
|
||||
pending('Locale sv_SE.UTF-8 not supported')
|
||||
return
|
||||
end
|
||||
clear{env={LANG="", LC_NUMERIC="sv_SE.UTF-8"}}
|
||||
clear { env = { LANG = '', LC_NUMERIC = 'sv_SE.UTF-8' } }
|
||||
eq(2.2, eval('str2float("2.2")'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -15,21 +15,24 @@ before_each(clear)
|
||||
|
||||
describe(':let', function()
|
||||
it('correctly lists variables with curly-braces', function()
|
||||
meths.set_var('v', {0})
|
||||
meths.set_var('v', { 0 })
|
||||
eq('v [0]', exec_capture('let {"v"}'))
|
||||
end)
|
||||
|
||||
it('correctly lists variables with subscript', function()
|
||||
meths.set_var('v', {0})
|
||||
meths.set_var('v', { 0 })
|
||||
eq('v[0] #0', exec_capture('let v[0]'))
|
||||
eq('g:["v"][0] #0', exec_capture('let g:["v"][0]'))
|
||||
eq('{"g:"}["v"][0] #0', exec_capture('let {"g:"}["v"][0]'))
|
||||
end)
|
||||
|
||||
it(":unlet self-referencing node in a List graph #6070", function()
|
||||
it(':unlet self-referencing node in a List graph #6070', function()
|
||||
-- :unlet-ing a self-referencing List must not allow GC on indirectly
|
||||
-- referenced in-scope Lists. Before #6070 this caused use-after-free.
|
||||
expect_exit(1000, source, [=[
|
||||
expect_exit(
|
||||
1000,
|
||||
source,
|
||||
[=[
|
||||
let [l1, l2] = [[], []]
|
||||
echo 'l1:' . id(l1)
|
||||
echo 'l2:' . id(l2)
|
||||
@@ -45,10 +48,11 @@ describe(':let', function()
|
||||
unlet l4
|
||||
call garbagecollect(1)
|
||||
call feedkeys(":\e:echo l1 l3\n:echo 42\n:cq\n", "t")
|
||||
]=])
|
||||
]=]
|
||||
)
|
||||
end)
|
||||
|
||||
it("multibyte env var #8398 #9267", function()
|
||||
it('multibyte env var #8398 #9267', function()
|
||||
command("let $NVIM_TEST_LET = 'AìaB'")
|
||||
eq('AìaB', eval('$NVIM_TEST_LET'))
|
||||
command("let $NVIM_TEST_LET = 'AaあB'")
|
||||
@@ -56,12 +60,14 @@ describe(':let', function()
|
||||
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
|
||||
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
|
||||
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
|
||||
command("let $NVIM_TEST_LET = '"..mbyte.."'")
|
||||
command("let $NVIM_TEST_LET = '" .. mbyte .. "'")
|
||||
eq(mbyte, eval('$NVIM_TEST_LET'))
|
||||
end)
|
||||
|
||||
it("multibyte env var to child process #8398 #9267", function()
|
||||
local cmd_get_child_env = ("let g:env_from_child = system(['%s', 'NVIM_TEST_LET'])"):format(testprg('printenv-test'))
|
||||
it('multibyte env var to child process #8398 #9267', function()
|
||||
local cmd_get_child_env = ("let g:env_from_child = system(['%s', 'NVIM_TEST_LET'])"):format(
|
||||
testprg('printenv-test')
|
||||
)
|
||||
command("let $NVIM_TEST_LET = 'AìaB'")
|
||||
command(cmd_get_child_env)
|
||||
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
|
||||
@@ -73,12 +79,12 @@ describe(':let', function()
|
||||
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
|
||||
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
|
||||
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
|
||||
command("let $NVIM_TEST_LET = '"..mbyte.."'")
|
||||
command("let $NVIM_TEST_LET = '" .. mbyte .. "'")
|
||||
command(cmd_get_child_env)
|
||||
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
|
||||
end)
|
||||
|
||||
it("release of list assigned to l: variable does not trigger assertion #12387, #12430", function()
|
||||
it('release of list assigned to l: variable does not trigger assertion #12387, #12430', function()
|
||||
source([[
|
||||
func! s:f()
|
||||
let l:x = [1]
|
||||
|
||||
@@ -19,22 +19,22 @@ describe('maparg()', function()
|
||||
before_each(clear)
|
||||
|
||||
local foo_bar_map_table = {
|
||||
lhs='foo',
|
||||
lhsraw='foo',
|
||||
script=0,
|
||||
silent=0,
|
||||
rhs='bar',
|
||||
expr=0,
|
||||
sid=0,
|
||||
scriptversion=1,
|
||||
buffer=0,
|
||||
nowait=0,
|
||||
mode='n',
|
||||
mode_bits=0x01,
|
||||
abbr=0,
|
||||
noremap=1,
|
||||
lnum=0,
|
||||
}
|
||||
lhs = 'foo',
|
||||
lhsraw = 'foo',
|
||||
script = 0,
|
||||
silent = 0,
|
||||
rhs = 'bar',
|
||||
expr = 0,
|
||||
sid = 0,
|
||||
scriptversion = 1,
|
||||
buffer = 0,
|
||||
nowait = 0,
|
||||
mode = 'n',
|
||||
mode_bits = 0x01,
|
||||
abbr = 0,
|
||||
noremap = 1,
|
||||
lnum = 0,
|
||||
}
|
||||
|
||||
it('returns a dictionary', function()
|
||||
nvim('command', 'nnoremap foo bar')
|
||||
@@ -64,7 +64,7 @@ describe('maparg()', function()
|
||||
eq(
|
||||
funcs.maparg('hello', 'i', false, true)['noremap'],
|
||||
funcs.maparg('this', 'i', false, true)['noremap']
|
||||
)
|
||||
)
|
||||
end)
|
||||
|
||||
it('returns a boolean for buffer', function()
|
||||
@@ -135,7 +135,7 @@ describe('maparg()', function()
|
||||
it('works with combining characters', function()
|
||||
-- Using addacutes to make combining character better visible
|
||||
local function ac(s)
|
||||
local acute = '\204\129' -- U+0301 COMBINING ACUTE ACCENT
|
||||
local acute = '\204\129' -- U+0301 COMBINING ACUTE ACCENT
|
||||
local ret = s:gsub('`', acute)
|
||||
return ret
|
||||
end
|
||||
@@ -145,8 +145,8 @@ describe('maparg()', function()
|
||||
nnoremap e` f`
|
||||
]]))
|
||||
eq(ac('b`'), funcs.maparg(ac('a')))
|
||||
eq(ac(''), funcs.maparg(ac('c')))
|
||||
eq(ac('d'), funcs.maparg(ac('c`')))
|
||||
eq(ac(''), funcs.maparg(ac('c')))
|
||||
eq(ac('d'), funcs.maparg(ac('c`')))
|
||||
eq(ac('f`'), funcs.maparg(ac('e`')))
|
||||
|
||||
local function acmap(lhs, rhs)
|
||||
@@ -170,9 +170,9 @@ describe('maparg()', function()
|
||||
}
|
||||
end
|
||||
|
||||
eq({}, funcs.maparg(ac('c'), 'n', 0, 1))
|
||||
eq(acmap('a', 'b`'), funcs.maparg(ac('a'), 'n', 0, 1))
|
||||
eq(acmap('c`', 'd'), funcs.maparg(ac('c`'), 'n', 0, 1))
|
||||
eq({}, funcs.maparg(ac('c'), 'n', 0, 1))
|
||||
eq(acmap('a', 'b`'), funcs.maparg(ac('a'), 'n', 0, 1))
|
||||
eq(acmap('c`', 'd'), funcs.maparg(ac('c`'), 'n', 0, 1))
|
||||
eq(acmap('e`', 'f`'), funcs.maparg(ac('e`'), 'n', 0, 1))
|
||||
end)
|
||||
end)
|
||||
@@ -182,30 +182,30 @@ describe('mapset()', function()
|
||||
|
||||
it('can restore mapping with backslash in lhs', function()
|
||||
meths.set_keymap('n', '\\ab', 'a', {})
|
||||
eq('\nn \\ab a', exec_capture("nmap \\ab"))
|
||||
eq('\nn \\ab a', exec_capture('nmap \\ab'))
|
||||
local mapargs = funcs.maparg('\\ab', 'n', false, true)
|
||||
meths.set_keymap('n', '\\ab', 'b', {})
|
||||
eq('\nn \\ab b', exec_capture("nmap \\ab"))
|
||||
eq('\nn \\ab b', exec_capture('nmap \\ab'))
|
||||
funcs.mapset('n', false, mapargs)
|
||||
eq('\nn \\ab a', exec_capture("nmap \\ab"))
|
||||
eq('\nn \\ab a', exec_capture('nmap \\ab'))
|
||||
end)
|
||||
|
||||
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', exec_capture("nmap lhs"))
|
||||
meths.set_keymap('n', 'lhs', 'rhs', { desc = 'map description' })
|
||||
eq('\nn lhs rhs\n map description', exec_capture('nmap lhs'))
|
||||
local mapargs = funcs.maparg('lhs', 'n', false, true)
|
||||
meths.set_keymap('n', 'lhs', 'rhs', {desc = 'MAP DESCRIPTION'})
|
||||
eq('\nn lhs rhs\n MAP DESCRIPTION', 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', 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()
|
||||
meths.set_keymap('i', 'foo', [['<l' .. 't>']], {expr = true, replace_keycodes = true})
|
||||
meths.set_keymap('i', 'foo', [['<l' .. 't>']], { expr = true, replace_keycodes = true })
|
||||
feed('Afoo')
|
||||
expect('<')
|
||||
local mapargs = funcs.maparg('foo', 'i', false, true)
|
||||
meths.set_keymap('i', 'foo', [['<l' .. 't>']], {expr = true})
|
||||
meths.set_keymap('i', 'foo', [['<l' .. 't>']], { expr = true })
|
||||
feed('foo')
|
||||
expect('<<lt>')
|
||||
funcs.mapset('i', false, mapargs)
|
||||
@@ -230,11 +230,14 @@ describe('mapset()', function()
|
||||
end)
|
||||
|
||||
it('can restore Lua callback from the dict returned by maparg()', function()
|
||||
eq(0, exec_lua([[
|
||||
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]]))
|
||||
|
||||
@@ -262,9 +265,13 @@ describe('mapset()', function()
|
||||
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})]]))
|
||||
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)
|
||||
|
||||
@@ -10,146 +10,191 @@ local exc_exec = helpers.exc_exec
|
||||
before_each(clear)
|
||||
|
||||
describe('setmatches()', function()
|
||||
it('correctly handles case when both group and pattern entries are numbers',
|
||||
function()
|
||||
it('correctly handles case when both group and pattern entries are numbers', function()
|
||||
command('hi def link 1 PreProc')
|
||||
eq(0, funcs.setmatches({{group=1, pattern=2, id=3, priority=4}}))
|
||||
eq({{
|
||||
group='1',
|
||||
pattern='2',
|
||||
id=3,
|
||||
priority=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(0, funcs.setmatches({{group=1, pattern=2, id=3, priority=4, conceal=5}}))
|
||||
eq({{
|
||||
group='1',
|
||||
pattern='2',
|
||||
id=3,
|
||||
priority=4,
|
||||
conceal='5',
|
||||
}}, funcs.getmatches())
|
||||
eq(0, funcs.setmatches({{group=1, pos1={2}, pos2={6}, id=3, priority=4, conceal=5}}))
|
||||
eq({{
|
||||
group='1',
|
||||
pos1={2},
|
||||
pos2={6},
|
||||
id=3,
|
||||
priority=4,
|
||||
conceal='5',
|
||||
}}, funcs.getmatches())
|
||||
eq(0, funcs.setmatches({ { group = 1, pattern = 2, id = 3, priority = 4 } }))
|
||||
eq({
|
||||
{
|
||||
group = '1',
|
||||
pattern = '2',
|
||||
id = 3,
|
||||
priority = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
eq(0, funcs.setmatches({ { group = 1, pattern = 2, id = 3, priority = 4, conceal = 5 } }))
|
||||
eq({
|
||||
{
|
||||
group = '1',
|
||||
pattern = '2',
|
||||
id = 3,
|
||||
priority = 4,
|
||||
conceal = '5',
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
eq(
|
||||
0,
|
||||
funcs.setmatches({
|
||||
{ group = 1, pos1 = { 2 }, pos2 = { 6 }, id = 3, priority = 4, conceal = 5 },
|
||||
})
|
||||
)
|
||||
eq({
|
||||
{
|
||||
group = '1',
|
||||
pos1 = { 2 },
|
||||
pos2 = { 6 },
|
||||
id = 3,
|
||||
priority = 4,
|
||||
conceal = '5',
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
end)
|
||||
|
||||
it('does not fail if highlight group is not defined', function()
|
||||
eq(0, funcs.setmatches{{group=1, pattern=2, id=3, priority=4}})
|
||||
eq({{group='1', pattern='2', id=3, priority=4}},
|
||||
funcs.getmatches())
|
||||
eq(0, funcs.setmatches{{group=1, pos1={2}, pos2={6}, id=3, priority=4, conceal=5}})
|
||||
eq({{group='1', pos1={2}, pos2={6}, id=3, priority=4, conceal='5'}},
|
||||
funcs.getmatches())
|
||||
eq(0, funcs.setmatches { { group = 1, pattern = 2, id = 3, priority = 4 } })
|
||||
eq({ { group = '1', pattern = '2', id = 3, priority = 4 } }, funcs.getmatches())
|
||||
eq(
|
||||
0,
|
||||
funcs.setmatches {
|
||||
{ group = 1, pos1 = { 2 }, pos2 = { 6 }, id = 3, priority = 4, conceal = 5 },
|
||||
}
|
||||
)
|
||||
eq(
|
||||
{ { group = '1', pos1 = { 2 }, pos2 = { 6 }, id = 3, priority = 4, conceal = '5' } },
|
||||
funcs.getmatches()
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('matchadd()', function()
|
||||
it('correctly works when first two arguments and conceal are numbers at once',
|
||||
function()
|
||||
it('correctly works when first two arguments and conceal are numbers at once', function()
|
||||
command('hi def link 1 PreProc')
|
||||
eq(4, funcs.matchadd(1, 2, 3, 4, {conceal=5}))
|
||||
eq({{
|
||||
group='1',
|
||||
pattern='2',
|
||||
priority=3,
|
||||
id=4,
|
||||
conceal='5',
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchadd(1, 2, 3, 4, { conceal = 5 }))
|
||||
eq({
|
||||
{
|
||||
group = '1',
|
||||
pattern = '2',
|
||||
priority = 3,
|
||||
id = 4,
|
||||
conceal = '5',
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('matchaddpos()', function()
|
||||
it('errors out on invalid input', function()
|
||||
command('hi clear PreProc')
|
||||
eq('Vim(let):E5030: Empty list at position 0',
|
||||
exc_exec('let val = matchaddpos("PreProc", [[]])'))
|
||||
eq('Vim(let):E5030: Empty list at position 1',
|
||||
exc_exec('let val = matchaddpos("PreProc", [1, v:_null_list])'))
|
||||
eq('Vim(let):E5031: List or number required at position 1',
|
||||
exc_exec('let val = matchaddpos("PreProc", [1, v:_null_dict])'))
|
||||
eq(
|
||||
'Vim(let):E5030: Empty list at position 0',
|
||||
exc_exec('let val = matchaddpos("PreProc", [[]])')
|
||||
)
|
||||
eq(
|
||||
'Vim(let):E5030: Empty list at position 1',
|
||||
exc_exec('let val = matchaddpos("PreProc", [1, v:_null_list])')
|
||||
)
|
||||
eq(
|
||||
'Vim(let):E5031: List or number required at position 1',
|
||||
exc_exec('let val = matchaddpos("PreProc", [1, v:_null_dict])')
|
||||
)
|
||||
end)
|
||||
it('works with 0 lnum', function()
|
||||
command('hi clear PreProc')
|
||||
eq(4, funcs.matchaddpos('PreProc', {1}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchaddpos('PreProc', { 1 }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
funcs.matchdelete(4)
|
||||
eq(4, funcs.matchaddpos('PreProc', {{0}, 1}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchaddpos('PreProc', { { 0 }, 1 }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
funcs.matchdelete(4)
|
||||
eq(4, funcs.matchaddpos('PreProc', {0, 1}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchaddpos('PreProc', { 0, 1 }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
end)
|
||||
it('works with negative numbers', function()
|
||||
command('hi clear PreProc')
|
||||
eq(4, funcs.matchaddpos('PreProc', {-10, 1}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchaddpos('PreProc', { -10, 1 }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
funcs.matchdelete(4)
|
||||
eq(4, funcs.matchaddpos('PreProc', {{-10}, 1}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchaddpos('PreProc', { { -10 }, 1 }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
funcs.matchdelete(4)
|
||||
eq(4, funcs.matchaddpos('PreProc', {{2, -1}, 1}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchaddpos('PreProc', { { 2, -1 }, 1 }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
funcs.matchdelete(4)
|
||||
eq(4, funcs.matchaddpos('PreProc', {{2, 0, -1}, 1}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
eq(4, funcs.matchaddpos('PreProc', { { 2, 0, -1 }, 1 }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
end)
|
||||
it('works with zero length', function()
|
||||
local screen = Screen.new(40, 5)
|
||||
screen:attach()
|
||||
funcs.setline(1, 'abcdef')
|
||||
command('hi PreProc guifg=Red')
|
||||
eq(4, funcs.matchaddpos('PreProc', {{1, 2, 0}}, 3, 4))
|
||||
eq({{
|
||||
group='PreProc',
|
||||
pos1 = {1, 2, 0},
|
||||
priority=3,
|
||||
id=4,
|
||||
}}, funcs.getmatches())
|
||||
screen:expect([[
|
||||
eq(4, funcs.matchaddpos('PreProc', { { 1, 2, 0 } }, 3, 4))
|
||||
eq({
|
||||
{
|
||||
group = 'PreProc',
|
||||
pos1 = { 1, 2, 0 },
|
||||
priority = 3,
|
||||
id = 4,
|
||||
},
|
||||
}, funcs.getmatches())
|
||||
screen:expect(
|
||||
[[
|
||||
^a{1:b}cdef |
|
||||
{2:~ }|*3
|
||||
|
|
||||
]], {[1] = {foreground = Screen.colors.Red}, [2] = {bold = true, foreground = Screen.colors.Blue1}})
|
||||
]],
|
||||
{
|
||||
[1] = { foreground = Screen.colors.Red },
|
||||
[2] = { bold = true, foreground = Screen.colors.Blue1 },
|
||||
}
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -8,14 +8,17 @@ local funcs = helpers.funcs
|
||||
local pcall_err = helpers.pcall_err
|
||||
|
||||
before_each(clear)
|
||||
for _, func in ipairs({'min', 'max'}) do
|
||||
for _, func in ipairs({ 'min', 'max' }) do
|
||||
describe(func .. '()', function()
|
||||
it('gives a single error message when multiple values failed conversions',
|
||||
function()
|
||||
eq('Vim(echo):E745: Using a List as a Number',
|
||||
pcall_err(command, 'echo ' .. func .. '([-5, [], [], [], 5])'))
|
||||
eq('Vim(echo):E745: Using a List as a Number',
|
||||
pcall_err(command, 'echo ' .. func .. '({1:-5, 2:[], 3:[], 4:[], 5:5})'))
|
||||
it('gives a single error message when multiple values failed conversions', function()
|
||||
eq(
|
||||
'Vim(echo):E745: Using a List as a Number',
|
||||
pcall_err(command, 'echo ' .. func .. '([-5, [], [], [], 5])')
|
||||
)
|
||||
eq(
|
||||
'Vim(echo):E745: Using a List as a Number',
|
||||
pcall_err(command, 'echo ' .. func .. '({1:-5, 2:[], 3:[], 4:[], 5:5})')
|
||||
)
|
||||
for errmsg, errinput in pairs({
|
||||
['Vim(echo):E745: Using a List as a Number'] = '[]',
|
||||
['Vim(echo):E805: Using a Float as a Number'] = '0.0',
|
||||
@@ -31,18 +34,26 @@ for _, func in ipairs({'min', 'max'}) do
|
||||
eq(0, eval(func .. '({})'))
|
||||
end)
|
||||
it('works with arrays/dictionaries with one item', function()
|
||||
eq(5, funcs[func]({5}))
|
||||
eq(5, funcs[func]({test=5}))
|
||||
eq(5, funcs[func]({ 5 }))
|
||||
eq(5, funcs[func]({ test = 5 }))
|
||||
end)
|
||||
it('works with NULL arrays/dictionaries', function()
|
||||
eq(0, eval(func .. '(v:_null_list)'))
|
||||
eq(0, eval(func .. '(v:_null_dict)'))
|
||||
end)
|
||||
it('errors out for invalid types', function()
|
||||
for _, errinput in ipairs({'1', 'v:true', 'v:false', 'v:null',
|
||||
'function("tr")', '""'}) do
|
||||
eq(('Vim(echo):E712: Argument of %s() must be a List or Dictionary'):format(func),
|
||||
pcall_err(command, 'echo ' .. func .. '(' .. errinput .. ')'))
|
||||
for _, errinput in ipairs({
|
||||
'1',
|
||||
'v:true',
|
||||
'v:false',
|
||||
'v:null',
|
||||
'function("tr")',
|
||||
'""',
|
||||
}) do
|
||||
eq(
|
||||
('Vim(echo):E712: Argument of %s() must be a List or Dictionary'):format(func),
|
||||
pcall_err(command, 'echo ' .. func .. '(' .. errinput .. ')')
|
||||
)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
|
||||
local assert_alive = helpers.assert_alive
|
||||
local clear, command, write_file = helpers.clear, helpers.command, helpers.write_file
|
||||
|
||||
describe("modeline", function()
|
||||
describe('modeline', function()
|
||||
local tempfile = helpers.tmpname()
|
||||
before_each(clear)
|
||||
|
||||
|
||||
@@ -40,8 +40,7 @@ describe('NULL', function()
|
||||
end
|
||||
local null_expr_test = function(name, expr, err, val, after)
|
||||
it(name, function()
|
||||
eq((err == 0) and ('') or ('\n' .. err),
|
||||
redir_exec('let g:_var = ' .. expr))
|
||||
eq((err == 0) and '' or ('\n' .. err), redir_exec('let g:_var = ' .. expr))
|
||||
if val == nil then
|
||||
eq(0, funcs.exists('g:_var'))
|
||||
else
|
||||
@@ -58,25 +57,31 @@ describe('NULL', function()
|
||||
null_expr_test('is equal to empty list (reverse order)', '[] == L', 0, 1)
|
||||
|
||||
-- Correct behaviour
|
||||
null_test('can be :unlet item with error message for empty list', ':unlet L[0]',
|
||||
'Vim(unlet):E684: List index out of range: 0')
|
||||
null_expr_test('can be indexed with error message for empty list', 'L[0]',
|
||||
'E684: List index out of range: 0', nil)
|
||||
null_test(
|
||||
'can be :unlet item with error message for empty list',
|
||||
':unlet L[0]',
|
||||
'Vim(unlet):E684: List index out of range: 0'
|
||||
)
|
||||
null_expr_test(
|
||||
'can be indexed with error message for empty list',
|
||||
'L[0]',
|
||||
'E684: List index out of range: 0',
|
||||
nil
|
||||
)
|
||||
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(0, L)', 0, 0, function()
|
||||
eq({''}, curbufmeths.get_lines(0, -1, false))
|
||||
eq({ '' }, curbufmeths.get_lines(0, -1, false))
|
||||
end)
|
||||
null_expr_test('does not crash setline()', 'setline(1, L)', 0, 0, function()
|
||||
eq({''}, curbufmeths.get_lines(0, -1, false))
|
||||
eq({ '' }, curbufmeths.get_lines(0, -1, false))
|
||||
end)
|
||||
null_expr_test('is identical to itself', 'L is L', 0, 1)
|
||||
null_expr_test('can be sliced', 'L[:]', 0, {})
|
||||
null_expr_test('can be copied', 'copy(L)', 0, {})
|
||||
null_expr_test('can be deepcopied', 'deepcopy(L)', 0, {})
|
||||
null_expr_test('does not crash when indexed', 'L[1]',
|
||||
'E684: List index out of range: 1', nil)
|
||||
null_expr_test('does not crash when indexed', 'L[1]', 'E684: List index out of range: 1', nil)
|
||||
null_expr_test('does not crash call()', 'call("arglistid", L)', 0, 0)
|
||||
null_expr_test('does not crash col()', 'col(L)', 0, 0)
|
||||
null_expr_test('does not crash virtcol()', 'virtcol(L)', 0, 0)
|
||||
@@ -96,44 +101,92 @@ describe('NULL', function()
|
||||
null_test('does not crash lockvar', 'lockvar! L', 0)
|
||||
null_expr_test('can be added to itself', '(L + L)', 0, {})
|
||||
null_expr_test('can be added to itself', '(L + L) is L', 0, 1)
|
||||
null_expr_test('can be added to non-empty list', '([1] + L)', 0, {1})
|
||||
null_expr_test('can be added to non-empty list (reversed)', '(L + [1])', 0, {1})
|
||||
null_expr_test('can be added to non-empty list', '([1] + L)', 0, { 1 })
|
||||
null_expr_test('can be added to non-empty list (reversed)', '(L + [1])', 0, { 1 })
|
||||
null_expr_test('is equal to itself', 'L == L', 0, 1)
|
||||
null_expr_test('is not not equal to itself', 'L != L', 0, 0)
|
||||
null_expr_test('counts correctly', 'count([L], L)', 0, 1)
|
||||
null_expr_test('makes map() return v:_null_list', 'map(L, "v:val") is# L', 0, 1)
|
||||
null_expr_test('makes filter() return v:_null_list', 'filter(L, "1") is# L', 0, 1)
|
||||
null_test('is treated by :let as empty list', ':let [l] = L', 'Vim(let):E688: More targets than List items')
|
||||
null_expr_test('is accepted as an empty list by inputlist()', '[feedkeys("\\n"), inputlist(L)]',
|
||||
'Type number and <Enter> or click with the mouse (q or empty cancels): ', {0, 0})
|
||||
null_expr_test('is accepted as an empty list by writefile()',
|
||||
('[writefile(L, "%s"), readfile("%s")]'):format(tmpfname, tmpfname),
|
||||
0, {0, {}})
|
||||
null_expr_test('makes add() error out', 'add(L, 0)',
|
||||
'E742: Cannot change value of add() argument', 1)
|
||||
null_expr_test('makes insert() error out', 'insert(L, 1)',
|
||||
'E742: Cannot change value of insert() argument', 0)
|
||||
null_expr_test('does not crash remove()', 'remove(L, 0)',
|
||||
'E742: Cannot change value of remove() argument', 0)
|
||||
null_expr_test('makes reverse() error out', 'reverse(L)',
|
||||
'E742: Cannot change value of reverse() argument', 0)
|
||||
null_expr_test('makes sort() error out', 'sort(L)',
|
||||
'E742: Cannot change value of sort() argument', 0)
|
||||
null_expr_test('makes uniq() error out', 'uniq(L)',
|
||||
'E742: Cannot change value of uniq() argument', 0)
|
||||
null_expr_test('does not crash extend()', 'extend(L, [1])', 'E742: Cannot change value of extend() argument', 0)
|
||||
null_expr_test('does not crash extend() (second position)', 'extend([1], L)', 0, {1})
|
||||
null_test(
|
||||
'is treated by :let as empty list',
|
||||
':let [l] = L',
|
||||
'Vim(let):E688: More targets than List items'
|
||||
)
|
||||
null_expr_test(
|
||||
'is accepted as an empty list by inputlist()',
|
||||
'[feedkeys("\\n"), inputlist(L)]',
|
||||
'Type number and <Enter> or click with the mouse (q or empty cancels): ',
|
||||
{ 0, 0 }
|
||||
)
|
||||
null_expr_test(
|
||||
'is accepted as an empty list by writefile()',
|
||||
('[writefile(L, "%s"), readfile("%s")]'):format(tmpfname, tmpfname),
|
||||
0,
|
||||
{ 0, {} }
|
||||
)
|
||||
null_expr_test(
|
||||
'makes add() error out',
|
||||
'add(L, 0)',
|
||||
'E742: Cannot change value of add() argument',
|
||||
1
|
||||
)
|
||||
null_expr_test(
|
||||
'makes insert() error out',
|
||||
'insert(L, 1)',
|
||||
'E742: Cannot change value of insert() argument',
|
||||
0
|
||||
)
|
||||
null_expr_test(
|
||||
'does not crash remove()',
|
||||
'remove(L, 0)',
|
||||
'E742: Cannot change value of remove() argument',
|
||||
0
|
||||
)
|
||||
null_expr_test(
|
||||
'makes reverse() error out',
|
||||
'reverse(L)',
|
||||
'E742: Cannot change value of reverse() argument',
|
||||
0
|
||||
)
|
||||
null_expr_test(
|
||||
'makes sort() error out',
|
||||
'sort(L)',
|
||||
'E742: Cannot change value of sort() argument',
|
||||
0
|
||||
)
|
||||
null_expr_test(
|
||||
'makes uniq() error out',
|
||||
'uniq(L)',
|
||||
'E742: Cannot change value of uniq() argument',
|
||||
0
|
||||
)
|
||||
null_expr_test(
|
||||
'does not crash extend()',
|
||||
'extend(L, [1])',
|
||||
'E742: Cannot change value of extend() argument',
|
||||
0
|
||||
)
|
||||
null_expr_test('does not crash extend() (second position)', 'extend([1], L)', 0, { 1 })
|
||||
null_expr_test('makes join() return empty string', 'join(L, "")', 0, '')
|
||||
null_expr_test('makes msgpackdump() return empty list', 'msgpackdump(L)', 0, {})
|
||||
null_expr_test('does not crash system()', 'system("cat", L)', 0, '')
|
||||
null_expr_test('does not crash setreg', 'setreg("x", L)', 0, 0)
|
||||
null_expr_test('does not crash systemlist()', 'systemlist("cat", L)', 0, {})
|
||||
null_test('does not make Neovim crash when v:oldfiles gets assigned to that', ':let v:oldfiles = L|oldfiles', 0)
|
||||
null_expr_test('does not make complete() crash or error out',
|
||||
'execute(":normal i\\<C-r>=complete(1, L)[-1]\\n")',
|
||||
0, '', function()
|
||||
eq({''}, curbufmeths.get_lines(0, -1, false))
|
||||
end)
|
||||
null_test(
|
||||
'does not make Neovim crash when v:oldfiles gets assigned to that',
|
||||
':let v:oldfiles = L|oldfiles',
|
||||
0
|
||||
)
|
||||
null_expr_test(
|
||||
'does not make complete() crash or error out',
|
||||
'execute(":normal i\\<C-r>=complete(1, L)[-1]\\n")',
|
||||
0,
|
||||
'',
|
||||
function()
|
||||
eq({ '' }, curbufmeths.get_lines(0, -1, false))
|
||||
end
|
||||
)
|
||||
null_expr_test('is accepted by setmatches()', 'setmatches(L)', 0, 0)
|
||||
null_expr_test('is accepted by setqflist()', 'setqflist(L)', 0, 0)
|
||||
null_expr_test('is accepted by setloclist()', 'setloclist(1, L)', 0, 0)
|
||||
@@ -143,11 +196,15 @@ describe('NULL', function()
|
||||
end)
|
||||
describe('dict', function()
|
||||
it('does not crash when indexing NULL dict', function()
|
||||
eq('\nE716: Key not present in Dictionary: "test"',
|
||||
redir_exec('echo v:_null_dict.test'))
|
||||
eq('\nE716: Key not present in Dictionary: "test"', redir_exec('echo v:_null_dict.test'))
|
||||
end)
|
||||
null_expr_test('makes extend error out', 'extend(D, {})', 'E742: Cannot change value of extend() argument', 0)
|
||||
null_expr_test('makes extend do nothing', 'extend({1: 2}, D)', 0, {['1']=2})
|
||||
null_expr_test(
|
||||
'makes extend error out',
|
||||
'extend(D, {})',
|
||||
'E742: Cannot change value of extend() argument',
|
||||
0
|
||||
)
|
||||
null_expr_test('makes extend do nothing', 'extend({1: 2}, D)', 0, { ['1'] = 2 })
|
||||
null_expr_test('does not crash map()', 'map(D, "v:val")', 0, {})
|
||||
null_expr_test('does not crash filter()', 'filter(D, "1")', 0, {})
|
||||
null_expr_test('makes map() return v:_null_dict', 'map(D, "v:val") is# D', 0, 1)
|
||||
@@ -158,7 +215,12 @@ describe('NULL', function()
|
||||
null_test('does not crash :execute', 'execute S', 0)
|
||||
null_expr_test('does not crash execute()', 'execute(S)', 0, '')
|
||||
null_expr_test('does not crash executable()', 'executable(S)', 0, 0)
|
||||
null_expr_test('makes timer_start() error out', 'timer_start(0, S)', 'E921: Invalid callback argument', -1)
|
||||
null_expr_test(
|
||||
'makes timer_start() error out',
|
||||
'timer_start(0, S)',
|
||||
'E921: Invalid callback argument',
|
||||
-1
|
||||
)
|
||||
null_expr_test('does not crash filereadable()', 'filereadable(S)', 0, 0)
|
||||
null_expr_test('does not crash filewritable()', 'filewritable(S)', 0, 0)
|
||||
null_expr_test('does not crash fnamemodify()', 'fnamemodify(S, S)', 0, '')
|
||||
@@ -169,7 +231,7 @@ describe('NULL', function()
|
||||
null_expr_test('does not crash glob()', 'glob(S)', 0, '')
|
||||
null_expr_test('does not crash globpath()', 'globpath(S, S)', 0, '')
|
||||
null_expr_test('does not crash mkdir()', 'mkdir(S)', 0, 0)
|
||||
null_expr_test('does not crash sort()', 'sort(["b", S, "a"])', 0, {'', 'a', 'b'})
|
||||
null_expr_test('does not crash sort()', 'sort(["b", S, "a"])', 0, { '', 'a', 'b' })
|
||||
null_expr_test('does not crash split()', 'split(S)', 0, {})
|
||||
null_test('can be used to set an option', 'let &grepprg = S', 0)
|
||||
|
||||
|
||||
@@ -7,22 +7,22 @@ describe('Division operator', function()
|
||||
before_each(clear)
|
||||
|
||||
it('returns infinity on {positive}/0.0', function()
|
||||
eq('str2float(\'inf\')', eval('string(1.0/0.0)'))
|
||||
eq('str2float(\'inf\')', eval('string(1.0e-100/0.0)'))
|
||||
eq('str2float(\'inf\')', eval('string(1.0e+100/0.0)'))
|
||||
eq('str2float(\'inf\')', eval('string((1.0/0.0)/0.0)'))
|
||||
eq("str2float('inf')", eval('string(1.0/0.0)'))
|
||||
eq("str2float('inf')", eval('string(1.0e-100/0.0)'))
|
||||
eq("str2float('inf')", eval('string(1.0e+100/0.0)'))
|
||||
eq("str2float('inf')", eval('string((1.0/0.0)/0.0)'))
|
||||
end)
|
||||
|
||||
it('returns -infinity on {negative}/0.0', function()
|
||||
eq('-str2float(\'inf\')', eval('string((-1.0)/0.0)'))
|
||||
eq('-str2float(\'inf\')', eval('string((-1.0e-100)/0.0)'))
|
||||
eq('-str2float(\'inf\')', eval('string((-1.0e+100)/0.0)'))
|
||||
eq('-str2float(\'inf\')', eval('string((-1.0/0.0)/0.0)'))
|
||||
eq("-str2float('inf')", eval('string((-1.0)/0.0)'))
|
||||
eq("-str2float('inf')", eval('string((-1.0e-100)/0.0)'))
|
||||
eq("-str2float('inf')", eval('string((-1.0e+100)/0.0)'))
|
||||
eq("-str2float('inf')", eval('string((-1.0/0.0)/0.0)'))
|
||||
end)
|
||||
|
||||
it('returns NaN on 0.0/0.0', function()
|
||||
eq('str2float(\'nan\')', eval('string(0.0/0.0)'))
|
||||
eq('str2float(\'nan\')', eval('string(-(0.0/0.0))'))
|
||||
eq('str2float(\'nan\')', eval('string((-0.0)/0.0)'))
|
||||
eq("str2float('nan')", eval('string(0.0/0.0)'))
|
||||
eq("str2float('nan')", eval('string(-(0.0/0.0))'))
|
||||
eq("str2float('nan')", eval('string((-0.0)/0.0)'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -52,7 +52,7 @@ describe('printf()', function()
|
||||
-- zero-fill modifier is ignored when used with left-align
|
||||
-- force-sign and add-blank are ignored
|
||||
-- use-grouping-characters modifier is ignored always
|
||||
eq('0b00011 ', funcs.printf('% \'+#0-10.5b', 3))
|
||||
eq('0b00011 ', funcs.printf("% '+#0-10.5b", 3))
|
||||
end)
|
||||
it('errors out when %b modifier is used for a list', function()
|
||||
eq('Vim(call):E745: Using a List as a Number', exc_exec('call printf("%b", [])'))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local helpers = require('test.functional.helpers')(after_each)
|
||||
local clear, eq, ok = helpers.clear, helpers.eq, helpers.ok
|
||||
local neq, command, funcs = helpers.neq, helpers.command, helpers.funcs
|
||||
local clear, eq, ok = helpers.clear, helpers.eq, helpers.ok
|
||||
local neq, command, funcs = helpers.neq, helpers.command, helpers.funcs
|
||||
local reltime, reltimestr, reltimefloat = funcs.reltime, funcs.reltimestr, funcs.reltimefloat
|
||||
|
||||
describe('reltimestr(), reltimefloat()', function()
|
||||
@@ -15,7 +15,7 @@ describe('reltimestr(), reltimefloat()', function()
|
||||
neq('0.0', reltimestr(elapsed))
|
||||
ok(reltimefloat(elapsed) > 0.0)
|
||||
-- original vim test for < 0.1, but easily fails on travis
|
||||
ok(nil ~= string.match(reltimestr(elapsed), "0%."))
|
||||
ok(nil ~= string.match(reltimestr(elapsed), '0%.'))
|
||||
ok(reltimefloat(elapsed) < 1.0)
|
||||
|
||||
local same = reltime(now, now)
|
||||
@@ -29,7 +29,7 @@ describe('reltimestr(), reltimefloat()', function()
|
||||
neq('0.0', reltimestr(differs))
|
||||
ok(reltimefloat(differs) > 0.0)
|
||||
-- original vim test for < 0.1, but easily fails on travis
|
||||
ok(nil ~= string.match(reltimestr(differs), "0%."))
|
||||
ok(nil ~= string.match(reltimestr(differs), '0%.'))
|
||||
ok(reltimefloat(differs) < 1.0)
|
||||
end)
|
||||
|
||||
|
||||
@@ -8,66 +8,72 @@ before_each(clear)
|
||||
describe('screenpos() function', function()
|
||||
it('works in floating window with border', function()
|
||||
local opts = {
|
||||
relative='editor',
|
||||
height=8,
|
||||
width=12,
|
||||
row=6,
|
||||
col=8,
|
||||
anchor='NW',
|
||||
style='minimal',
|
||||
border='none',
|
||||
focusable=1
|
||||
relative = 'editor',
|
||||
height = 8,
|
||||
width = 12,
|
||||
row = 6,
|
||||
col = 8,
|
||||
anchor = 'NW',
|
||||
style = 'minimal',
|
||||
border = 'none',
|
||||
focusable = 1,
|
||||
}
|
||||
local float = meths.open_win(meths.create_buf(false, true), false, opts)
|
||||
command('redraw')
|
||||
eq({row = 7, col = 9, endcol = 9, curscol = 9}, funcs.screenpos(float, 1, 1))
|
||||
eq({ row = 7, col = 9, endcol = 9, curscol = 9 }, funcs.screenpos(float, 1, 1))
|
||||
|
||||
-- only left border
|
||||
opts.border = {'', '', '', '', '', '', '', '|'}
|
||||
opts.border = { '', '', '', '', '', '', '', '|' }
|
||||
meths.win_set_config(float, opts)
|
||||
command('redraw')
|
||||
eq({row = 7, col = 10, endcol = 10, curscol = 10}, funcs.screenpos(float, 1, 1))
|
||||
eq({ row = 7, col = 10, endcol = 10, curscol = 10 }, funcs.screenpos(float, 1, 1))
|
||||
|
||||
-- only top border
|
||||
opts.border = {'', '_', '', '', '', '', '', ''}
|
||||
opts.border = { '', '_', '', '', '', '', '', '' }
|
||||
meths.win_set_config(float, opts)
|
||||
command('redraw')
|
||||
eq({row = 8, col = 9, endcol = 9, curscol = 9}, funcs.screenpos(float, 1, 1))
|
||||
eq({ row = 8, col = 9, endcol = 9, curscol = 9 }, funcs.screenpos(float, 1, 1))
|
||||
|
||||
-- both left and top border
|
||||
opts.border = 'single'
|
||||
meths.win_set_config(float, opts)
|
||||
command('redraw')
|
||||
eq({row = 8, col = 10, endcol = 10, curscol = 10}, funcs.screenpos(float, 1, 1))
|
||||
eq({ row = 8, col = 10, endcol = 10, curscol = 10 }, funcs.screenpos(float, 1, 1))
|
||||
end)
|
||||
|
||||
it('works for folded line with virt_lines attached to line above', function()
|
||||
meths.buf_set_lines(0, 0, -1, true, {'aaa', 'bbb', 'ccc', 'ddd'})
|
||||
meths.buf_set_lines(0, 0, -1, true, { 'aaa', 'bbb', 'ccc', 'ddd' })
|
||||
local ns = meths.create_namespace('')
|
||||
meths.buf_set_extmark(0, ns, 0, 0, { virt_lines = {{{'abb'}}, {{'acc'}}, {{'add'}}} })
|
||||
meths.buf_set_extmark(
|
||||
0,
|
||||
ns,
|
||||
0,
|
||||
0,
|
||||
{ virt_lines = { { { 'abb' } }, { { 'acc' } }, { { 'add' } } } }
|
||||
)
|
||||
command('2,3fold')
|
||||
eq({row = 5, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1))
|
||||
eq({row = 5, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1))
|
||||
eq({row = 6, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1))
|
||||
eq({ row = 5, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 2, 1))
|
||||
eq({ row = 5, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 3, 1))
|
||||
eq({ row = 6, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 4, 1))
|
||||
|
||||
feed('<C-E>')
|
||||
eq({row = 4, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1))
|
||||
eq({row = 4, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1))
|
||||
eq({row = 5, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1))
|
||||
eq({ row = 4, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 2, 1))
|
||||
eq({ row = 4, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 3, 1))
|
||||
eq({ row = 5, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 4, 1))
|
||||
|
||||
feed('<C-E>')
|
||||
eq({row = 3, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1))
|
||||
eq({row = 3, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1))
|
||||
eq({row = 4, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1))
|
||||
eq({ row = 3, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 2, 1))
|
||||
eq({ row = 3, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 3, 1))
|
||||
eq({ row = 4, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 4, 1))
|
||||
|
||||
feed('<C-E>')
|
||||
eq({row = 2, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1))
|
||||
eq({row = 2, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1))
|
||||
eq({row = 3, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1))
|
||||
eq({ row = 2, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 2, 1))
|
||||
eq({ row = 2, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 3, 1))
|
||||
eq({ row = 3, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 4, 1))
|
||||
|
||||
feed('<C-E>')
|
||||
eq({row = 1, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 2, 1))
|
||||
eq({row = 1, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 3, 1))
|
||||
eq({row = 2, col = 1, endcol = 1, curscol = 1}, funcs.screenpos(0, 4, 1))
|
||||
eq({ row = 1, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 2, 1))
|
||||
eq({ row = 1, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 3, 1))
|
||||
eq({ row = 2, col = 1, endcol = 1, curscol = 1 }, funcs.screenpos(0, 4, 1))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -24,43 +24,41 @@ describe('server', function()
|
||||
it('serverstart() stores sockets in $XDG_RUNTIME_DIR', function()
|
||||
local dir = 'Xtest_xdg_run'
|
||||
mkdir(dir)
|
||||
clear({ env={ XDG_RUNTIME_DIR=dir } })
|
||||
clear({ env = { XDG_RUNTIME_DIR = dir } })
|
||||
matches(dir, funcs.stdpath('run'))
|
||||
if not is_os('win') then
|
||||
matches(dir, funcs.serverstart())
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
it('serverstart(), serverstop() does not set $NVIM', function()
|
||||
clear()
|
||||
local s = eval('serverstart()')
|
||||
assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
|
||||
assert(s ~= nil and s:len() > 0, 'serverstart() returned empty')
|
||||
eq('', eval('$NVIM'))
|
||||
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
||||
eq(1, eval("serverstop('"..s.."')"))
|
||||
eq(1, eval("serverstop('" .. s .. "')"))
|
||||
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
||||
end)
|
||||
|
||||
it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function()
|
||||
clear({env={NVIM_LISTEN_ADDRESS='.'}})
|
||||
clear({ env = { NVIM_LISTEN_ADDRESS = '.' } })
|
||||
-- Cleared on startup.
|
||||
eq('', eval('$NVIM_LISTEN_ADDRESS'))
|
||||
local servers = funcs.serverlist()
|
||||
eq(1, #servers)
|
||||
ok(string.len(servers[1]) > 4) -- "~/.local/state/nvim…/…" or "\\.\pipe\…"
|
||||
ok(string.len(servers[1]) > 4) -- "~/.local/state/nvim…/…" or "\\.\pipe\…"
|
||||
end)
|
||||
|
||||
it('sets v:servername at startup or if all servers were stopped', function()
|
||||
clear()
|
||||
local initial_server = meths.get_vvar('servername')
|
||||
assert(initial_server ~= nil and initial_server:len() > 0,
|
||||
'v:servername was not initialized')
|
||||
assert(initial_server ~= nil and initial_server:len() > 0, 'v:servername was not initialized')
|
||||
|
||||
-- v:servername is readonly so we cannot unset it--but we can test that it
|
||||
-- does not get set again thereafter.
|
||||
local s = funcs.serverstart()
|
||||
assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
|
||||
assert(s ~= nil and s:len() > 0, 'serverstart() returned empty')
|
||||
neq(initial_server, s)
|
||||
|
||||
-- serverstop() does _not_ modify v:servername...
|
||||
@@ -72,8 +70,10 @@ describe('server', function()
|
||||
eq('', meths.get_vvar('servername'))
|
||||
|
||||
-- v:servername and $NVIM take the next available server.
|
||||
local servername = (is_os('win') and [[\\.\pipe\Xtest-functional-server-pipe]]
|
||||
or './Xtest-functional-server-socket')
|
||||
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'))
|
||||
-- Not set in the current process, only in children.
|
||||
@@ -81,31 +81,31 @@ describe('server', function()
|
||||
end)
|
||||
|
||||
it('serverstop() returns false for invalid input', function()
|
||||
clear{env={
|
||||
NVIM_LOG_FILE=testlog,
|
||||
NVIM_LISTEN_ADDRESS='.',
|
||||
}}
|
||||
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{env={
|
||||
NVIM_LOG_FILE=testlog,
|
||||
NVIM_LISTEN_ADDRESS='.',
|
||||
}}
|
||||
clear { env = {
|
||||
NVIM_LOG_FILE = testlog,
|
||||
NVIM_LISTEN_ADDRESS = '.',
|
||||
} }
|
||||
clear_serverlist()
|
||||
eq({}, funcs.serverlist())
|
||||
|
||||
local s = funcs.serverstart('127.0.0.1:0') -- assign random port
|
||||
local s = funcs.serverstart('127.0.0.1:0') -- assign random port
|
||||
if #s > 0 then
|
||||
assert(string.match(s, '127.0.0.1:%d+'))
|
||||
eq(s, funcs.serverlist()[1])
|
||||
clear_serverlist()
|
||||
end
|
||||
|
||||
s = funcs.serverstart('127.0.0.1:') -- assign random port
|
||||
s = funcs.serverstart('127.0.0.1:') -- assign random port
|
||||
if #s > 0 then
|
||||
assert(string.match(s, '127.0.0.1:%d+'))
|
||||
eq(s, funcs.serverlist()[1])
|
||||
@@ -117,7 +117,7 @@ describe('server', function()
|
||||
local status, _ = pcall(funcs.serverstart, v4)
|
||||
if status then
|
||||
table.insert(expected, v4)
|
||||
pcall(funcs.serverstart, v4) -- exists already; ignore
|
||||
pcall(funcs.serverstart, v4) -- exists already; ignore
|
||||
assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10)
|
||||
end
|
||||
|
||||
@@ -125,7 +125,7 @@ describe('server', function()
|
||||
status, _ = pcall(funcs.serverstart, v6)
|
||||
if status then
|
||||
table.insert(expected, v6)
|
||||
pcall(funcs.serverstart, v6) -- exists already; ignore
|
||||
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())
|
||||
@@ -135,8 +135,10 @@ describe('server', function()
|
||||
matches([[.*[/\\]xtest1%.2%.3%.4[^/\\]*]], funcs.serverstart('xtest1.2.3.4'))
|
||||
clear_serverlist()
|
||||
|
||||
eq('Vim:Failed to start server: invalid argument',
|
||||
pcall_err(funcs.serverstart, '127.0.0.1:65536')) -- invalid port
|
||||
eq(
|
||||
'Vim:Failed to start server: invalid argument',
|
||||
pcall_err(funcs.serverstart, '127.0.0.1:65536')
|
||||
) -- invalid port
|
||||
eq({}, funcs.serverlist())
|
||||
end)
|
||||
|
||||
@@ -146,11 +148,12 @@ describe('server', function()
|
||||
local n = eval('len(serverlist())')
|
||||
|
||||
-- Add some servers.
|
||||
local servs = (is_os('win')
|
||||
and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
|
||||
or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] })
|
||||
local servs = (
|
||||
is_os('win') and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
|
||||
or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] }
|
||||
)
|
||||
for _, s in ipairs(servs) do
|
||||
eq(s, eval("serverstart('"..s.."')"))
|
||||
eq(s, eval("serverstart('" .. s .. "')"))
|
||||
end
|
||||
|
||||
local new_servs = eval('serverlist()')
|
||||
@@ -160,7 +163,7 @@ describe('server', function()
|
||||
-- The new servers should be at the end of the list.
|
||||
for i = 1, #servs do
|
||||
eq(servs[i], new_servs[i + n])
|
||||
eq(1, eval("serverstop('"..servs[i].."')"))
|
||||
eq(1, eval("serverstop('" .. servs[i] .. "')"))
|
||||
end
|
||||
-- After serverstop() the servers should NOT be in the list.
|
||||
eq(n, eval('len(serverlist())'))
|
||||
@@ -180,14 +183,12 @@ describe('startup --listen', function()
|
||||
end)
|
||||
|
||||
it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
|
||||
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 } })
|
||||
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 } })
|
||||
eq(addr, meths.get_vvar('servername'))
|
||||
|
||||
-- Address without slashes is a "name" which is appended to a generated path. #8519
|
||||
clear({ args={ '--listen', 'test-name' } })
|
||||
clear({ args = { '--listen', 'test-name' } })
|
||||
matches([[.*[/\\]test%-name[^/\\]*]], meths.get_vvar('servername'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -8,7 +8,6 @@ local eval = helpers.eval
|
||||
local eq = helpers.eq
|
||||
local exc_exec = helpers.exc_exec
|
||||
|
||||
|
||||
describe('setpos() function', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
@@ -23,42 +22,42 @@ describe('setpos() function', function()
|
||||
Line of text 3]])
|
||||
end)
|
||||
it('can set the current cursor position', function()
|
||||
setpos(".", {0, 2, 1, 0})
|
||||
eq({0, 2, 1, 0}, getpos("."))
|
||||
setpos(".", {2, 1, 1, 0})
|
||||
eq({0, 1, 1, 0}, getpos("."))
|
||||
setpos('.', { 0, 2, 1, 0 })
|
||||
eq({ 0, 2, 1, 0 }, getpos('.'))
|
||||
setpos('.', { 2, 1, 1, 0 })
|
||||
eq({ 0, 1, 1, 0 }, getpos('.'))
|
||||
local ret = exc_exec('call setpos(".", [1, 1, 1, 0])')
|
||||
eq(0, ret)
|
||||
end)
|
||||
it('can set lowercase marks in the current buffer', function()
|
||||
setpos("'d", {0, 2, 1, 0})
|
||||
eq({0, 2, 1, 0}, getpos("'d"))
|
||||
setpos("'d", { 0, 2, 1, 0 })
|
||||
eq({ 0, 2, 1, 0 }, getpos("'d"))
|
||||
command('undo')
|
||||
command('call setpos("\'d", [2, 3, 1, 0])')
|
||||
eq({0, 3, 1, 0}, getpos("'d"))
|
||||
eq({ 0, 3, 1, 0 }, getpos("'d"))
|
||||
end)
|
||||
it('can set lowercase marks in other buffers', function()
|
||||
local retval = setpos("'d", {1, 2, 1, 0})
|
||||
local retval = setpos("'d", { 1, 2, 1, 0 })
|
||||
eq(0, retval)
|
||||
setpos("'d", {1, 2, 1, 0})
|
||||
eq({0, 0, 0, 0}, getpos("'d"))
|
||||
setpos("'d", { 1, 2, 1, 0 })
|
||||
eq({ 0, 0, 0, 0 }, getpos("'d"))
|
||||
command('wincmd w')
|
||||
eq(1, eval('bufnr("%")'))
|
||||
eq({0, 2, 1, 0}, getpos("'d"))
|
||||
eq({ 0, 2, 1, 0 }, getpos("'d"))
|
||||
end)
|
||||
it("fails when setting a mark in a buffer that doesn't exist", function()
|
||||
local retval = setpos("'d", {3, 2, 1, 0})
|
||||
local retval = setpos("'d", { 3, 2, 1, 0 })
|
||||
eq(-1, retval)
|
||||
eq({0, 0, 0, 0}, getpos("'d"))
|
||||
retval = setpos("'D", {3, 2, 1, 0})
|
||||
eq({ 0, 0, 0, 0 }, getpos("'d"))
|
||||
retval = setpos("'D", { 3, 2, 1, 0 })
|
||||
eq(-1, retval)
|
||||
eq({0, 0, 0, 0}, getpos("'D"))
|
||||
eq({ 0, 0, 0, 0 }, getpos("'D"))
|
||||
end)
|
||||
it('can set uppercase marks', function()
|
||||
setpos("'D", {2, 2, 3, 0})
|
||||
eq({2, 2, 3, 0}, getpos("'D"))
|
||||
setpos("'D", { 2, 2, 3, 0 })
|
||||
eq({ 2, 2, 3, 0 }, getpos("'D"))
|
||||
-- Can set a mark in another buffer
|
||||
setpos("'D", {1, 2, 2, 0})
|
||||
eq({1, 2, 2, 0}, getpos("'D"))
|
||||
setpos("'D", { 1, 2, 2, 0 })
|
||||
eq({ 1, 2, 2, 0 }, getpos("'D"))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -14,31 +14,41 @@ before_each(clear)
|
||||
|
||||
describe('sort()', function()
|
||||
it('errors out when sorting special values', function()
|
||||
eq('Vim(call):E362: Using a boolean value as a Float',
|
||||
exc_exec('call sort([v:true, v:false], "f")'))
|
||||
eq(
|
||||
'Vim(call):E362: Using a boolean value as a Float',
|
||||
exc_exec('call sort([v:true, v:false], "f")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('sorts “wrong” values between -0.0001 and 0.0001, preserving order',
|
||||
function()
|
||||
meths.set_var('list', {true, false, NIL, {}, {a=42}, 'check',
|
||||
0.0001, -0.0001})
|
||||
it('sorts “wrong” values between -0.0001 and 0.0001, preserving order', function()
|
||||
meths.set_var('list', {
|
||||
true,
|
||||
false,
|
||||
NIL,
|
||||
{},
|
||||
{ a = 42 },
|
||||
'check',
|
||||
0.0001,
|
||||
-0.0001,
|
||||
})
|
||||
command('call insert(g:list, function("tr"))')
|
||||
local error_lines = funcs.split(
|
||||
funcs.execute('silent! call sort(g:list, "f")'), '\n')
|
||||
local error_lines = funcs.split(funcs.execute('silent! call sort(g:list, "f")'), '\n')
|
||||
local errors = {}
|
||||
for _, err in ipairs(error_lines) do
|
||||
errors[err] = true
|
||||
end
|
||||
eq({
|
||||
['E362: Using a boolean value as a Float']=true,
|
||||
['E891: Using a Funcref as a Float']=true,
|
||||
['E892: Using a String as a Float']=true,
|
||||
['E893: Using a List as a Float']=true,
|
||||
['E894: Using a Dictionary as a Float']=true,
|
||||
['E907: Using a special value as a Float']=true,
|
||||
['E362: Using a boolean value as a Float'] = true,
|
||||
['E891: Using a Funcref as a Float'] = true,
|
||||
['E892: Using a String as a Float'] = true,
|
||||
['E893: Using a List as a Float'] = true,
|
||||
['E894: Using a Dictionary as a Float'] = true,
|
||||
['E907: Using a special value as a Float'] = true,
|
||||
}, errors)
|
||||
eq('[-1.0e-4, function(\'tr\'), v:true, v:false, v:null, [], {\'a\': 42}, \'check\', 1.0e-4]',
|
||||
eval('string(g:list)'))
|
||||
eq(
|
||||
"[-1.0e-4, function('tr'), v:true, v:false, v:null, [], {'a': 42}, 'check', 1.0e-4]",
|
||||
eval('string(g:list)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('can yield E702 and stop sorting after that', function()
|
||||
@@ -50,7 +60,9 @@ describe('sort()', function()
|
||||
return (a:a > a:b) - (a:a < a:b)
|
||||
endfunction
|
||||
]])
|
||||
eq('Vim(let):E745: Using a List as a Number',
|
||||
pcall_err(command, 'let sl = sort([1, 0, [], 3, 2], "Cmp")'))
|
||||
eq(
|
||||
'Vim(let):E745: Using a List as a Number',
|
||||
pcall_err(command, 'let sl = sort([1, 0, [], 3, 2], "Cmp")')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -98,8 +98,8 @@ describe('Special values', function()
|
||||
eq(0, eval('0 + v:false'))
|
||||
|
||||
eq(-1, eval('0 - v:true'))
|
||||
eq( 0, eval('0 - v:null'))
|
||||
eq( 0, eval('0 - v:false'))
|
||||
eq(0, eval('0 - v:null'))
|
||||
eq(0, eval('0 - v:false'))
|
||||
|
||||
eq(1, eval('1 * v:true'))
|
||||
eq(0, eval('1 * v:null'))
|
||||
@@ -125,9 +125,9 @@ describe('Special values', function()
|
||||
end)
|
||||
|
||||
it('work with . (concat) properly', function()
|
||||
eq("v:true", eval('"" . v:true'))
|
||||
eq("v:null", eval('"" . v:null'))
|
||||
eq("v:false", eval('"" . v:false'))
|
||||
eq('v:true', eval('"" . v:true'))
|
||||
eq('v:null', eval('"" . v:null'))
|
||||
eq('v:false', eval('"" . v:false'))
|
||||
end)
|
||||
|
||||
it('work with ?? (falsy operator)', function()
|
||||
|
||||
@@ -12,7 +12,7 @@ before_each(clear)
|
||||
describe('state() function', function()
|
||||
-- oldtest: Test_state()
|
||||
it('works', function()
|
||||
meths.ui_attach(80, 24, {}) -- Allow hit-enter-prompt
|
||||
meths.ui_attach(80, 24, {}) -- Allow hit-enter-prompt
|
||||
|
||||
exec_lua([[
|
||||
function _G.Get_state_mode()
|
||||
@@ -42,34 +42,34 @@ describe('state() function', function()
|
||||
|
||||
-- Using a timer callback
|
||||
feed([[:call RunTimer()<CR>]])
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
eq({ 'c', 'n' }, exec_lua('return _G.res'))
|
||||
|
||||
-- Halfway a mapping
|
||||
feed([[:call v:lua.Run_timer()<CR>;]])
|
||||
meths.get_mode() -- Process pending input and luv timer callback
|
||||
meths.get_mode() -- Process pending input and luv timer callback
|
||||
feed(';')
|
||||
eq({ 'mS', 'n' }, exec_lua('return _G.res'))
|
||||
|
||||
-- An operator is pending
|
||||
feed([[:call RunTimer()<CR>y]])
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
feed('y')
|
||||
eq({ 'oSc', 'n' }, exec_lua('return _G.res'))
|
||||
|
||||
-- A register was specified
|
||||
feed([[:call RunTimer()<CR>"r]])
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
feed('yy')
|
||||
eq({ 'oSc', 'n' }, exec_lua('return _G.res'))
|
||||
|
||||
-- Insert mode completion
|
||||
feed([[:call RunTimer()<CR>Got<C-N>]])
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
poke_eventloop() -- Process pending input
|
||||
poke_eventloop() -- Process time_event
|
||||
feed('<Esc>')
|
||||
eq({ 'aSc', 'i' }, exec_lua('return _G.res'))
|
||||
|
||||
@@ -79,7 +79,7 @@ describe('state() function', function()
|
||||
|
||||
-- messages scrolled
|
||||
feed([[:call v:lua.Run_timer() | echo "one\ntwo\nthree"<CR>]])
|
||||
meths.get_mode() -- Process pending input and luv timer callback
|
||||
meths.get_mode() -- Process pending input and luv timer callback
|
||||
feed('<CR>')
|
||||
eq({ 'Ss', 'r' }, exec_lua('return _G.res'))
|
||||
end)
|
||||
|
||||
@@ -15,12 +15,12 @@ describe('string() function', function()
|
||||
|
||||
describe('used to represent floating-point values', function()
|
||||
it('dumps NaN values', function()
|
||||
eq('str2float(\'nan\')', eval('string(str2float(\'nan\'))'))
|
||||
eq("str2float('nan')", eval("string(str2float('nan'))"))
|
||||
end)
|
||||
|
||||
it('dumps infinite values', function()
|
||||
eq('str2float(\'inf\')', eval('string(str2float(\'inf\'))'))
|
||||
eq('-str2float(\'inf\')', eval('string(str2float(\'-inf\'))'))
|
||||
eq("str2float('inf')", eval("string(str2float('inf'))"))
|
||||
eq("-str2float('inf')", eval("string(str2float('-inf'))"))
|
||||
end)
|
||||
|
||||
it('dumps regular values', function()
|
||||
@@ -38,14 +38,12 @@ describe('string() function', function()
|
||||
eq('v:null', funcs.string(NIL))
|
||||
end)
|
||||
|
||||
it('dumps values with at most six digits after the decimal point',
|
||||
function()
|
||||
it('dumps values with at most six digits after the decimal point', function()
|
||||
eq('1.234568e-20', funcs.string(1.23456789123456789123456789e-020))
|
||||
eq('1.234568', funcs.string(1.23456789123456789123456789))
|
||||
end)
|
||||
|
||||
it('dumps values with at most seven digits before the decimal point',
|
||||
function()
|
||||
it('dumps values with at most seven digits before the decimal point', function()
|
||||
eq('1234567.891235', funcs.string(1234567.89123456789123456789))
|
||||
eq('1.234568e7', funcs.string(12345678.9123456789123456789))
|
||||
end)
|
||||
@@ -68,29 +66,29 @@ describe('string() function', function()
|
||||
end)
|
||||
|
||||
it('dumps large values', function()
|
||||
eq('2147483647', funcs.string(2^31-1))
|
||||
eq('-2147483648', funcs.string(-2^31))
|
||||
eq('2147483647', funcs.string(2 ^ 31 - 1))
|
||||
eq('-2147483648', funcs.string(-2 ^ 31))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('used to represent strings', function()
|
||||
it('dumps regular strings', function()
|
||||
eq('\'test\'', funcs.string('test'))
|
||||
eq("'test'", funcs.string('test'))
|
||||
end)
|
||||
|
||||
it('dumps empty strings', function()
|
||||
eq('\'\'', funcs.string(''))
|
||||
eq("''", funcs.string(''))
|
||||
end)
|
||||
|
||||
it('dumps strings with \' inside', function()
|
||||
eq('\'\'\'\'\'\'\'\'', funcs.string('\'\'\''))
|
||||
eq('\'a\'\'b\'\'\'\'\'', funcs.string('a\'b\'\''))
|
||||
eq('\'\'\'b\'\'\'\'d\'', funcs.string('\'b\'\'d'))
|
||||
eq('\'a\'\'b\'\'c\'\'d\'', funcs.string('a\'b\'c\'d'))
|
||||
it("dumps strings with ' inside", function()
|
||||
eq("''''''''", funcs.string("'''"))
|
||||
eq("'a''b'''''", funcs.string("a'b''"))
|
||||
eq("'''b''''d'", funcs.string("'b''d"))
|
||||
eq("'a''b''c''d'", funcs.string("a'b'c'd"))
|
||||
end)
|
||||
|
||||
it('dumps NULL strings', function()
|
||||
eq('\'\'', eval('string($XXX_UNEXISTENT_VAR_XXX)'))
|
||||
eq("''", eval('string($XXX_UNEXISTENT_VAR_XXX)'))
|
||||
end)
|
||||
|
||||
it('dumps NULL lists', function()
|
||||
@@ -119,16 +117,16 @@ describe('string() function', function()
|
||||
end)
|
||||
|
||||
it('dumps references to built-in functions', function()
|
||||
eq('function(\'function\')', eval('string(function("function"))'))
|
||||
eq("function('function')", eval('string(function("function"))'))
|
||||
end)
|
||||
|
||||
it('dumps references to user functions', function()
|
||||
eq('function(\'Test1\')', eval('string(function("Test1"))'))
|
||||
eq('function(\'g:Test3\')', eval('string(function("g:Test3"))'))
|
||||
eq("function('Test1')", eval('string(function("Test1"))'))
|
||||
eq("function('g:Test3')", eval('string(function("g:Test3"))'))
|
||||
end)
|
||||
|
||||
it('dumps references to script functions', function()
|
||||
eq('function(\'<SNR>1_Test2\')', eval('string(Test2_f)'))
|
||||
eq("function('<SNR>1_Test2')", eval('string(Test2_f)'))
|
||||
end)
|
||||
|
||||
it('dumps partials with self referencing a partial', function()
|
||||
@@ -139,67 +137,84 @@ describe('string() function', function()
|
||||
let TestDictRef = function('TestDict', d)
|
||||
let d.tdr = TestDictRef
|
||||
]])
|
||||
eq("Vim(echo):E724: unable to correctly dump variable with self-referencing container",
|
||||
pcall_err(command, 'echo string(d.tdr)'))
|
||||
eq(
|
||||
'Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string(d.tdr)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('dumps automatically created partials', function()
|
||||
eq('function(\'<SNR>1_Test2\', {\'f\': function(\'<SNR>1_Test2\')})',
|
||||
eval('string({"f": Test2_f}.f)'))
|
||||
eq('function(\'<SNR>1_Test2\', [1], {\'f\': function(\'<SNR>1_Test2\', [1])})',
|
||||
eval('string({"f": function(Test2_f, [1])}.f)'))
|
||||
eq(
|
||||
"function('<SNR>1_Test2', {'f': function('<SNR>1_Test2')})",
|
||||
eval('string({"f": Test2_f}.f)')
|
||||
)
|
||||
eq(
|
||||
"function('<SNR>1_Test2', [1], {'f': function('<SNR>1_Test2', [1])})",
|
||||
eval('string({"f": function(Test2_f, [1])}.f)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('dumps manually created partials', function()
|
||||
eq('function(\'Test3\', [1, 2], {})',
|
||||
eval('string(function("Test3", [1, 2], {}))'))
|
||||
eq('function(\'Test3\', {})',
|
||||
eval('string(function("Test3", {}))'))
|
||||
eq('function(\'Test3\', [1, 2])',
|
||||
eval('string(function("Test3", [1, 2]))'))
|
||||
eq("function('Test3', [1, 2], {})", eval('string(function("Test3", [1, 2], {}))'))
|
||||
eq("function('Test3', {})", eval('string(function("Test3", {}))'))
|
||||
eq("function('Test3', [1, 2])", eval('string(function("Test3", [1, 2]))'))
|
||||
end)
|
||||
|
||||
it('does not crash or halt when dumping partials with reference cycles in self',
|
||||
function()
|
||||
meths.set_var('d', {v=true})
|
||||
eq([[Vim(echo):E724: unable to correctly dump variable with self-referencing container]],
|
||||
pcall_err(command, 'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))'))
|
||||
it('does not crash or halt when dumping partials with reference cycles in self', function()
|
||||
meths.set_var('d', { v = true })
|
||||
eq(
|
||||
[[Vim(echo):E724: unable to correctly dump variable with self-referencing container]],
|
||||
pcall_err(command, 'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))')
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not show errors when dumping partials referencing the same dictionary',
|
||||
function()
|
||||
it('does not show errors when dumping partials referencing the same dictionary', function()
|
||||
command('let d = {}')
|
||||
-- Regression for “eval/typval_encode: Dump empty dictionary before
|
||||
-- checking for refcycle”, results in error.
|
||||
eq('[function(\'tr\', {}), function(\'tr\', {})]', eval('string([function("tr", d), function("tr", d)])'))
|
||||
eq(
|
||||
"[function('tr', {}), function('tr', {})]",
|
||||
eval('string([function("tr", d), function("tr", d)])')
|
||||
)
|
||||
-- Regression for “eval: Work with reference cycles in partials (self)
|
||||
-- properly”, results in crash.
|
||||
eval('extend(d, {"a": 1})')
|
||||
eq('[function(\'tr\', {\'a\': 1}), function(\'tr\', {\'a\': 1})]', eval('string([function("tr", d), function("tr", d)])'))
|
||||
eq(
|
||||
"[function('tr', {'a': 1}), function('tr', {'a': 1})]",
|
||||
eval('string([function("tr", d), function("tr", d)])')
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not crash or halt when dumping partials with reference cycles in arguments',
|
||||
function()
|
||||
it('does not crash or halt when dumping partials with reference cycles in arguments', function()
|
||||
meths.set_var('l', {})
|
||||
eval('add(l, l)')
|
||||
-- Regression: the below line used to crash (add returns original list and
|
||||
-- there was error in dumping partials). Tested explicitly in
|
||||
-- test/unit/api/private_helpers_spec.lua.
|
||||
eval('add(l, function("Test1", l))')
|
||||
eq([=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=],
|
||||
pcall_err(command, 'echo string(function("Test1", l))'))
|
||||
eq(
|
||||
[=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=],
|
||||
pcall_err(command, 'echo string(function("Test1", l))')
|
||||
)
|
||||
end)
|
||||
|
||||
it('does not crash or halt when dumping partials with reference cycles in self and arguments',
|
||||
function()
|
||||
meths.set_var('d', {v=true})
|
||||
meths.set_var('l', {})
|
||||
eval('add(l, l)')
|
||||
eval('add(l, function("Test1", l))')
|
||||
eval('add(l, function("Test1", d))')
|
||||
eq([=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=],
|
||||
pcall_err(command, 'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))'))
|
||||
end)
|
||||
it(
|
||||
'does not crash or halt when dumping partials with reference cycles in self and arguments',
|
||||
function()
|
||||
meths.set_var('d', { v = true })
|
||||
meths.set_var('l', {})
|
||||
eval('add(l, l)')
|
||||
eval('add(l, function("Test1", l))')
|
||||
eval('add(l, function("Test1", d))')
|
||||
eq(
|
||||
[=[Vim(echo):E724: unable to correctly dump variable with self-referencing container]=],
|
||||
pcall_err(
|
||||
command,
|
||||
'echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))'
|
||||
)
|
||||
)
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
describe('used to represent lists', function()
|
||||
@@ -208,27 +223,33 @@ describe('string() function', function()
|
||||
end)
|
||||
|
||||
it('dumps nested lists', function()
|
||||
eq('[[[[[]]]]]', funcs.string({{{{{}}}}}))
|
||||
eq('[[[[[]]]]]', funcs.string({ { { { {} } } } }))
|
||||
end)
|
||||
|
||||
it('dumps nested non-empty lists', function()
|
||||
eq('[1, [[3, [[5], 4]], 2]]', funcs.string({1, {{3, {{5}, 4}}, 2}}))
|
||||
eq('[1, [[3, [[5], 4]], 2]]', funcs.string({ 1, { { 3, { { 5 }, 4 } }, 2 } }))
|
||||
end)
|
||||
|
||||
it('errors when dumping recursive lists', function()
|
||||
meths.set_var('l', {})
|
||||
eval('add(l, l)')
|
||||
eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('echo string(l)'))
|
||||
eq(
|
||||
'Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('echo string(l)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('dumps recursive lists despite the error', function()
|
||||
meths.set_var('l', {})
|
||||
eval('add(l, l)')
|
||||
eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string(l)'))
|
||||
eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string([l])'))
|
||||
eq(
|
||||
'Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string(l)')
|
||||
)
|
||||
eq(
|
||||
'Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string([l])')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -240,28 +261,34 @@ describe('string() function', function()
|
||||
it('dumps list with two same empty dictionaries, also in partials', function()
|
||||
command('let d = {}')
|
||||
eq('[{}, {}]', eval('string([d, d])'))
|
||||
eq('[function(\'tr\', {}), {}]', eval('string([function("tr", d), d])'))
|
||||
eq('[{}, function(\'tr\', {})]', eval('string([d, function("tr", d)])'))
|
||||
eq("[function('tr', {}), {}]", eval('string([function("tr", d), d])'))
|
||||
eq("[{}, function('tr', {})]", eval('string([d, function("tr", d)])'))
|
||||
end)
|
||||
|
||||
it('dumps non-empty dictionary', function()
|
||||
eq('{\'t\'\'est\': 1}', funcs.string({['t\'est']=1}))
|
||||
eq("{'t''est': 1}", funcs.string({ ["t'est"] = 1 }))
|
||||
end)
|
||||
|
||||
it('errors when dumping recursive dictionaries', function()
|
||||
meths.set_var('d', {d=1})
|
||||
meths.set_var('d', { d = 1 })
|
||||
eval('extend(d, {"d": d})')
|
||||
eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('echo string(d)'))
|
||||
eq(
|
||||
'Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
exc_exec('echo string(d)')
|
||||
)
|
||||
end)
|
||||
|
||||
it('dumps recursive dictionaries despite the error', function()
|
||||
meths.set_var('d', {d=1})
|
||||
meths.set_var('d', { d = 1 })
|
||||
eval('extend(d, {"d": d})')
|
||||
eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string(d)'))
|
||||
eq('Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string({"out": d})'))
|
||||
eq(
|
||||
'Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string(d)')
|
||||
)
|
||||
eq(
|
||||
'Vim(echo):E724: unable to correctly dump variable with self-referencing container',
|
||||
pcall_err(command, 'echo string({"out": d})')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -5,8 +5,13 @@ local helpers = require('test.functional.helpers')(after_each)
|
||||
local assert_alive = helpers.assert_alive
|
||||
local testprg = helpers.testprg
|
||||
local eq, call, clear, eval, feed_command, feed, nvim =
|
||||
helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.feed_command,
|
||||
helpers.feed, helpers.nvim
|
||||
helpers.eq,
|
||||
helpers.call,
|
||||
helpers.clear,
|
||||
helpers.eval,
|
||||
helpers.feed_command,
|
||||
helpers.feed,
|
||||
helpers.nvim
|
||||
local command = helpers.command
|
||||
local insert = helpers.insert
|
||||
local expect = helpers.expect
|
||||
@@ -19,14 +24,14 @@ local Screen = require('test.functional.ui.screen')
|
||||
|
||||
local function create_file_with_nuls(name)
|
||||
return function()
|
||||
feed('ipart1<C-V>000part2<C-V>000part3<ESC>:w '..name..'<CR>')
|
||||
eval('1') -- wait for the file to be created
|
||||
feed('ipart1<C-V>000part2<C-V>000part3<ESC>:w ' .. name .. '<CR>')
|
||||
eval('1') -- wait for the file to be created
|
||||
end
|
||||
end
|
||||
|
||||
local function delete_file(name)
|
||||
return function()
|
||||
eval("delete('"..name.."')")
|
||||
eval("delete('" .. name .. "')")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,8 +40,10 @@ describe('system()', function()
|
||||
|
||||
describe('command passed as a List', function()
|
||||
it('throws error if cmd[0] is not executable', function()
|
||||
eq("Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable",
|
||||
pcall_err(call, 'system', { 'this-should-not-exist' }))
|
||||
eq(
|
||||
"Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable",
|
||||
pcall_err(call, 'system', { 'this-should-not-exist' })
|
||||
)
|
||||
eq(-1, eval('v:shell_error'))
|
||||
end)
|
||||
|
||||
@@ -51,8 +58,10 @@ describe('system()', function()
|
||||
eq(0, eval('v:shell_error'))
|
||||
|
||||
-- Provoke a non-zero v:shell_error.
|
||||
eq("Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable",
|
||||
pcall_err(call, 'system', { 'this-should-not-exist' }))
|
||||
eq(
|
||||
"Vim:E475: Invalid value for argument cmd: 'this-should-not-exist' is not executable",
|
||||
pcall_err(call, 'system', { 'this-should-not-exist' })
|
||||
)
|
||||
local old_val = eval('v:shell_error')
|
||||
eq(-1, old_val)
|
||||
|
||||
@@ -65,8 +74,8 @@ describe('system()', function()
|
||||
end)
|
||||
|
||||
it('quotes arguments correctly #5280', function()
|
||||
local out = call('system',
|
||||
{ testprg('printargs-test'), [[1]], [[2 "3]], [[4 ' 5]], [[6 ' 7']] })
|
||||
local out =
|
||||
call('system', { testprg('printargs-test'), [[1]], [[2 "3]], [[4 ' 5]], [[6 ' 7']] })
|
||||
|
||||
eq(0, eval('v:shell_error'))
|
||||
eq([[arg1=1;arg2=2 "3;arg3=4 ' 5;arg4=6 ' 7';]], out)
|
||||
@@ -75,22 +84,29 @@ describe('system()', function()
|
||||
eq(0, eval('v:shell_error'))
|
||||
eq([[arg1='1;arg2=2 "3;]], out)
|
||||
|
||||
out = call('system', { testprg('printargs-test'), "A\nB" })
|
||||
out = call('system', { testprg('printargs-test'), 'A\nB' })
|
||||
eq(0, eval('v:shell_error'))
|
||||
eq("arg1=A\nB;", out)
|
||||
eq('arg1=A\nB;', out)
|
||||
end)
|
||||
|
||||
it('calls executable in $PATH', function()
|
||||
if 0 == eval("executable('python3')") then pending("missing `python3`") end
|
||||
eq("foo\n", eval([[system(['python3', '-c', 'print("foo")'])]]))
|
||||
if 0 == eval("executable('python3')") then
|
||||
pending('missing `python3`')
|
||||
end
|
||||
eq('foo\n', eval([[system(['python3', '-c', 'print("foo")'])]]))
|
||||
eq(0, eval('v:shell_error'))
|
||||
end)
|
||||
|
||||
it('does NOT run in shell', function()
|
||||
if is_os('win') then
|
||||
eq("%PATH%\n", eval("system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])"))
|
||||
eq(
|
||||
'%PATH%\n',
|
||||
eval(
|
||||
"system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])"
|
||||
)
|
||||
)
|
||||
else
|
||||
eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])"))
|
||||
eq('* $PATH %PATH%\n', eval("system(['echo', '*', '$PATH', '%PATH%'])"))
|
||||
end
|
||||
end)
|
||||
end)
|
||||
@@ -133,7 +149,12 @@ describe('system()', function()
|
||||
eval([[system('"ping" "-n" "1" "127.0.0.1"')]])
|
||||
eq(0, eval('v:shell_error'))
|
||||
eq('"a b"\n', eval([[system('cmd /s/c "cmd /s/c "cmd /s/c "echo "a b""""')]]))
|
||||
eq('"a b"\n', eval([[system('powershell -NoProfile -NoLogo -ExecutionPolicy RemoteSigned -Command Write-Output ''\^"a b\^"''')]]))
|
||||
eq(
|
||||
'"a b"\n',
|
||||
eval(
|
||||
[[system('powershell -NoProfile -NoLogo -ExecutionPolicy RemoteSigned -Command Write-Output ''\^"a b\^"''')]]
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it('with shell=cmd.exe', function()
|
||||
@@ -177,7 +198,7 @@ describe('system()', function()
|
||||
|
||||
it('powershell w/ UTF-8 text #13713', function()
|
||||
if not helpers.has_powershell() then
|
||||
pending("powershell not found", function() end)
|
||||
pending('powershell not found', function() end)
|
||||
return
|
||||
end
|
||||
helpers.set_shell_powershell()
|
||||
@@ -205,9 +226,9 @@ describe('system()', function()
|
||||
screen:try_resize(72, 14)
|
||||
feed(':4verbose echo system("echo hi")<cr>')
|
||||
if is_os('win') then
|
||||
screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]]}
|
||||
screen:expect { any = [[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]] }
|
||||
else
|
||||
screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]]}
|
||||
screen:expect { any = [[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]] }
|
||||
end
|
||||
feed('<cr>')
|
||||
end)
|
||||
@@ -234,16 +255,16 @@ describe('system()', function()
|
||||
end)
|
||||
|
||||
it('`yes` interrupted with CTRL-C', function()
|
||||
feed(':call system("' .. (is_os('win')
|
||||
and 'for /L %I in (1,0,2) do @echo y'
|
||||
or 'yes') .. '")<cr>')
|
||||
feed(
|
||||
':call system("'
|
||||
.. (is_os('win') and 'for /L %I in (1,0,2) do @echo y' or 'yes')
|
||||
.. '")<cr>'
|
||||
)
|
||||
screen:expect([[
|
||||
|
|
||||
~ |*12
|
||||
]] .. (is_os('win')
|
||||
and [[
|
||||
:call system("for /L %I in (1,0,2) do @echo y") |]]
|
||||
or [[
|
||||
]] .. (is_os('win') and [[
|
||||
:call system("for /L %I in (1,0,2) do @echo y") |]] or [[
|
||||
:call system("yes") |]]))
|
||||
feed('foo<c-c>')
|
||||
screen:expect([[
|
||||
@@ -255,16 +276,16 @@ describe('system()', function()
|
||||
|
||||
it('`yes` interrupted with mapped CTRL-C', function()
|
||||
command('nnoremap <C-C> i')
|
||||
feed(':call system("' .. (is_os('win')
|
||||
and 'for /L %I in (1,0,2) do @echo y'
|
||||
or 'yes') .. '")<cr>')
|
||||
feed(
|
||||
':call system("'
|
||||
.. (is_os('win') and 'for /L %I in (1,0,2) do @echo y' or 'yes')
|
||||
.. '")<cr>'
|
||||
)
|
||||
screen:expect([[
|
||||
|
|
||||
~ |*12
|
||||
]] .. (is_os('win')
|
||||
and [[
|
||||
:call system("for /L %I in (1,0,2) do @echo y") |]]
|
||||
or [[
|
||||
]] .. (is_os('win') and [[
|
||||
:call system("for /L %I in (1,0,2) do @echo y") |]] or [[
|
||||
:call system("yes") |]]))
|
||||
feed('foo<c-c>')
|
||||
screen:expect([[
|
||||
@@ -278,17 +299,19 @@ describe('system()', function()
|
||||
describe('passing no input', function()
|
||||
it('returns the program output', function()
|
||||
if is_os('win') then
|
||||
eq("echoed\n", eval('system("echo echoed")'))
|
||||
eq('echoed\n', eval('system("echo echoed")'))
|
||||
else
|
||||
eq("echoed", eval('system("printf echoed")'))
|
||||
eq('echoed', eval('system("printf echoed")'))
|
||||
end
|
||||
end)
|
||||
it('to backgrounded command does not crash', function()
|
||||
-- This is indeterminate, just exercise the codepath. May get E5677.
|
||||
feed_command('call system(has("win32") ? "start /b /wait cmd /c echo echoed" : "printf echoed &")')
|
||||
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
|
||||
feed_command(
|
||||
'call system(has("win32") ? "start /b /wait cmd /c echo echoed" : "printf echoed &")'
|
||||
)
|
||||
local v_errnum = string.match(eval('v:errmsg'), '^E%d*:')
|
||||
if v_errnum then
|
||||
eq("E5677:", v_errnum)
|
||||
eq('E5677:', v_errnum)
|
||||
end
|
||||
assert_alive()
|
||||
end)
|
||||
@@ -296,19 +319,19 @@ describe('system()', function()
|
||||
|
||||
describe('passing input', function()
|
||||
it('returns the program output', function()
|
||||
eq("input", eval('system("cat -", "input")'))
|
||||
eq('input', eval('system("cat -", "input")'))
|
||||
end)
|
||||
it('to backgrounded command does not crash', function()
|
||||
-- This is indeterminate, just exercise the codepath. May get E5677.
|
||||
feed_command('call system(has("win32") ? "start /b /wait more" : "cat - &", "input")')
|
||||
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
|
||||
local v_errnum = string.match(eval('v:errmsg'), '^E%d*:')
|
||||
if v_errnum then
|
||||
eq("E5677:", v_errnum)
|
||||
eq('E5677:', v_errnum)
|
||||
end
|
||||
assert_alive()
|
||||
end)
|
||||
it('works with an empty string', function()
|
||||
eq("test\n", eval('system("echo test", "")'))
|
||||
eq('test\n', eval('system("echo test", "")'))
|
||||
assert_alive()
|
||||
end)
|
||||
end)
|
||||
@@ -332,8 +355,7 @@ describe('system()', function()
|
||||
it('is treated as a buffer id', function()
|
||||
command("put ='text in buffer 1'")
|
||||
eq('\ntext in buffer 1\n', eval('system("cat", 1)'))
|
||||
eq('Vim(echo):E86: Buffer 42 does not exist',
|
||||
exc_exec('echo system("cat", 42)'))
|
||||
eq('Vim(echo):E86: Buffer 42 does not exist', exc_exec('echo system("cat", 42)'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -344,14 +366,13 @@ describe('system()', function()
|
||||
after_each(delete_file(fname))
|
||||
|
||||
it('replaces NULs by SOH characters', function()
|
||||
eq('part1\001part2\001part3\n', eval([[system('"cat" "]]..fname..[["')]]))
|
||||
eq('part1\001part2\001part3\n', eval([[system('"cat" "]] .. fname .. [["')]]))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('input passed as List', function()
|
||||
it('joins List items with linefeed characters', function()
|
||||
eq('line1\nline2\nline3',
|
||||
eval("system('cat -', ['line1', 'line2', 'line3'])"))
|
||||
eq('line1\nline2\nline3', eval("system('cat -', ['line1', 'line2', 'line3'])"))
|
||||
end)
|
||||
|
||||
-- Notice that NULs are converted to SOH when the data is read back. This
|
||||
@@ -360,15 +381,19 @@ describe('system()', function()
|
||||
-- characters(see the following tests with `systemlist()` below)
|
||||
describe('with linefeed characters inside List items', function()
|
||||
it('converts linefeed characters to NULs', function()
|
||||
eq('l1\001p2\nline2\001a\001b\nl3',
|
||||
eval([[system('cat -', ["l1\np2", "line2\na\nb", 'l3'])]]))
|
||||
eq(
|
||||
'l1\001p2\nline2\001a\001b\nl3',
|
||||
eval([[system('cat -', ["l1\np2", "line2\na\nb", 'l3'])]])
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('with leading/trailing whitespace characters on items', function()
|
||||
it('preserves whitespace, replacing linefeeds by NULs', function()
|
||||
eq('line \nline2\001\n\001line3',
|
||||
eval([[system('cat -', ['line ', "line2\n", "\nline3"])]]))
|
||||
eq(
|
||||
'line \nline2\001\n\001line3',
|
||||
eval([[system('cat -', ['line ', "line2\n", "\nline3"])]])
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
@@ -376,7 +401,7 @@ describe('system()', function()
|
||||
it("with a program that doesn't close stdout will exit properly after passing input", function()
|
||||
local out = eval(string.format("system('%s', 'clip-data')", testprg('streams-test')))
|
||||
assert(out:sub(0, 5) == 'pid: ', out)
|
||||
os_kill(out:match("%d+"))
|
||||
os_kill(out:match('%d+'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -445,7 +470,7 @@ describe('systemlist()', function()
|
||||
|
||||
describe('passing string with linefeed characters as input', function()
|
||||
it('splits the output on linefeed characters', function()
|
||||
eq({'abc', 'def', 'ghi'}, eval([[systemlist("cat -", "abc\ndef\nghi")]]))
|
||||
eq({ 'abc', 'def', 'ghi' }, eval([[systemlist("cat -", "abc\ndef\nghi")]]))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -470,75 +495,77 @@ describe('systemlist()', function()
|
||||
after_each(delete_file(fname))
|
||||
|
||||
it('replaces NULs by newline characters', function()
|
||||
eq({'part1\npart2\npart3'}, eval([[systemlist('"cat" "]]..fname..[["')]]))
|
||||
eq({ 'part1\npart2\npart3' }, eval([[systemlist('"cat" "]] .. fname .. [["')]]))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('input passed as List', function()
|
||||
it('joins list items with linefeed characters', function()
|
||||
eq({'line1', 'line2', 'line3'},
|
||||
eval("systemlist('cat -', ['line1', 'line2', 'line3'])"))
|
||||
eq({ 'line1', 'line2', 'line3' }, eval("systemlist('cat -', ['line1', 'line2', 'line3'])"))
|
||||
end)
|
||||
|
||||
-- Unlike `system()` which uses SOH to represent NULs, with `systemlist()`
|
||||
-- input and output are the same.
|
||||
describe('with linefeed characters inside list items', function()
|
||||
it('converts linefeed characters to NULs', function()
|
||||
eq({'l1\np2', 'line2\na\nb', 'l3'},
|
||||
eval([[systemlist('cat -', ["l1\np2", "line2\na\nb", 'l3'])]]))
|
||||
eq(
|
||||
{ 'l1\np2', 'line2\na\nb', 'l3' },
|
||||
eval([[systemlist('cat -', ["l1\np2", "line2\na\nb", 'l3'])]])
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('with leading/trailing whitespace characters on items', function()
|
||||
it('preserves whitespace, replacing linefeeds by NULs', function()
|
||||
eq({'line ', 'line2\n', '\nline3'},
|
||||
eval([[systemlist('cat -', ['line ', "line2\n", "\nline3"])]]))
|
||||
eq(
|
||||
{ 'line ', 'line2\n', '\nline3' },
|
||||
eval([[systemlist('cat -', ['line ', "line2\n", "\nline3"])]])
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('handles empty lines', function()
|
||||
it('in the middle', function()
|
||||
eq({'line one','','line two'}, eval("systemlist('cat',['line one','','line two'])"))
|
||||
eq({ 'line one', '', 'line two' }, eval("systemlist('cat',['line one','','line two'])"))
|
||||
end)
|
||||
|
||||
it('in the beginning', function()
|
||||
eq({'','line one','line two'}, eval("systemlist('cat',['','line one','line two'])"))
|
||||
eq({ '', 'line one', 'line two' }, eval("systemlist('cat',['','line one','line two'])"))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('when keepempty option is', function()
|
||||
it('0, ignores trailing newline', function()
|
||||
eq({'aa','bb'}, eval("systemlist('cat',['aa','bb'],0)"))
|
||||
eq({'aa','bb'}, eval("systemlist('cat',['aa','bb',''],0)"))
|
||||
eq({ 'aa', 'bb' }, eval("systemlist('cat',['aa','bb'],0)"))
|
||||
eq({ 'aa', 'bb' }, eval("systemlist('cat',['aa','bb',''],0)"))
|
||||
end)
|
||||
|
||||
it('1, preserves trailing newline', function()
|
||||
eq({'aa','bb'}, eval("systemlist('cat',['aa','bb'],1)"))
|
||||
eq({'aa','bb',''}, eval("systemlist('cat',['aa','bb',''],2)"))
|
||||
eq({ 'aa', 'bb' }, eval("systemlist('cat',['aa','bb'],1)"))
|
||||
eq({ 'aa', 'bb', '' }, eval("systemlist('cat',['aa','bb',''],2)"))
|
||||
end)
|
||||
end)
|
||||
|
||||
it("with a program that doesn't close stdout will exit properly after passing input", function()
|
||||
local out = eval(string.format("systemlist('%s', 'clip-data')", testprg('streams-test')))
|
||||
assert(out[1]:sub(0, 5) == 'pid: ', out)
|
||||
os_kill(out[1]:match("%d+"))
|
||||
os_kill(out[1]:match('%d+'))
|
||||
end)
|
||||
|
||||
it('powershell w/ UTF-8 text #13713', function()
|
||||
if not helpers.has_powershell() then
|
||||
pending("powershell not found", function() end)
|
||||
pending('powershell not found', function() end)
|
||||
return
|
||||
end
|
||||
helpers.set_shell_powershell()
|
||||
eq({is_os('win') 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({is_os('win') and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
|
||||
eq({ is_os('win') and '?\r' or 'あ' }, eval([[systemlist('Write-Output あ')]]))
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
describe('shell :!', function()
|
||||
@@ -555,13 +582,13 @@ describe('shell :!', function()
|
||||
2]])
|
||||
if is_os('win') then
|
||||
feed(':4verbose %!sort /R<cr>')
|
||||
screen:expect{
|
||||
any=[[Executing command: .?& { Get%-Content .* | & sort /R } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]]
|
||||
screen:expect {
|
||||
any = [[Executing command: .?& { Get%-Content .* | & sort /R } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]],
|
||||
}
|
||||
else
|
||||
feed(':4verbose %!sort -r<cr>')
|
||||
screen:expect{
|
||||
any=[[Executing command: .?& { Get%-Content .* | & sort %-r } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]]
|
||||
screen:expect {
|
||||
any = [[Executing command: .?& { Get%-Content .* | & sort %-r } 2>&1 | %%{ "$_" } | Out%-File .*; exit $LastExitCode"]],
|
||||
}
|
||||
end
|
||||
feed('<CR>')
|
||||
@@ -585,20 +612,19 @@ describe('shell :!', function()
|
||||
2]])
|
||||
feed(':4verbose %w !sort<cr>')
|
||||
if is_os('win') then
|
||||
screen:expect{
|
||||
any=[[Executing command: .?sort %< .*]]
|
||||
screen:expect {
|
||||
any = [[Executing command: .?sort %< .*]],
|
||||
}
|
||||
else
|
||||
screen:expect{
|
||||
any=[[Executing command: .?%(sort%) %< .*]]
|
||||
|
||||
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 }]]
|
||||
screen:expect {
|
||||
any = [[Executing command: .?& { Get%-Content .* | & sort }]],
|
||||
}
|
||||
feed('<CR>')
|
||||
helpers.expect_exit(command, 'qall!')
|
||||
|
||||
@@ -22,20 +22,20 @@ describe('timers', function()
|
||||
it('works one-shot', function()
|
||||
eq(0, eval("[timer_start(10, 'MyHandler'), g:val][1]"))
|
||||
run(nil, nil, nil, load_adjust(100))
|
||||
eq(1,eval("g:val"))
|
||||
eq(1, eval('g:val'))
|
||||
end)
|
||||
|
||||
it('works one-shot when repeat=0', function()
|
||||
eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 0}), g:val][1]"))
|
||||
run(nil, nil, nil, load_adjust(100))
|
||||
eq(1, eval("g:val"))
|
||||
eq(1, eval('g:val'))
|
||||
end)
|
||||
|
||||
it('works with repeat two', function()
|
||||
eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 2}), g:val][1]"))
|
||||
run(nil, nil, nil, load_adjust(20))
|
||||
retry(nil, load_adjust(300), function()
|
||||
eq(2, eval("g:val"))
|
||||
eq(2, eval('g:val'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -52,12 +52,12 @@ describe('timers', function()
|
||||
endfunc
|
||||
]])
|
||||
eval("timer_start(10, 'MyHandler', {'repeat': -1})")
|
||||
nvim_async("command", "sleep 10")
|
||||
eq(-1, eval("g:val")) -- timer did nothing yet.
|
||||
nvim_async("command", "let g:val = 0")
|
||||
nvim_async('command', 'sleep 10')
|
||||
eq(-1, eval('g:val')) -- timer did nothing yet.
|
||||
nvim_async('command', 'let g:val = 0')
|
||||
run(nil, nil, nil, load_adjust(20))
|
||||
retry(nil, nil, function()
|
||||
eq(2, eval("g:val"))
|
||||
eq(2, eval('g:val'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -65,52 +65,53 @@ describe('timers', function()
|
||||
-- timer_start does still not invoke the callback immediately
|
||||
eq(0, eval("[timer_start(0, 'MyHandler', {'repeat': 1000}), g:val][1]"))
|
||||
retry(nil, nil, function()
|
||||
eq(1000, eval("g:val"))
|
||||
eq(1000, eval('g:val'))
|
||||
end)
|
||||
end)
|
||||
|
||||
it('can be started during sleep', function()
|
||||
nvim_async("command", "sleep 10")
|
||||
nvim_async('command', 'sleep 10')
|
||||
-- this also tests that remote requests works during sleep
|
||||
eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 2}), g:val][1]"))
|
||||
run(nil, nil, nil, load_adjust(20))
|
||||
retry(nil, load_adjust(300), function() eq(2,eval("g:val")) end)
|
||||
retry(nil, load_adjust(300), function()
|
||||
eq(2, eval('g:val'))
|
||||
end)
|
||||
end)
|
||||
|
||||
it('are paused when event processing is disabled', function()
|
||||
command("call timer_start(5, 'MyHandler', {'repeat': -1})")
|
||||
run(nil, nil, nil, load_adjust(10))
|
||||
local count = eval("g:val")
|
||||
local count = eval('g:val')
|
||||
-- shows two line error message and thus invokes the return prompt.
|
||||
-- if we start to allow event processing here, we need to change this test.
|
||||
feed(':throw "fatal error"<CR>')
|
||||
run(nil, nil, nil, load_adjust(30))
|
||||
feed("<cr>")
|
||||
local diff = eval("g:val") - count
|
||||
assert(0 <= diff and diff <= 4,
|
||||
'expected (0 <= diff <= 4), got: '..tostring(diff))
|
||||
feed('<cr>')
|
||||
local diff = eval('g:val') - count
|
||||
assert(0 <= diff and diff <= 4, 'expected (0 <= diff <= 4), got: ' .. tostring(diff))
|
||||
end)
|
||||
|
||||
it('are triggered in blocking getchar() call', function()
|
||||
command("call timer_start(5, 'MyHandler', {'repeat': -1})")
|
||||
nvim_async("command", "let g:val = 0 | let g:c = getchar()")
|
||||
nvim_async('command', 'let g:val = 0 | let g:c = getchar()')
|
||||
retry(nil, nil, function()
|
||||
local val = eval("g:val")
|
||||
local val = eval('g:val')
|
||||
ok(val >= 2, '>= 2', tostring(val))
|
||||
eq(0, eval("getchar(1)"))
|
||||
eq(0, eval('getchar(1)'))
|
||||
end)
|
||||
feed("c")
|
||||
eq(99, eval("g:c"))
|
||||
feed('c')
|
||||
eq(99, eval('g:c'))
|
||||
end)
|
||||
|
||||
it('can invoke redraw in blocking getchar() call', function()
|
||||
local screen = Screen.new(40, 6)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids({
|
||||
[1] = {bold=true, foreground=Screen.colors.Blue},
|
||||
[1] = { bold = true, foreground = Screen.colors.Blue },
|
||||
})
|
||||
|
||||
curbufmeths.set_lines(0, -1, true, {"ITEM 1", "ITEM 2"})
|
||||
curbufmeths.set_lines(0, -1, true, { 'ITEM 1', 'ITEM 2' })
|
||||
source([[
|
||||
let g:cont = 0
|
||||
func! AddItem(timer)
|
||||
@@ -127,8 +128,8 @@ describe('timers', function()
|
||||
redraw
|
||||
endfunc
|
||||
]])
|
||||
nvim_async("command", "let g:c2 = getchar()")
|
||||
nvim_async("command", "call timer_start("..load_adjust(100)..", 'AddItem', {'repeat': -1})")
|
||||
nvim_async('command', 'let g:c2 = getchar()')
|
||||
nvim_async('command', 'call timer_start(' .. load_adjust(100) .. ", 'AddItem', {'repeat': -1})")
|
||||
|
||||
screen:expect([[
|
||||
^ITEM 1 |
|
||||
@@ -136,7 +137,7 @@ describe('timers', function()
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
nvim_async("command", "let g:cont = 1")
|
||||
nvim_async('command', 'let g:cont = 1')
|
||||
|
||||
screen:expect([[
|
||||
^ITEM 1 |
|
||||
@@ -146,15 +147,18 @@ describe('timers', function()
|
||||
|
|
||||
]])
|
||||
|
||||
feed("3")
|
||||
eq(51, eval("g:c2"))
|
||||
screen:expect{grid=[[
|
||||
feed('3')
|
||||
eq(51, eval('g:c2'))
|
||||
screen:expect {
|
||||
grid = [[
|
||||
^ITEM 1 |
|
||||
ITEM 2 |
|
||||
ITEM 3 |
|
||||
{1:~ }|*2
|
||||
|
|
||||
]], unchanged=true}
|
||||
]],
|
||||
unchanged = true,
|
||||
}
|
||||
end)
|
||||
|
||||
it('can be stopped', function()
|
||||
@@ -162,9 +166,9 @@ describe('timers', function()
|
||||
eq(0, t_init_val[2])
|
||||
run(nil, nil, nil, load_adjust(30))
|
||||
funcs.timer_stop(t_init_val[1])
|
||||
local count = eval("g:val")
|
||||
local count = eval('g:val')
|
||||
run(nil, load_adjust(300), nil, load_adjust(30))
|
||||
local count2 = eval("g:val")
|
||||
local count2 = eval('g:val')
|
||||
-- when count is eval:ed after timer_stop this should be non-racy
|
||||
eq(count, count2)
|
||||
end)
|
||||
@@ -180,10 +184,10 @@ describe('timers', function()
|
||||
endif
|
||||
endfunc
|
||||
]])
|
||||
eq(0, eval("g:val"))
|
||||
eq(0, eval('g:val'))
|
||||
command("call timer_start(10, 'MyHandler', {'repeat': -1})")
|
||||
retry(nil, nil, function()
|
||||
eq(3, eval("g:val"))
|
||||
eq(3, eval('g:val'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -197,8 +201,8 @@ describe('timers', function()
|
||||
command("call timer_start(2, 'MyHandler', {'repeat': 3})")
|
||||
command("call timer_start(4, 'MyHandler2', {'repeat': 2})")
|
||||
retry(nil, nil, function()
|
||||
eq(3, eval("g:val"))
|
||||
eq(2, eval("g:val2"))
|
||||
eq(3, eval('g:val'))
|
||||
eq(2, eval('g:val2'))
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -214,15 +218,14 @@ describe('timers', function()
|
||||
command("call timer_start(5, 'MyHandler', {'repeat': 1})")
|
||||
run(nil, nil, nil, load_adjust(20))
|
||||
retry(nil, load_adjust(150), function()
|
||||
eq(1, eval("g:val"))
|
||||
eq(1, eval('g:val'))
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
it("doesn't mess up the cmdline", function()
|
||||
local screen = Screen.new(40, 6)
|
||||
screen:attach()
|
||||
screen:set_default_attr_ids( {[0] = {bold=true, foreground=255}} )
|
||||
screen:set_default_attr_ids({ [0] = { bold = true, foreground = 255 } })
|
||||
source([[
|
||||
let g:val = 0
|
||||
func! MyHandler(timer)
|
||||
@@ -237,7 +240,7 @@ describe('timers', function()
|
||||
endfunc
|
||||
]])
|
||||
command("call timer_start(100, 'MyHandler', {'repeat': -1})")
|
||||
feed(":good")
|
||||
feed(':good')
|
||||
screen:expect([[
|
||||
|
|
||||
{0:~ }|*4
|
||||
@@ -255,7 +258,7 @@ describe('timers', function()
|
||||
call execute('echo ''execute() should be disallowed''', '')
|
||||
endfunction
|
||||
]]
|
||||
eq("Vim(call):E48: Not allowed in sandbox", exc_exec("sandbox call timer_start(0, 'Scary')"))
|
||||
eq('Vim(call):E48: Not allowed in sandbox', exc_exec("sandbox call timer_start(0, 'Scary')"))
|
||||
end)
|
||||
|
||||
it('can be triggered after an empty string <expr> mapping #17257', function()
|
||||
@@ -263,6 +266,6 @@ describe('timers', function()
|
||||
screen:attach()
|
||||
command([=[imap <expr> <F2> [timer_start(0, { _ -> execute("throw 'x'", "") }), ''][-1]]=])
|
||||
feed('i<F2>')
|
||||
screen:expect({any='E605: Exception not caught: x'})
|
||||
screen:expect({ any = 'E605: Exception not caught: x' })
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -10,8 +10,10 @@ before_each(clear)
|
||||
|
||||
describe('uniq()', function()
|
||||
it('errors out when processing special values', function()
|
||||
eq('Vim(call):E362: Using a boolean value as a Float',
|
||||
exc_exec('call uniq([v:true, v:false], "f")'))
|
||||
eq(
|
||||
'Vim(call):E362: Using a boolean value as a Float',
|
||||
exc_exec('call uniq([v:true, v:false], "f")')
|
||||
)
|
||||
end)
|
||||
|
||||
it('can yield E882 and stop filtering after that', function()
|
||||
@@ -23,7 +25,9 @@ describe('uniq()', function()
|
||||
return (a:a > a:b) - (a:a < a:b)
|
||||
endfunction
|
||||
]])
|
||||
eq('Vim(let):E745: Using a List as a Number',
|
||||
pcall_err(command, 'let fl = uniq([0, 0, [], 1, 1], "Cmp")'))
|
||||
eq(
|
||||
'Vim(let):E745: Using a List as a Number',
|
||||
pcall_err(command, 'let fl = uniq([0, 0, [], 1, 1], "Cmp")')
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -12,4 +12,3 @@ describe('v:event', function()
|
||||
eq(false, pcall(command, 'let v:event.mykey = {}'))
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
@@ -36,11 +36,12 @@ describe('wait()', function()
|
||||
end)
|
||||
|
||||
it('returns -2 when interrupted', function()
|
||||
feed_command('call rpcnotify(g:channel, "ready") | '..
|
||||
'call rpcnotify(g:channel, "wait", wait(-1, 0))')
|
||||
eq({'notification', 'ready', {}}, next_msg())
|
||||
feed_command(
|
||||
'call rpcnotify(g:channel, "ready") | ' .. 'call rpcnotify(g:channel, "wait", wait(-1, 0))'
|
||||
)
|
||||
eq({ 'notification', 'ready', {} }, next_msg())
|
||||
feed('<c-c>')
|
||||
eq({'notification', 'wait', {-2}}, next_msg())
|
||||
eq({ 'notification', 'wait', { -2 } }, next_msg())
|
||||
end)
|
||||
|
||||
it('returns -3 on error', function()
|
||||
|
||||
@@ -52,125 +52,151 @@ describe('writefile()', function()
|
||||
end)
|
||||
|
||||
it('writes list with an empty string to a file', function()
|
||||
eq(0, exc_exec(
|
||||
('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s", "b")'):format(
|
||||
fname)))
|
||||
eq(0, exc_exec(('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s", "b")'):format(fname)))
|
||||
eq('', read_file(fname))
|
||||
eq(0, exc_exec(('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s")'):format(
|
||||
fname)))
|
||||
eq(0, exc_exec(('call writefile([$XXX_NONEXISTENT_VAR_XXX], "%s")'):format(fname)))
|
||||
eq('\n', read_file(fname))
|
||||
end)
|
||||
|
||||
it('writes list with a null string to a file', function()
|
||||
eq(0, exc_exec(
|
||||
('call writefile([v:_null_string], "%s", "b")'):format(
|
||||
fname)))
|
||||
eq(0, exc_exec(('call writefile([v:_null_string], "%s", "b")'):format(fname)))
|
||||
eq('', read_file(fname))
|
||||
eq(0, exc_exec(('call writefile([v:_null_string], "%s")'):format(
|
||||
fname)))
|
||||
eq(0, exc_exec(('call writefile([v:_null_string], "%s")'):format(fname)))
|
||||
eq('\n', read_file(fname))
|
||||
end)
|
||||
|
||||
it('appends to a file', function()
|
||||
eq(nil, read_file(fname))
|
||||
eq(0, funcs.writefile({'abc', 'def', 'ghi'}, fname))
|
||||
eq(0, funcs.writefile({ 'abc', 'def', 'ghi' }, fname))
|
||||
eq('abc\ndef\nghi\n', read_file(fname))
|
||||
eq(0, funcs.writefile({'jkl'}, fname, 'a'))
|
||||
eq(0, funcs.writefile({ 'jkl' }, fname, 'a'))
|
||||
eq('abc\ndef\nghi\njkl\n', read_file(fname))
|
||||
os.remove(fname)
|
||||
eq(nil, read_file(fname))
|
||||
eq(0, funcs.writefile({'abc', 'def', 'ghi'}, fname, 'b'))
|
||||
eq(0, funcs.writefile({ 'abc', 'def', 'ghi' }, fname, 'b'))
|
||||
eq('abc\ndef\nghi', read_file(fname))
|
||||
eq(0, funcs.writefile({'jkl'}, fname, 'ab'))
|
||||
eq(0, funcs.writefile({ 'jkl' }, fname, 'ab'))
|
||||
eq('abc\ndef\nghijkl', read_file(fname))
|
||||
end)
|
||||
|
||||
it('correctly treats NLs', function()
|
||||
eq(0, funcs.writefile({'\na\nb\n'}, fname, 'b'))
|
||||
eq(0, funcs.writefile({ '\na\nb\n' }, fname, 'b'))
|
||||
eq('\0a\0b\0', read_file(fname))
|
||||
eq(0, funcs.writefile({'a\n\n\nb'}, fname, 'b'))
|
||||
eq(0, funcs.writefile({ 'a\n\n\nb' }, fname, 'b'))
|
||||
eq('a\0\0\0b', read_file(fname))
|
||||
end)
|
||||
|
||||
it('writes with s and S', function()
|
||||
eq(0, funcs.writefile({'\na\nb\n'}, fname, 'bs'))
|
||||
eq(0, funcs.writefile({ '\na\nb\n' }, fname, 'bs'))
|
||||
eq('\0a\0b\0', read_file(fname))
|
||||
eq(0, funcs.writefile({'a\n\n\nb'}, fname, 'bS'))
|
||||
eq(0, funcs.writefile({ 'a\n\n\nb' }, fname, 'bS'))
|
||||
eq('a\0\0\0b', read_file(fname))
|
||||
end)
|
||||
|
||||
it('correctly overwrites file', function()
|
||||
eq(0, funcs.writefile({'\na\nb\n'}, fname, 'b'))
|
||||
eq(0, funcs.writefile({ '\na\nb\n' }, fname, 'b'))
|
||||
eq('\0a\0b\0', read_file(fname))
|
||||
eq(0, funcs.writefile({'a\n'}, fname, 'b'))
|
||||
eq(0, funcs.writefile({ 'a\n' }, fname, 'b'))
|
||||
eq('a\0', read_file(fname))
|
||||
end)
|
||||
|
||||
it('shows correct file name when supplied numbers', function()
|
||||
meths.set_current_dir(dname)
|
||||
eq('Vim(call):E482: Can\'t open file 2 for writing: illegal operation on a directory',
|
||||
pcall_err(command, ('call writefile([42], %s)'):format(ddname_tail)))
|
||||
eq(
|
||||
"Vim(call):E482: Can't open file 2 for writing: illegal operation on a directory",
|
||||
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(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(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")'))
|
||||
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',
|
||||
pcall_err(command, 'call writefile()'))
|
||||
eq('Vim(call):E119: Not enough arguments for function: writefile',
|
||||
pcall_err(command, 'call writefile([])'))
|
||||
eq('Vim(call):E118: Too many arguments for function: writefile',
|
||||
pcall_err(command, ('call writefile([], "%s", "b", 1)'):format(fname)))
|
||||
for _, arg in ipairs({'0', '0.0', 'function("tr")', '{}', '"test"'}) do
|
||||
eq('Vim(call):E475: Invalid argument: writefile() first argument must be a List or a Blob',
|
||||
pcall_err(command, ('call writefile(%s, "%s", "b")'):format(arg, fname)))
|
||||
eq(
|
||||
'Vim(call):E119: Not enough arguments for function: writefile',
|
||||
pcall_err(command, 'call writefile()')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E119: Not enough arguments for function: writefile',
|
||||
pcall_err(command, 'call writefile([])')
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E118: Too many arguments for function: writefile',
|
||||
pcall_err(command, ('call writefile([], "%s", "b", 1)'):format(fname))
|
||||
)
|
||||
for _, arg in ipairs({ '0', '0.0', 'function("tr")', '{}', '"test"' }) do
|
||||
eq(
|
||||
'Vim(call):E475: Invalid argument: writefile() first argument must be a List or a Blob',
|
||||
pcall_err(command, ('call writefile(%s, "%s", "b")'):format(arg, fname))
|
||||
)
|
||||
end
|
||||
for _, args in ipairs({'[], %s, "b"', '[], "' .. fname .. '", %s'}) do
|
||||
eq('Vim(call):E730: Using a List as a String',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('[]'))))
|
||||
eq('Vim(call):E731: Using a Dictionary as a String',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('{}'))))
|
||||
eq('Vim(call):E729: Using a Funcref as a String',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")'))))
|
||||
for _, args in ipairs({ '[], %s, "b"', '[], "' .. fname .. '", %s' }) do
|
||||
eq(
|
||||
'Vim(call):E730: Using a List as a String',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('[]')))
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E731: Using a Dictionary as a String',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('{}')))
|
||||
)
|
||||
eq(
|
||||
'Vim(call):E729: Using a Funcref as a String',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")')))
|
||||
)
|
||||
end
|
||||
eq('Vim(call):E5060: Unknown flag: «»',
|
||||
pcall_err(command, ('call writefile([], "%s", "bs«»")'):format(fname)))
|
||||
eq(
|
||||
'Vim(call):E5060: Unknown flag: «»',
|
||||
pcall_err(command, ('call writefile([], "%s", "bs«»")'):format(fname))
|
||||
)
|
||||
eq('TEST', read_file(fname))
|
||||
end)
|
||||
|
||||
it('does not write to file if error in list', function()
|
||||
local args = '["tset"] + repeat([%s], 3), "' .. fname .. '"'
|
||||
eq('Vim(call):E805: Expected a Number or a String, Float found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('0.0'))))
|
||||
eq(
|
||||
'Vim(call):E805: Expected a Number or a String, Float found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('0.0')))
|
||||
)
|
||||
eq(nil, read_file(fname))
|
||||
write_file(fname, 'TEST')
|
||||
eq('Vim(call):E745: Expected a Number or a String, List found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('[]'))))
|
||||
eq(
|
||||
'Vim(call):E745: Expected a Number or a String, List found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('[]')))
|
||||
)
|
||||
eq('TEST', read_file(fname))
|
||||
eq('Vim(call):E728: Expected a Number or a String, Dictionary found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('{}'))))
|
||||
eq(
|
||||
'Vim(call):E728: Expected a Number or a String, Dictionary found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('{}')))
|
||||
)
|
||||
eq('TEST', read_file(fname))
|
||||
eq('Vim(call):E703: Expected a Number or a String, Funcref found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")'))))
|
||||
eq(
|
||||
'Vim(call):E703: Expected a Number or a String, Funcref found',
|
||||
pcall_err(command, ('call writefile(%s)'):format(args:format('function("tr")')))
|
||||
)
|
||||
eq('TEST', read_file(fname))
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user