aboutsummaryrefslogtreecommitdiff
path: root/test/functional/eval
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2021-09-17 09:16:40 -0700
committerGitHub <noreply@github.com>2021-09-17 09:16:40 -0700
commitd8de4eb685e35646c7d541e9a75bdc296127b7e2 (patch)
tree4bb05ec713856715ac9ba57e5d116eed344511b9 /test/functional/eval
parentd56002f7b722facd97b0958e141c8ed2d01495f7 (diff)
downloadrneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.tar.gz
rneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.tar.bz2
rneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.zip
test: reorg #15698
Problem: Subdirectories like "visual", "insert", "normal" encourage people to separate *related* tests for no good reason. Typically the _mode_ is not the relevant topic of a test (and when it is, _then_ create an appropriate describe() or it()). Solution: - Delete the various `test/functional/<mode>/` subdirectories, move their tests to more meaningful topics. - Rename `…/normal/` to `…/editor/`. - Move or merge `…/visual/*` and `…/insert/*` tests into here where appropriate. - Rename `…/eval/` to `…/vimscript/`. - Move `…/viml/*` into here also. * test(reorg): insert/* => editor/mode_insert_spec.lua * test(reorg): cmdline/* => editor/mode_cmdline_spec.lua * test(reorg): eval core tests => eval_spec.lua
Diffstat (limited to 'test/functional/eval')
-rw-r--r--test/functional/eval/api_functions_spec.lua167
-rw-r--r--test/functional/eval/backtick_expansion_spec.lua50
-rw-r--r--test/functional/eval/buf_functions_spec.lua306
-rw-r--r--test/functional/eval/changedtick_spec.lua142
-rw-r--r--test/functional/eval/container_functions_spec.lua24
-rw-r--r--test/functional/eval/ctx_functions_spec.lua406
-rw-r--r--test/functional/eval/environ_spec.lua80
-rw-r--r--test/functional/eval/executable_spec.lua218
-rw-r--r--test/functional/eval/execute_spec.lua337
-rw-r--r--test/functional/eval/exepath_spec.lua40
-rw-r--r--test/functional/eval/fnamemodify_spec.lua156
-rw-r--r--test/functional/eval/function_spec.lua37
-rw-r--r--test/functional/eval/getline_spec.lua39
-rw-r--r--test/functional/eval/glob_spec.lua28
-rw-r--r--test/functional/eval/has_spec.lua66
-rw-r--r--test/functional/eval/hostname_spec.lua20
-rw-r--r--test/functional/eval/input_spec.lua483
-rw-r--r--test/functional/eval/interrupt_spec.lua61
-rw-r--r--test/functional/eval/json_functions_spec.lua795
-rw-r--r--test/functional/eval/let_spec.lua93
-rw-r--r--test/functional/eval/map_functions_spec.lua163
-rw-r--r--test/functional/eval/match_functions_spec.lua157
-rw-r--r--test/functional/eval/minmax_functions_spec.lua51
-rw-r--r--test/functional/eval/modeline_spec.lua19
-rw-r--r--test/functional/eval/msgpack_functions_spec.lua755
-rw-r--r--test/functional/eval/null_spec.lua170
-rw-r--r--test/functional/eval/operators_spec.lua28
-rw-r--r--test/functional/eval/printf_spec.lua92
-rw-r--r--test/functional/eval/reltime_spec.lua53
-rw-r--r--test/functional/eval/server_spec.lua156
-rw-r--r--test/functional/eval/setpos_spec.lua64
-rw-r--r--test/functional/eval/sort_spec.lua57
-rw-r--r--test/functional/eval/special_vars_spec.lua190
-rw-r--r--test/functional/eval/string_spec.lua277
-rw-r--r--test/functional/eval/system_spec.lua589
-rw-r--r--test/functional/eval/timer_spec.lua265
-rw-r--r--test/functional/eval/uniq_spec.lua31
-rw-r--r--test/functional/eval/vvar_event_spec.lua15
-rw-r--r--test/functional/eval/wait_spec.lua78
-rw-r--r--test/functional/eval/writefile_spec.lua156
40 files changed, 0 insertions, 6914 deletions
diff --git a/test/functional/eval/api_functions_spec.lua b/test/functional/eval/api_functions_spec.lua
deleted file mode 100644
index d07e74d40e..0000000000
--- a/test/functional/eval/api_functions_spec.lua
+++ /dev/null
@@ -1,167 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local Screen = require('test.functional.ui.screen')
-local lfs = require('lfs')
-local neq, eq, command = helpers.neq, helpers.eq, helpers.command
-local clear, curbufmeths = helpers.clear, helpers.curbufmeths
-local exc_exec, expect, eval = helpers.exc_exec, helpers.expect, helpers.eval
-local insert, pcall_err = helpers.insert, helpers.pcall_err
-local meths = helpers.meths
-
-describe('eval-API', function()
- before_each(clear)
-
- 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'])")
- expect([[
- aa
- bb]])
-
- 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()
- local err = exc_exec('call nvim_get_current_buf("foo")')
- eq('Vim(call):E118: Too many arguments for function: nvim_get_current_buf', err)
-
- err = exc_exec('call nvim_set_option("hlsearch")')
- eq('Vim(call):E119: Not enough arguments for function: nvim_set_option', 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)
-
- 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)
-
- 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)
-
- err = exc_exec('call nvim_buf_line_count(17)')
- eq('Vim(call):E5555: API call: Invalid buffer id: 17', err)
- end)
-
- it('cannot change texts if textlocked', function()
- command("autocmd TextYankPost <buffer> ++once call nvim_buf_set_lines(0, 0, -1, v:false, [])")
- eq('Vim(call):E5555: API call: E523: Not allowed here', pcall_err(command, "normal! yy"))
- end)
-
- 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()")
- eq(bnr, bhnd)
- eq(wid, whnd)
-
- 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()")
- 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)"))
-
- 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()"))
- 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)"))
-
- command('call nvim_buf_set_lines(0, 1, 2, v:true, ["xx", "\\nyy"])')
- eq({'aa\0', 'xx', '\0yy'}, curbufmeths.get_lines(0, -1, 1))
- end)
-
- 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)
-
- -- Deprecated buffer_ prefix is not exported.
- err = exc_exec('call buffer_line_count(0)')
- eq('Vim(call):E117: Unknown function: buffer_line_count', err)
-
- -- Functions deprecated before the api functions became available
- -- in vimscript are not exported.
- err = exc_exec('call buffer_get_line(0, 1)')
- eq('Vim(call):E117: Unknown function: buffer_get_line', err)
-
- -- some api functions are only useful from a msgpack-rpc channel
- err = exc_exec('call nvim_subscribe("fancyevent")')
- eq('Vim(call):E117: Unknown function: nvim_subscribe', err)
- 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)
- end)
-
- it('are highlighted by vim.vim syntax file', function()
- if lfs.attributes("build/runtime/syntax/vim/generated.vim",'uid') == nil then
- pending("runtime was not built, skipping test")
- return
- end
- 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},
- })
-
- command("set ft=vim")
- command("let &rtp='build/runtime/,'.&rtp")
- command("syntax on")
- insert([[
- call bufnr('%')
- call nvim_input('typing...')
- call not_a_function(42)]])
-
- screen:expect([[
- {1:call} {2:bufnr}{3:(}{4:'%'}{3:)} |
- {1:call} {2:nvim_input}{3:(}{4:'typing...'}{3:)} |
- {1:call} not_a_function{3:(}{4:42}{3:^)} |
- {5:~ }|
- {5:~ }|
- {5:~ }|
- {5:~ }|
- |
- ]])
- 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))
- end)
-
- it('converts blobs to API strings', function()
- command('let g:v1 = nvim__id(0z68656c6c6f)')
- command('let g:v2 = nvim__id(v:_null_blob)')
- eq(1, eval('type(g:v1)'))
- eq(1, eval('type(g:v2)'))
- eq('hello', eval('g:v1'))
- eq('', eval('g:v2'))
- end)
-end)
diff --git a/test/functional/eval/backtick_expansion_spec.lua b/test/functional/eval/backtick_expansion_spec.lua
deleted file mode 100644
index b1b44cfa8b..0000000000
--- a/test/functional/eval/backtick_expansion_spec.lua
+++ /dev/null
@@ -1,50 +0,0 @@
-local lfs = require('lfs')
-local helpers = require('test.functional.helpers')(after_each)
-local clear, command, eval, eq = helpers.clear, helpers.command, helpers.eval, helpers.eq
-local write_file = helpers.write_file
-
-describe("backtick expansion", function()
- setup(function()
- clear()
- lfs.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")
- lfs.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)
-
- teardown(function()
- helpers.rmdir('test-backticks')
- end)
-
- it("with default 'shell'", function()
- if helpers.iswin() then
- command(":silent args `dir /b *2`")
- else
- command(":silent args `echo ***2`")
- end
- eq({ "file2", }, eval("argv()"))
- if helpers.iswin() then
- 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()"))
- end
- end)
-
- 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()"))
- end)
-end)
diff --git a/test/functional/eval/buf_functions_spec.lua b/test/functional/eval/buf_functions_spec.lua
deleted file mode 100644
index e957e5f5af..0000000000
--- a/test/functional/eval/buf_functions_spec.lua
+++ /dev/null
@@ -1,306 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local lfs = require('lfs')
-
-local eq = helpers.eq
-local clear = helpers.clear
-local funcs = helpers.funcs
-local meths = helpers.meths
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local bufmeths = helpers.bufmeths
-local winmeths = helpers.winmeths
-local curbufmeths = helpers.curbufmeths
-local curwinmeths = helpers.curwinmeths
-local curtabmeths = helpers.curtabmeths
-local get_pathsep = helpers.get_pathsep
-local rmdir = helpers.rmdir
-local pcall_err = helpers.pcall_err
-
-local fname = 'Xtest-functional-eval-buf_functions'
-local fname2 = fname .. '.2'
-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
- 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)))
- end
- 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")')))
- end)
- end)
-end
-
-describe('bufname() function', function()
- it('returns empty string when buffer was not found', function()
- command('file ' .. fname)
- eq('', funcs.bufname(2))
- eq('', funcs.bufname('non-existent-buffer'))
- eq('', funcs.bufname('#'))
- command('edit ' .. fname2)
- eq(2, funcs.bufnr('%'))
- eq('', funcs.bufname('X'))
- end)
- before_each(function()
- lfs.mkdir(dirname)
- end)
- after_each(function()
- rmdir(dirname)
- end)
- it('returns expected buffer name', function()
- eq('', funcs.bufname('%')) -- Buffer has no name yet
- command('file ' .. fname)
- local wd = lfs.currentdir()
- local sep = get_pathsep()
- local curdirname = funcs.fnamemodify(wd, ':t')
- for _, arg in ipairs({'%', 1, 'X', wd}) do
- eq(fname, funcs.bufname(arg))
- meths.set_current_dir('..')
- eq(curdirname .. sep .. fname, funcs.bufname(arg))
- meths.set_current_dir(curdirname)
- meths.set_current_dir(dirname)
- eq(wd .. sep .. fname, funcs.bufname(arg))
- meths.set_current_dir('..')
- eq(fname, funcs.bufname(arg))
- command('enew')
- end
- eq('', funcs.bufname('%'))
- eq('', funcs.bufname('$'))
- eq(2, funcs.bufnr('%'))
- end)
-end)
-
-describe('bufnr() function', function()
- it('returns -1 when buffer was not found', function()
- command('file ' .. fname)
- eq(-1, funcs.bufnr(2))
- eq(-1, funcs.bufnr('non-existent-buffer'))
- eq(-1, funcs.bufnr('#'))
- command('edit ' .. fname2)
- eq(2, funcs.bufnr('%'))
- eq(-1, funcs.bufnr('X'))
- end)
- it('returns expected buffer number', function()
- eq(1, funcs.bufnr('%'))
- command('file ' .. fname)
- local wd = lfs.currentdir()
- local curdirname = funcs.fnamemodify(wd, ':t')
- eq(1, funcs.bufnr(fname))
- eq(1, funcs.bufnr(wd))
- eq(1, funcs.bufnr(curdirname))
- eq(1, funcs.bufnr('X'))
- end)
- it('returns number of last buffer with "$"', function()
- eq(1, funcs.bufnr('$'))
- command('new')
- eq(2, funcs.bufnr('$'))
- command('new')
- eq(3, funcs.bufnr('$'))
- command('only')
- eq(3, funcs.bufnr('$'))
- eq(3, funcs.bufnr('%'))
- command('buffer 1')
- eq(3, funcs.bufnr('$'))
- eq(1, funcs.bufnr('%'))
- command('bwipeout 2')
- eq(3, funcs.bufnr('$'))
- eq(1, funcs.bufnr('%'))
- command('bwipeout 3')
- eq(1, funcs.bufnr('$'))
- eq(1, funcs.bufnr('%'))
- command('new')
- eq(4, funcs.bufnr('$'))
- end)
-end)
-
-describe('bufwinnr() function', function()
- it('returns -1 when buffer was not found', function()
- command('file ' .. fname)
- 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
- eq(2, funcs.bufnr('%'))
- eq(-1, funcs.bufwinnr('X'))
- end)
- before_each(function()
- lfs.mkdir(dirname)
- end)
- after_each(function()
- rmdir(dirname)
- end)
- it('returns expected window number', function()
- eq(1, funcs.bufwinnr('%'))
- command('file ' .. fname)
- command('vsplit')
- command('split ' .. fname2)
- eq(2, funcs.bufwinnr(fname))
- eq(1, funcs.bufwinnr(fname2))
- eq(-1, funcs.bufwinnr(fname:sub(1, #fname - 1)))
- meths.set_current_dir(dirname)
- eq(2, funcs.bufwinnr(fname))
- eq(1, funcs.bufwinnr(fname2))
- eq(-1, funcs.bufwinnr(fname:sub(1, #fname - 1)))
- eq(1, funcs.bufwinnr('%'))
- eq(2, funcs.bufwinnr(1))
- eq(1, funcs.bufwinnr(2))
- eq(-1, funcs.bufwinnr(3))
- eq(1, funcs.bufwinnr('$'))
- end)
-end)
-
-describe('getbufline() function', function()
- it('returns empty list when buffer was not found', function()
- command('file ' .. fname)
- eq({}, funcs.getbufline(2, 1))
- eq({}, funcs.getbufline('non-existent-buffer', 1))
- eq({}, funcs.getbufline('#', 1))
- command('edit ' .. fname2)
- eq(2, funcs.bufnr('%'))
- eq({}, funcs.getbufline('X', 1))
- end)
- it('returns empty list when range is invalid', function()
- eq({}, funcs.getbufline(1, 0))
- 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))
- eq({}, funcs.getbufline(1, -1, 9999))
- end)
- it('returns expected lines', function()
- meths.set_option('hidden', true)
- command('file ' .. fname)
- 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))
- end)
-end)
-
-describe('getbufvar() function', function()
- it('returns empty list when buffer was not found', function()
- command('file ' .. fname)
- eq('', funcs.getbufvar(2, '&autoindent'))
- eq('', funcs.getbufvar('non-existent-buffer', '&autoindent'))
- eq('', funcs.getbufvar('#', '&autoindent'))
- command('edit ' .. fname2)
- eq(2, funcs.bufnr('%'))
- eq('', funcs.getbufvar('X', '&autoindent'))
- end)
- it('returns empty list when variable/option/etc was not found', function()
- command('file ' .. fname)
- eq('', funcs.getbufvar(1, '&autondent'))
- eq('', funcs.getbufvar(1, 'changedtic'))
- end)
- it('returns expected option value', function()
- eq(0, funcs.getbufvar(1, '&autoindent'))
- eq(0, funcs.getbufvar(1, '&l:autoindent'))
- eq(0, funcs.getbufvar(1, '&g:autoindent'))
- -- Also works with global-only options
- eq(1, funcs.getbufvar(1, '&hidden'))
- eq(1, funcs.getbufvar(1, '&l:hidden'))
- eq(1, funcs.getbufvar(1, '&g:hidden'))
- -- Also works with window-local options
- eq(0, funcs.getbufvar(1, '&number'))
- eq(0, funcs.getbufvar(1, '&l:number'))
- eq(0, funcs.getbufvar(1, '&g:number'))
- command('new')
- -- But with window-local options it probably does not what you expect
- command("setl number")
- -- (note that current window’s buffer is 2, but getbufvar() receives 1)
- 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.
- eq(0, funcs.getbufvar(1, '&g:number'))
- end)
- it('returns expected variable value', function()
- eq(2, funcs.getbufvar(1, 'changedtick'))
- 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, ''))
- command('new')
- eq(3, funcs.getbufvar(1, 'changedtick'))
- eq(true, funcs.getbufvar(1, 'test'))
- 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)'))
- command('edit ' .. fname2)
- eq(2, funcs.bufnr('%'))
- 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()
- eq(false, curwinmeths.get_option('number'))
- command('split')
- command('new')
- eq(2, bufmeths.get_number(curwinmeths.get_buf()))
- funcs.setbufvar(1, '&number', true)
- local windows = curtabmeths.list_wins()
- eq(false, winmeths.get_option(windows[1], 'number'))
- eq(true, winmeths.get_option(windows[2], 'number'))
- eq(false, winmeths.get_option(windows[3], 'number'))
- eq(false, winmeths.get_option(meths.get_current_win(), 'number'))
-
- eq(true, meths.get_option('hidden'))
- funcs.setbufvar(1, '&hidden', 0)
- eq(false, meths.get_option('hidden'))
-
- eq(false, bufmeths.get_option(buf1, 'autoindent'))
- funcs.setbufvar(1, '&autoindent', true)
- eq(true, bufmeths.get_option(buf1, 'autoindent'))
- 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()
- command('split')
- command('new')
- 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(true, bufmeths.get_var(buf1, 'number'))
- eq('Vim:E46: Cannot change read-only variable "b:changedtick"',
- pcall_err(funcs.setbufvar, 1, 'changedtick', true))
- eq(2, funcs.getbufvar(1, 'changedtick'))
- end)
-end)
diff --git a/test/functional/eval/changedtick_spec.lua b/test/functional/eval/changedtick_spec.lua
deleted file mode 100644
index 99406d9d7a..0000000000
--- a/test/functional/eval/changedtick_spec.lua
+++ /dev/null
@@ -1,142 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local eval = helpers.eval
-local feed = helpers.feed
-local clear = helpers.clear
-local funcs = helpers.funcs
-local meths = helpers.meths
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local redir_exec = helpers.redir_exec
-local pcall_err = helpers.pcall_err
-local curbufmeths = helpers.curbufmeths
-
-before_each(clear)
-
-local function changedtick()
- local ct = curbufmeths.get_changedtick()
- eq(ct, curbufmeths.get_var('changedtick'))
- eq(ct, curbufmeths.get_var('changedtick'))
- eq(ct, eval('b:changedtick'))
- eq(ct, eval('b:["changedtick"]'))
- eq(ct, eval('b:.changedtick'))
- eq(ct, funcs.getbufvar('%', 'changedtick'))
- eq(ct, funcs.getbufvar('%', '').changedtick)
- eq(ct, eval('b:').changedtick)
- return ct
-end
-
-describe('b:changedtick', function()
- -- Ported tests from Vim-8.0.333
- it('increments', function() -- Test_changedtick_increments
- -- New buffer has an empty line, tick starts at 2
- eq(2, changedtick())
- funcs.setline(1, 'hello')
- eq(3, changedtick())
- eq(0, exc_exec('undo'))
- -- Somehow undo counts as two changes
- eq(5, changedtick())
- end)
- it('is present in b: dictionary', function()
- eq(2, changedtick())
- command('let d = b:')
- eq(2, meths.get_var('d').changedtick)
- end)
- it('increments at bdel', function()
- command('new')
- eq(2, changedtick())
- local bnr = curbufmeths.get_number()
- eq(2, bnr)
- command('bdel')
- eq(3, funcs.getbufvar(bnr, 'changedtick'))
- eq(1, curbufmeths.get_number())
- end)
- it('fails to be changed by user', function()
- local ct = changedtick()
- local ctn = ct + 100500
- eq(0, exc_exec('let d = b:'))
- eq('\nE46: Cannot change read-only variable "b:changedtick"',
- redir_exec('let b:changedtick = ' .. ctn))
- eq('\nE46: Cannot change read-only variable "b:["changedtick"]"',
- redir_exec('let b:["changedtick"] = ' .. ctn))
- eq('\nE46: Cannot change read-only variable "b:.changedtick"',
- redir_exec('let b:.changedtick = ' .. ctn))
- eq('\nE46: Cannot change read-only variable "d.changedtick"',
- redir_exec('let d.changedtick = ' .. ctn))
- eq('Key is read-only: changedtick',
- pcall_err(curbufmeths.set_var, 'changedtick', ctn))
-
- eq('\nE795: Cannot delete variable b:changedtick',
- redir_exec('unlet b:changedtick'))
- eq('\nE46: Cannot change read-only variable "b:.changedtick"',
- redir_exec('unlet b:.changedtick'))
- eq('\nE46: Cannot change read-only variable "b:["changedtick"]"',
- redir_exec('unlet b:["changedtick"]'))
- eq('\nE46: Cannot change read-only variable "d.changedtick"',
- redir_exec('unlet d.changedtick'))
- eq('Key is read-only: changedtick',
- pcall_err(curbufmeths.del_var, 'changedtick'))
- eq(ct, changedtick())
-
- eq('\nE46: Cannot change read-only variable "b:["changedtick"]"',
- redir_exec('let b:["changedtick"] += ' .. ctn))
- eq('\nE46: Cannot change read-only variable "b:["changedtick"]"',
- redir_exec('let b:["changedtick"] -= ' .. ctn))
- eq('\nE46: Cannot change read-only variable "b:["changedtick"]"',
- redir_exec('let b:["changedtick"] .= ' .. ctn))
-
- eq(ct, changedtick())
-
- funcs.setline(1, 'hello')
-
- eq(ct + 1, changedtick())
- end)
- it('is listed in :let output', function()
- eq('\nb:changedtick #2',
- redir_exec(':let b:'))
- end)
- it('fails to unlock b:changedtick', function()
- eq(0, exc_exec('let d = b:'))
- eq(0, funcs.islocked('b:changedtick'))
- eq(0, funcs.islocked('d.changedtick'))
- eq('\nE940: Cannot lock or unlock variable b:changedtick',
- redir_exec('unlockvar b:changedtick'))
- eq('\nE46: Cannot change read-only variable "d.changedtick"',
- redir_exec('unlockvar d.changedtick'))
- eq(0, funcs.islocked('b:changedtick'))
- eq(0, funcs.islocked('d.changedtick'))
- eq('\nE940: Cannot lock or unlock variable b:changedtick',
- redir_exec('lockvar b:changedtick'))
- eq('\nE46: Cannot change read-only variable "d.changedtick"',
- redir_exec('lockvar d.changedtick'))
- eq(0, funcs.islocked('b:changedtick'))
- eq(0, funcs.islocked('d.changedtick'))
- end)
- it('is being completed', function()
- feed(':echo b:<Tab><Home>let cmdline="<End>"<CR>')
- eq('echo b:changedtick', meths.get_var('cmdline'))
- end)
- it('cannot be changed by filter() or map()', function()
- eq(2, changedtick())
- eq('\nE795: Cannot delete variable filter() argument',
- redir_exec('call filter(b:, 0)'))
- eq('\nE742: Cannot change value of map() argument',
- redir_exec('call map(b:, 0)'))
- eq('\nE742: Cannot change value of map() argument',
- redir_exec('call map(b:, "v:val")'))
- eq(2, changedtick())
- end)
- it('cannot be remove()d', function()
- eq(2, changedtick())
- eq('\nE795: Cannot delete variable remove() argument',
- redir_exec('call remove(b:, "changedtick")'))
- eq(2, changedtick())
- end)
- it('does not inherit VAR_FIXED when copying dictionary over', function()
- eq(2, changedtick())
- eq('', redir_exec('let d1 = copy(b:)|let d1.changedtick = 42'))
- eq('', redir_exec('let d2 = copy(b:)|unlet d2.changedtick'))
- eq(2, changedtick())
- end)
-end)
diff --git a/test/functional/eval/container_functions_spec.lua b/test/functional/eval/container_functions_spec.lua
deleted file mode 100644
index 04a3248c49..0000000000
--- a/test/functional/eval/container_functions_spec.lua
+++ /dev/null
@@ -1,24 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local eval = helpers.eval
-local meths = helpers.meths
-local clear = helpers.clear
-
-before_each(clear)
-
-describe('extend()', function()
- it('suceeds 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, 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'))
- end)
-end)
diff --git a/test/functional/eval/ctx_functions_spec.lua b/test/functional/eval/ctx_functions_spec.lua
deleted file mode 100644
index f23adbc556..0000000000
--- a/test/functional/eval/ctx_functions_spec.lua
+++ /dev/null
@@ -1,406 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local call = helpers.call
-local clear = helpers.clear
-local command = helpers.command
-local eq = helpers.eq
-local eval = helpers.eval
-local feed = helpers.feed
-local map = helpers.tbl_map
-local nvim = helpers.nvim
-local parse_context = helpers.parse_context
-local redir_exec = helpers.redir_exec
-local source = helpers.source
-local trim = helpers.trim
-local write_file = helpers.write_file
-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'
-
- before_each(function()
- clear()
- write_file(fname1, "1\n2\n3")
- write_file(fname2, "a\nb\nc")
- end)
-
- after_each(function()
- os.remove(fname1)
- os.remove(fname2)
- end)
-
- describe('ctxpush/ctxpop', function()
- it('saves and restores registers properly', function()
- 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))
- call('ctxpush')
- call('ctxpush', {'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))
-
- 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))
- end)
-
- it('saves and restores jumplist properly', function()
- command('edit '..fname1)
- feed('G')
- feed('gg')
- command('edit '..fname2)
- local jumplist = call('getjumplist')
- call('ctxpush')
- call('ctxpush', {'jumps'})
-
- command('clearjumps')
- eq({{}, 0}, call('getjumplist'))
-
- call('ctxpop')
- eq(jumplist, call('getjumplist'))
-
- command('clearjumps')
- 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 TEST')
- local bufs = call('map', call('getbufinfo'), 'v:val.name')
- call('ctxpush')
- call('ctxpush', {'bufs'})
-
- command('%bwipeout')
- eq({''}, call('map', call('getbufinfo'), 'v:val.name'))
-
- call('ctxpop')
- eq({'', unpack(bufs)}, call('map', call('getbufinfo'), 'v:val.name'))
-
- command('%bwipeout')
- eq({''}, call('map', call('getbufinfo'), 'v:val.name'))
-
- call('ctxpop')
- 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]'))
- call('ctxpush')
- call('ctxpush', {'gvars'})
-
- nvim('del_var', 'one')
- nvim('del_var', 'Two')
- nvim('del_var', 'THREE')
- eq('Vim:E121: Undefined variable: g:one', pcall_err(eval, 'g:one'))
- eq('Vim:E121: Undefined variable: g:Two', pcall_err(eval, 'g:Two'))
- 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]'))
-
- nvim('del_var', 'one')
- nvim('del_var', 'Two')
- nvim('del_var', 'THREE')
- eq('Vim:E121: Undefined variable: g:one', pcall_err(eval, 'g:one'))
- eq('Vim:E121: Undefined variable: g:Two', pcall_err(eval, 'g:Two'))
- 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]'))
- end)
-
- it('saves and restores script functions properly', function()
- source([[
- function s:greet(name)
- echom 'Hello, '.a:name.'!'
- endfunction
-
- function s:greet_all(name, ...)
- echom 'Hello, '.a:name.'!'
- for more in a:000
- echom 'Hello, '.more.'!'
- endfor
- endfunction
-
- function Greet(name)
- call call('s:greet', [a:name])
- endfunction
-
- function GreetAll(name, ...)
- call call('s:greet_all', extend([a:name], a:000))
- endfunction
-
- function SaveSFuncs()
- call ctxpush(['sfuncs'])
- endfunction
-
- function DeleteSFuncs()
- delfunction s:greet
- delfunction s:greet_all
- endfunction
-
- function RestoreFuncs()
- call ctxpop()
- endfunction
- ]])
-
- eq('\nHello, World!', redir_exec([[call Greet('World')]]))
- eq('\nHello, World!'..
- '\nHello, One!'..
- '\nHello, Two!'..
- '\nHello, Three!',
- redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
-
- call('SaveSFuncs')
- call('DeleteSFuncs')
-
- eq('\nError detected while processing function Greet:'..
- '\nline 1:'..
- '\nE117: Unknown function: s:greet',
- redir_exec([[call Greet('World')]]))
- eq('\nError detected while processing function GreetAll:'..
- '\nline 1:'..
- '\nE117: Unknown function: s:greet_all',
- redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
-
- call('RestoreFuncs')
-
- eq('\nHello, World!', redir_exec([[call Greet('World')]]))
- eq('\nHello, World!'..
- '\nHello, One!'..
- '\nHello, Two!'..
- '\nHello, Three!',
- redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
- end)
-
- it('saves and restores functions properly', function()
- source([[
- function Greet(name)
- echom 'Hello, '.a:name.'!'
- endfunction
-
- function GreetAll(name, ...)
- echom 'Hello, '.a:name.'!'
- for more in a:000
- echom 'Hello, '.more.'!'
- endfor
- endfunction
- ]])
-
- eq('\nHello, World!', redir_exec([[call Greet('World')]]))
- eq('\nHello, World!'..
- '\nHello, One!'..
- '\nHello, Two!'..
- '\nHello, Three!',
- redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
-
- 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'))
-
- call('ctxpop')
-
- eq('\nHello, World!', redir_exec([[call Greet('World')]]))
- eq('\nHello, World!'..
- '\nHello, One!'..
- '\nHello, Two!'..
- '\nHello, Three!',
- redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]]))
- end)
-
- it('errors out when context stack is empty', function()
- local err = 'Vim:Context stack is empty'
- eq(err, pcall_err(call, 'ctxpop'))
- eq(err, pcall_err(call, 'ctxpop'))
- call('ctxpush')
- call('ctxpush')
- call('ctxpop')
- call('ctxpop')
- eq(err, pcall_err(call, 'ctxpop'))
- end)
- end)
-
- describe('ctxsize()', function()
- it('returns context stack size', function()
- eq(0, call('ctxsize'))
- call('ctxpush')
- eq(1, call('ctxsize'))
- call('ctxpush')
- eq(2, call('ctxsize'))
- call('ctxpush')
- eq(3, call('ctxsize'))
- call('ctxpop')
- eq(2, call('ctxsize'))
- call('ctxpop')
- eq(1, call('ctxsize'))
- call('ctxpop')
- eq(0, call('ctxsize'))
- end)
- end)
-
- describe('ctxget()', function()
- it('errors out when index is out of bounds', function()
- eq(outofbounds, pcall_err(call, 'ctxget'))
- call('ctxpush')
- eq(outofbounds, pcall_err(call, 'ctxget', 1))
- call('ctxpop')
- eq(outofbounds, pcall_err(call, 'ctxget', 0))
- end)
-
- it('returns context dictionary at index in context stack', function()
- feed('i1<cr>2<cr>3<c-[>ddddddqahjklq')
- command('edit! '..fname1)
- feed('G')
- feed('gg')
- 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},
- }
- }
-
- local with_jumps = {
- ['jumps'] = eval(([[
- filter(map(getjumplist()[0], 'filter(
- { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum },
- { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)')
- ]]):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}}
- }
-
- local with_all = {
- ['regs'] = with_regs['regs'],
- ['jumps'] = with_jumps['jumps'],
- ['bufs'] = with_bufs['bufs'],
- ['gvars'] = with_gvars['gvars'],
- }
-
- call('ctxpush')
- eq(with_all, parse_context(call('ctxget')))
- eq(with_all, parse_context(call('ctxget', 0)))
-
- 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'})
- 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'})
- 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'})
- eq(with_regs, parse_context(call('ctxget')))
- eq(with_regs, parse_context(call('ctxget', 0)))
- eq(with_jumps, parse_context(call('ctxget', 1)))
- eq(with_bufs, parse_context(call('ctxget', 2)))
- eq(with_gvars, parse_context(call('ctxget', 3)))
- eq(with_all, parse_context(call('ctxget', 4)))
-
- call('ctxpop')
- 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('ctxpop')
- 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('ctxpop')
- eq(with_gvars, parse_context(call('ctxget')))
- eq(with_gvars, parse_context(call('ctxget', 0)))
- eq(with_all, parse_context(call('ctxget', 1)))
-
- call('ctxpop')
- eq(with_all, parse_context(call('ctxget')))
- eq(with_all, parse_context(call('ctxget', 0)))
- end)
- end)
-
- describe('ctxset()', function()
- it('errors out when index is out of bounds', function()
- eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}))
- call('ctxpush')
- eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 1))
- call('ctxpop')
- eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 0))
- end)
-
- it('sets context dictionary at index in context stack', function()
- nvim('set_var', 'one', 1)
- nvim('set_var', 'Two', 2)
- nvim('set_var', 'THREE', 3)
- call('ctxpush')
- local ctx1 = call('ctxget')
- nvim('set_var', 'one', 'a')
- nvim('set_var', 'Two', 'b')
- nvim('set_var', 'THREE', 'c')
- call('ctxpush')
- call('ctxpush')
- local ctx2 = call('ctxget')
-
- 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]'))
- call('ctxpop')
- 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]'))
- call('ctxpop')
- eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]'))
- end)
- end)
-end)
diff --git a/test/functional/eval/environ_spec.lua b/test/functional/eval/environ_spec.lua
deleted file mode 100644
index 9e19568249..0000000000
--- a/test/functional/eval/environ_spec.lua
+++ /dev/null
@@ -1,80 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear = helpers.clear
-local eq = helpers.eq
-local environ = helpers.funcs.environ
-local exists = helpers.funcs.exists
-local system = helpers.funcs.system
-local nvim_prog = helpers.nvim_prog
-local command = helpers.command
-local eval = helpers.eval
-local setenv = helpers.funcs.setenv
-
-describe('environment variables', function()
- it('environ() handles empty env variable', function()
- 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=""}})
- eq(1, exists('$EMPTY_VAR'))
- eq(0, exists('$DOES_NOT_EXIST'))
- end)
-end)
-
-describe('empty $HOME', function()
- local original_home = os.getenv('HOME')
-
- -- recover $HOME after each test
- after_each(function()
- if original_home ~= nil then
- setenv('HOME', original_home)
- end
- os.remove('test_empty_home')
- os.remove('./~')
- end)
-
- local function tilde_in_cwd()
- -- get files in cwd
- command("let test_empty_home_cwd_files = split(globpath('.', '*'), '\n')")
- -- get the index of the file named '~'
- command('let test_empty_home_tilde_index = index(test_empty_home_cwd_files, "./~")')
- return eval('test_empty_home_tilde_index') ~= -1
- end
-
- local function write_and_test_tilde()
- 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")
- write_and_test_tilde()
-
- command("let $HOMEDRIVE='C:'")
- command("let $USERPROFILE='C:\\'")
- write_and_test_tilde()
-
- command("unlet $HOMEDRIVE")
- write_and_test_tilde()
-
- command("unlet $USERPROFILE")
- write_and_test_tilde()
-
- command("let $HOME='%USERPROFILE%'")
- command("let $USERPROFILE='C:\\'")
- write_and_test_tilde()
- end)
-
- it("'~' folder not created in cwd if writing a file with invalid $HOME", function()
- setenv('HOME', '/path/does/not/exist')
- write_and_test_tilde()
- end)
-
- it("'~' folder not created in cwd if writing a file with $HOME=''", function()
- command("let $HOME=''")
- write_and_test_tilde()
- end)
-end)
diff --git a/test/functional/eval/executable_spec.lua b/test/functional/eval/executable_spec.lua
deleted file mode 100644
index 28aefb72e5..0000000000
--- a/test/functional/eval/executable_spec.lua
+++ /dev/null
@@ -1,218 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, call, iswin, write_file, command =
- helpers.eq, helpers.clear, helpers.call, helpers.iswin, helpers.write_file,
- helpers.command
-local exc_exec = helpers.exc_exec
-local eval = helpers.eval
-
-describe('executable()', function()
- before_each(clear)
-
- it('returns 1 for commands in $PATH', function()
- local exe = iswin() and 'ping' or 'ls'
- eq(1, call('executable', exe))
- command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
- eq(1, call('executable', 'null'))
- eq(1, call('executable', 'true'))
- eq(1, call('executable', 'false'))
- end)
-
- it('fails for invalid values', function()
- for _, input in ipairs({'""', 'v:null', 'v:true', 'v:false', '{}', '[]'}) do
- eq('Vim(call):E928: String required', exc_exec('call executable('..input..')'))
- end
- command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
- for _, input in ipairs({'v:null', 'v:true', 'v:false'}) do
- eq('Vim(call):E928: String required', exc_exec('call executable('..input..')'))
- end
- end)
-
- it('returns 0 for non-existent files', function()
- eq(0, call('executable', 'no_such_file_exists_209ufq23f'))
- end)
-
- it('sibling to nvim binary', function()
- -- Some executable in build/bin/, *not* in $PATH nor CWD.
- local sibling_exe = 'printargs-test'
- -- Windows: siblings are in Nvim's "pseudo-$PATH".
- local expected = iswin() and 1 or 0
- if iswin() then
- eq('arg1=lemon;arg2=sky;arg3=tree;',
- call('system', sibling_exe..' lemon sky tree'))
- end
- eq(expected, call('executable', sibling_exe))
- end)
-
- describe('exec-bit', function()
- setup(function()
- clear()
- write_file('Xtest_not_executable', 'non-executable file')
- write_file('Xtest_executable', 'executable file (exec-bit set)')
- if not iswin() then -- N/A for Windows.
- call('system', {'chmod', '-x', 'Xtest_not_executable'})
- call('system', {'chmod', '+x', 'Xtest_executable'})
- end
- end)
-
- teardown(function()
- os.remove('Xtest_not_executable')
- os.remove('Xtest_executable')
- end)
-
- it('not set', function()
- eq(0, call('executable', 'Xtest_not_executable'))
- eq(0, call('executable', './Xtest_not_executable'))
- end)
-
- it('set, unqualified and not in $PATH', function()
- eq(0, call('executable', 'Xtest_executable'))
- end)
-
- it('set, qualified as a path', function()
- local expected = iswin() and 0 or 1
- eq(expected, call('executable', './Xtest_executable'))
- end)
- end)
-end)
-
-describe('executable() (Windows)', function()
- if not iswin() then return end -- N/A for Unix.
-
- local exts = {'bat', 'exe', 'com', 'cmd'}
- setup(function()
- for _, ext in ipairs(exts) do
- 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)
- 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))
- 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))
- end
- eq(0, call('executable', '.\\test_executable_zzz'))
- end)
-
- it('system([…]), jobstart([…]) use $PATHEXT #9569', function()
- -- 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'}))
- end)
-
- it('full path with extension', function()
- -- 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'
- eq(1, call('executable', exepath))
- eq('arg1=lemon;arg2=sky;arg3=tree;',
- call('system', exepath..' lemon sky tree'))
- end)
-
- it('full path without extension', function()
- -- 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))
- 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))
- 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))
- end
- eq(1, call('executable', '.\\test_executable_zzz'))
- end)
-
- it("with weird $PATHEXT", function()
- clear({env={PATHEXT=';'}})
- eq(0, call('executable', '.\\test_executable_zzz'))
- clear({env={PATHEXT=';;;.zzz;;'}})
- eq(1, call('executable', '.\\test_executable_zzz'))
- end)
-
- it("unqualified filename, Unix-style 'shell'", function()
- clear({env={PATHEXT=''}})
- command('set shell=sh')
- 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=''}})
- 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))
- 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))
- 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))
- 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))
- 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'}})
- eq(1, call('executable', 'test_executable_zzz.zzz'))
- end)
-
- it('relative path does not search $PATH', function()
- clear({env={PATHEXT=''}})
- eq(0, call('executable', './System32/notepad.exe'))
- eq(0, call('executable', '.\\System32\\notepad.exe'))
- eq(0, call('executable', '../notepad.exe'))
- eq(0, call('executable', '..\\notepad.exe'))
- end)
-end)
diff --git a/test/functional/eval/execute_spec.lua b/test/functional/eval/execute_spec.lua
deleted file mode 100644
index fccf52935b..0000000000
--- a/test/functional/eval/execute_spec.lua
+++ /dev/null
@@ -1,337 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq = helpers.eq
-local eval = helpers.eval
-local clear = helpers.clear
-local source = helpers.source
-local redir_exec = helpers.redir_exec
-local exc_exec = helpers.exc_exec
-local funcs = helpers.funcs
-local Screen = require('test.functional.ui.screen')
-local command = helpers.command
-local feed = helpers.feed
-local iswin = helpers.iswin
-
-describe('execute()', function()
- before_each(clear)
-
- it('captures the same result as :redir', function()
- eq(redir_exec('messages'), funcs.execute('messages'))
- 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"'}))
- end)
-
- it('supports nested execute("execute(...)")', function()
- eq('42', funcs.execute([[echon execute("echon execute('echon 42')")]]))
- end)
-
- it('supports nested :redir to a variable', function()
- source([[
- function! g:Foo()
- let a = ''
- redir => a
- silent echon "foo"
- redir END
- return a
- endfunction
- function! g:Bar()
- let a = ''
- redir => a
- silent echon "bar1"
- call g:Foo()
- silent echon "bar2"
- redir END
- silent echon "bar3"
- return a
- endfunction
- ]])
- eq('top1bar1foobar2bar3', funcs.execute('echon "top1"|call g:Bar()'))
- end)
-
- it('supports nested :redir to a register', function()
- source([[
- let @a = ''
- function! g:Foo()
- redir @a>>
- silent echon "foo"
- redir END
- return @a
- endfunction
- function! g:Bar()
- redir @a>>
- silent echon "bar1"
- call g:Foo()
- silent echon "bar2"
- redir END
- silent echon "bar3"
- return @a
- endfunction
- ]])
- eq('top1bar1foobar2bar3', funcs.execute('echon "top1"|call g:Bar()'))
- -- :redir itself doesn't nest, so the redirection ends in g:Foo
- eq('bar1foo', eval('@a'))
- end)
-
- it('captures a transformed string', function()
- eq('^A', funcs.execute('echon "\\<C-a>"'))
- end)
-
- it('returns empty string if the argument list is empty', function()
- eq('', funcs.execute({}))
- eq(0, exc_exec('let g:ret = execute(v:_null_list)'))
- eq('', eval('g:ret'))
- end)
-
- it('captures errors', function()
- local ret
- ret = exc_exec('call execute(0.0)')
- eq('Vim(call):E806: using Float as a String', ret)
- ret = exc_exec('call execute(v:_null_dict)')
- eq('Vim(call):E731: using Dictionary as a String', ret)
- ret = exc_exec('call execute(function("tr"))')
- eq('Vim(call):E729: using Funcref as a String', ret)
- ret = exc_exec('call execute(["echo 42", 0.0, "echo 44"])')
- eq('Vim:E806: using Float as a String', ret)
- ret = exc_exec('call execute(["echo 42", v:_null_dict, "echo 44"])')
- eq('Vim:E731: using Dictionary as a String', ret)
- ret = exc_exec('call execute(["echo 42", function("tr"), "echo 44"])')
- eq('Vim:E729: using Funcref as a String', ret)
- end)
-
- it('captures output with highlights', function()
- 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([[
- |
- {1:~ }|
- {1:~ }|
- {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},
- })
- feed('<CR>')
- end)
-
- it('places cursor correctly #6035', function()
- local screen = Screen.new(40, 6)
- screen:attach()
- source([=[
- " test 1: non-silenced output goes as usual
- function! Test1()
- echo 1234
- let x = execute('echon "abcdef"', '')
- echon 'ABCD'
- endfunction
-
- " test 2: silenced output does not affect ui
- function! Test2()
- echo 1234
- let x = execute('echon "abcdef"', 'silent')
- echon 'ABCD'
- endfunction
-
- " test 3: silenced! error does not affect ui
- function! Test3()
- echo 1234
- let x = execute('echoerr "abcdef"', 'silent!')
- echon 'ABCD'
- endfunction
-
- " test 4: silenced echoerr goes as usual
- " bug here
- function! Test4()
- echo 1234
- let x = execute('echoerr "abcdef"', 'silent')
- echon 'ABCD'
- endfunction
-
- " test 5: silenced! echoerr does not affect ui
- function! Test5()
- echo 1234
- let x = execute('echoerr "abcdef"', 'silent!')
- echon 'ABCD'
- endfunction
-
- " test 6: silenced error goes as usual
- function! Test6()
- echo 1234
- let x = execute('echo undefined', 'silent')
- echon 'ABCD'
- endfunction
-
- " test 7: existing error does not mess the result
- function! Test7()
- " display from Test6() is still visible
- " why does the "abcdef" goes into a newline
- let x = execute('echon "abcdef"', '')
- echon 'ABCD'
- endfunction
- ]=])
-
- feed([[:call Test1()<cr>]])
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ABCD |
- ]])
-
- feed([[:call Test2()<cr>]])
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- 1234ABCD |
- ]])
-
- feed([[:call Test3()<cr>]])
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- 1234ABCD |
- ]])
-
- feed([[:call Test4()<cr>]])
- -- unexpected: need to fix
- -- echoerr does not set did_emsg
- -- "ef" was overwritten since msg_col was recovered wrongly
- screen:expect([[
- 1234 |
- Error detected while processing function|
- Test4: |
- line 2: |
- abcdABCD |
- Press ENTER or type command to continue^ |
- ]])
-
- feed([[<cr>]]) -- to clear screen
- feed([[:call Test5()<cr>]])
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- 1234ABCD |
- ]])
-
- feed([[:call Test6()<cr>]])
- screen:expect([[
- |
- Error detected while processing function|
- Test6: |
- line 2: |
- E121ABCD |
- Press ENTER or type command to continue^ |
- ]])
-
- feed([[:call Test7()<cr>]])
- screen:expect([[
- Error detected while processing function|
- Test6: |
- line 2: |
- E121ABCD |
- ABCD |
- Press ENTER or type command to continue^ |
- ]])
- end)
-
- -- This deviates from vim behavior, but is consistent
- -- with how nvim currently displays the output.
- it('captures shell-command output', function()
- local win_lf = iswin() and '\13' or ''
- eq('\n:!echo foo\r\n\nfoo'..win_lf..'\n', funcs.execute('!echo foo'))
- end)
-
- describe('{silent} argument', function()
- it('captures & displays output for ""', function()
- local screen = Screen.new(40, 5)
- screen:attach()
- command('let g:mes = execute("echon 42", "")')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- 42 |
- ]])
- eq('42', eval('g:mes'))
- end)
-
- it('captures but does not display output for "silent"', function()
- local screen = Screen.new(40, 5)
- screen:attach()
- command('let g:mes = execute("echon 42")')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- |
- ]])
- eq('42', eval('g:mes'))
-
- command('let g:mes = execute("echon 13", "silent")')
- screen:expect{grid=[[
- ^ |
- ~ |
- ~ |
- ~ |
- |
- ]], unchanged=true}
- eq('13', eval('g:mes'))
- end)
-
- it('suppresses errors for "silent!"', function()
- eq(0, exc_exec('let g:mes = execute(0.0, "silent!")'))
- eq('', eval('g:mes'))
-
- eq(0, exc_exec('let g:mes = execute("echon add(1, 1)", "silent!")'))
- eq('1', eval('g:mes'))
-
- eq(0, exc_exec('let g:mes = execute(["echon 42", "echon add(1, 1)"], "silent!")'))
- eq('421', eval('g:mes'))
- end)
-
- it('propagates errors for "" and "silent"', function()
- local ret
- ret = exc_exec('call execute(0.0, "")')
- eq('Vim(call):E806: using Float as a String', ret)
-
- ret = exc_exec('call execute(v:_null_dict, "silent")')
- eq('Vim(call):E731: using Dictionary as a String', ret)
-
- ret = exc_exec('call execute("echo add(1, 1)", "")')
- eq('Vim(echo):E897: List or Blob required', ret)
-
- ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "")')
- eq('Vim(echo):E897: List or Blob required', ret)
-
- ret = exc_exec('call execute("echo add(1, 1)", "silent")')
- eq('Vim(echo):E897: List or Blob required', ret)
-
- ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "silent")')
- eq('Vim(echo):E897: List or Blob required', ret)
- end)
- end)
-end)
diff --git a/test/functional/eval/exepath_spec.lua b/test/functional/eval/exepath_spec.lua
deleted file mode 100644
index 08d2c59af8..0000000000
--- a/test/functional/eval/exepath_spec.lua
+++ /dev/null
@@ -1,40 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, call, iswin =
- helpers.eq, helpers.clear, helpers.call, helpers.iswin
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local matches = helpers.matches
-
-describe('exepath()', function()
- before_each(clear)
-
- it('returns 1 for commands in $PATH', function()
- local exe = iswin() and 'ping' or 'ls'
- local ext_pat = iswin() and '%.EXE$' or '$'
- matches(exe .. ext_pat, call('exepath', exe))
- command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
- ext_pat = iswin() and '%.CMD$' or '$'
- matches('null' .. ext_pat, call('exepath', 'null'))
- matches('true' .. ext_pat, call('exepath', 'true'))
- matches('false' .. ext_pat, call('exepath', 'false'))
- end)
-
- it('fails for invalid values', function()
- for _, input in ipairs({'""', 'v:null', 'v:true', 'v:false', '{}', '[]'}) do
- eq('Vim(call):E928: String required', exc_exec('call exepath('..input..')'))
- end
- command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
- for _, input in ipairs({'v:null', 'v:true', 'v:false'}) do
- eq('Vim(call):E928: String required', exc_exec('call exepath('..input..')'))
- end
- end)
-
- if iswin() then
- it('append extension if omitted', function()
- local filename = 'cmd'
- local pathext = '.exe'
- clear({env={PATHEXT=pathext}})
- eq(call('exepath', filename..pathext), call('exepath', filename))
- end)
- end
-end)
diff --git a/test/functional/eval/fnamemodify_spec.lua b/test/functional/eval/fnamemodify_spec.lua
deleted file mode 100644
index d54a6db417..0000000000
--- a/test/functional/eval/fnamemodify_spec.lua
+++ /dev/null
@@ -1,156 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear = helpers.clear
-local eq = helpers.eq
-local iswin = helpers.iswin
-local fnamemodify = helpers.funcs.fnamemodify
-local getcwd = helpers.funcs.getcwd
-local command = helpers.command
-local write_file = helpers.write_file
-local alter_slashes = helpers.alter_slashes
-
-local function eq_slashconvert(expected, got)
- eq(alter_slashes(expected), alter_slashes(got))
-end
-
-describe('fnamemodify()', function()
- setup(function()
- write_file('Xtest-fnamemodify.txt', [[foobar]])
- end)
-
- before_each(clear)
-
- teardown(function()
- os.remove('Xtest-fnamemodify.txt')
- end)
-
- it('handles the root path', function()
- local root = helpers.pathroot()
- eq(root, fnamemodify([[/]], ':p:h'))
- eq(root, fnamemodify([[/]], ':p'))
- if iswin() then
- eq(root, fnamemodify([[\]], ':p:h'))
- eq(root, fnamemodify([[\]], ':p'))
- command('set shellslash')
- root = string.sub(root, 1, -2)..'/'
- eq(root, fnamemodify([[\]], ':p:h'))
- eq(root, fnamemodify([[\]], ':p'))
- eq(root, fnamemodify([[/]], ':p:h'))
- eq(root, fnamemodify([[/]], ':p'))
- end
- end)
-
- it(':8 works', function()
- eq('Xtest-fnamemodify.txt', fnamemodify([[Xtest-fnamemodify.txt]], ':8'))
- end)
-
- it('handles examples from ":help filename-modifiers"', function()
- local filename = "src/version.c"
- local cwd = getcwd()
-
- eq_slashconvert(cwd .. '/src/version.c', fnamemodify(filename, ':p'))
-
- eq_slashconvert('src/version.c', fnamemodify(filename, ':p:.'))
- eq_slashconvert(cwd .. '/src', fnamemodify(filename, ':p:h'))
- eq_slashconvert(cwd .. '', fnamemodify(filename, ':p:h:h'))
- eq('version.c', fnamemodify(filename, ':p:t'))
- eq_slashconvert(cwd .. '/src/version', fnamemodify(filename, ':p:r'))
-
- eq_slashconvert(cwd .. '/src/main.c', fnamemodify(filename, ':s?version?main?:p'))
-
- local converted_cwd = cwd:gsub('/', '\\')
- eq(converted_cwd .. '\\src\\version.c', fnamemodify(filename, ':p:gs?/?\\\\?'))
-
- eq('src', fnamemodify(filename, ':h'))
- eq('version.c', fnamemodify(filename, ':t'))
- eq_slashconvert('src/version', fnamemodify(filename, ':r'))
- eq('version', fnamemodify(filename, ':t:r'))
- eq('c', fnamemodify(filename, ':e'))
-
- eq_slashconvert('src/main.c', fnamemodify(filename, ':s?version?main?'))
- end)
-
- it('handles advanced examples from ":help filename-modifiers"', function()
- local filename = "src/version.c.gz"
-
- eq('gz', fnamemodify(filename, ':e'))
- eq('c.gz', fnamemodify(filename, ':e:e'))
- eq('c.gz', fnamemodify(filename, ':e:e:e'))
-
- eq('c', fnamemodify(filename, ':e:e:r'))
-
- eq_slashconvert('src/version.c', fnamemodify(filename, ':r'))
- eq('c', fnamemodify(filename, ':r:e'))
-
- eq_slashconvert('src/version', fnamemodify(filename, ':r:r'))
- eq_slashconvert('src/version', fnamemodify(filename, ':r:r:r'))
- end)
-
- it('handles :h', function()
- eq('.', fnamemodify('hello.txt', ':h'))
-
- eq_slashconvert('path/to', fnamemodify('path/to/hello.txt', ':h'))
- end)
-
- it('handles :t', function()
- eq('hello.txt', fnamemodify('hello.txt', ':t'))
- eq_slashconvert('hello.txt', fnamemodify('path/to/hello.txt', ':t'))
- end)
-
- it('handles :r', function()
- eq('hello', fnamemodify('hello.txt', ':r'))
- eq_slashconvert('path/to/hello', fnamemodify('path/to/hello.txt', ':r'))
- end)
-
- it('handles :e', function()
- eq('txt', fnamemodify('hello.txt', ':e'))
- eq_slashconvert('txt', fnamemodify('path/to/hello.txt', ':e'))
- end)
-
- it('handles regex replacements', function()
- eq('content-there-here.txt', fnamemodify('content-here-here.txt', ':s/here/there/'))
- eq('content-there-there.txt', fnamemodify('content-here-here.txt', ':gs/here/there/'))
- end)
-
- it('handles shell escape', function()
- local expected
-
- if iswin() then
- -- we expand with double-quotes on Windows
- expected = [["hello there! quote ' newline]] .. '\n' .. [["]]
- else
- expected = [['hello there! quote '\'' newline]] .. '\n' .. [[']]
- end
-
- eq(expected, fnamemodify("hello there! quote ' newline\n", ':S'))
- end)
-
- it('can combine :e and :r', function()
- -- simple, single extension filename
- eq('c', fnamemodify('a.c', ':e'))
- eq('c', fnamemodify('a.c', ':e:e'))
- eq('c', fnamemodify('a.c', ':e:e:r'))
- eq('c', fnamemodify('a.c', ':e:e:r:r'))
-
- -- multi extension filename
- eq('rb', fnamemodify('a.spec.rb', ':e:r'))
- eq('rb', fnamemodify('a.spec.rb', ':e:r:r'))
-
- eq('spec', fnamemodify('a.spec.rb', ':e:e:r'))
- eq('spec', fnamemodify('a.spec.rb', ':e:e:r:r'))
-
- eq('spec', fnamemodify('a.b.spec.rb', ':e:e:r'))
- eq('b.spec', fnamemodify('a.b.spec.rb', ':e:e:e:r'))
- eq('b', fnamemodify('a.b.spec.rb', ':e:e:e:r:r'))
-
- eq('spec', fnamemodify('a.b.spec.rb', ':r:e'))
- eq('b', fnamemodify('a.b.spec.rb', ':r:r:e'))
-
- -- extraneous :e expansions
- eq('c', fnamemodify('a.b.c.d.e', ':r:r:e'))
- eq('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e'))
-
- -- :e never includes the whole filename, so "a.b":e:e:e --> "b"
- eq('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e'))
- eq('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e:e'))
- end)
-end)
diff --git a/test/functional/eval/function_spec.lua b/test/functional/eval/function_spec.lua
deleted file mode 100644
index ce8850fcc2..0000000000
--- a/test/functional/eval/function_spec.lua
+++ /dev/null
@@ -1,37 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local eq = helpers.eq
-local matches = helpers.matches
-local exc_exec = helpers.exc_exec
-local iswin = helpers.iswin
-local eval = helpers.eval
-
-describe('Up to MAX_FUNC_ARGS arguments are handled by', function()
- local max_func_args = 20 -- from eval.h
- local range = helpers.funcs.range
-
- before_each(clear)
-
- it('printf()', 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))))
- 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)
-
- it('rpcnotify()', function()
- local rpcnotify = helpers.funcs.rpcnotify
- local ret = rpcnotify(0, 'foo', unpack(range(3, max_func_args)))
- eq(1, ret)
- ret = exc_exec('call rpcnotify(0, "foo", 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 rpcnotify', ret)
- end)
-end)
-
-it('windowsversion()', function()
- clear()
- matches(iswin() and '^%d+%.%d+$' or '^$', eval('windowsversion()'))
-end)
diff --git a/test/functional/eval/getline_spec.lua b/test/functional/eval/getline_spec.lua
deleted file mode 100644
index 3c56bde094..0000000000
--- a/test/functional/eval/getline_spec.lua
+++ /dev/null
@@ -1,39 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local call = helpers.call
-local clear = helpers.clear
-local eq = helpers.eq
-local expect = helpers.expect
-
-describe('getline()', function()
- before_each(function()
- clear()
- call('setline', 1, {'a', 'b', 'c'})
- expect([[
- a
- b
- c]])
- end)
-
- it('returns empty string for invalid line', function()
- eq('', call('getline', -1))
- eq('', call('getline', 0))
- eq('', call('getline', 4))
- end)
-
- it('returns empty list for invalid range', function()
- eq({}, call('getline', 2, 1))
- eq({}, call('getline', -1, 1))
- eq({}, call('getline', 4, 4))
- end)
-
- it('returns value of valid line', function()
- eq('b', call('getline', 2))
- eq('a', call('getline', '.'))
- end)
-
- it('returns value of valid range', function()
- eq({'a', 'b'}, call('getline', 1, 2))
- eq({'a', 'b', 'c'}, call('getline', 1, 4))
- end)
-end)
diff --git a/test/functional/eval/glob_spec.lua b/test/functional/eval/glob_spec.lua
deleted file mode 100644
index b8807ecfcc..0000000000
--- a/test/functional/eval/glob_spec.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-local lfs = require('lfs')
-local helpers = require('test.functional.helpers')(after_each)
-local clear, command, eval, eq = helpers.clear, helpers.command, helpers.eval, helpers.eq
-
-before_each(function()
- clear()
- lfs.mkdir('test-glob')
-
- -- Long path might cause "Press ENTER" prompt; use :silent to avoid it.
- command('silent cd test-glob')
-end)
-
-after_each(function()
- lfs.rmdir('test-glob')
-end)
-
-describe('glob()', function()
- it("glob('.*') returns . and .. ", function()
- eq({'.', '..'}, eval("glob('.*', 0, 1)"))
- -- Do it again to verify scandir_next_with_dots() internal state.
- eq({'.', '..'}, eval("glob('.*', 0, 1)"))
- end)
- it("glob('*') returns an empty list ", function()
- eq({}, eval("glob('*', 0, 1)"))
- -- Do it again to verify scandir_next_with_dots() internal state.
- eq({}, eval("glob('*', 0, 1)"))
- end)
-end)
diff --git a/test/functional/eval/has_spec.lua b/test/functional/eval/has_spec.lua
deleted file mode 100644
index a3af2d1a20..0000000000
--- a/test/functional/eval/has_spec.lua
+++ /dev/null
@@ -1,66 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq = helpers.eq
-local clear = helpers.clear
-local funcs = helpers.funcs
-local iswin = helpers.iswin
-
-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(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 iswin()) and funcs.has("clipboard") == 1 then
- eq(1, funcs.has("unnamedplus"))
- else
- eq(0, funcs.has("unnamedplus"))
- end
- end)
-
- it('"wsl"', function()
- if 1 == funcs.has('win32') or 1 == funcs.has('mac') then
- eq(0, funcs.has('wsl'))
- end
- end)
-end)
diff --git a/test/functional/eval/hostname_spec.lua b/test/functional/eval/hostname_spec.lua
deleted file mode 100644
index 6112cf64e3..0000000000
--- a/test/functional/eval/hostname_spec.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq = helpers.eq
-local ok = helpers.ok
-local call = helpers.call
-local clear = helpers.clear
-local iswin = helpers.iswin
-
-describe('hostname()', function()
- before_each(clear)
-
- it('returns hostname string', function()
- local actual = call('hostname')
- ok(string.len(actual) > 0)
- if call('executable', 'hostname') == 1 then
- local expected = string.gsub(call('system', 'hostname'), '[\n\r]', '')
- eq((iswin() and expected:upper() or expected),
- (iswin() and actual:upper() or actual))
- end
- end)
-end)
diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua
deleted file mode 100644
index 14c02f9eb2..0000000000
--- a/test/functional/eval/input_spec.lua
+++ /dev/null
@@ -1,483 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local Screen = require('test.functional.ui.screen')
-
-local eq = helpers.eq
-local feed = helpers.feed
-local meths = helpers.meths
-local clear = helpers.clear
-local source = helpers.source
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local nvim_async = helpers.nvim_async
-
-local screen
-
-before_each(function()
- clear()
- screen = Screen.new(25, 5)
- screen:attach()
- source([[
- hi Test ctermfg=Red guifg=Red term=bold
- function CustomCompl(...)
- return 'TEST'
- endfunction
- function CustomListCompl(...)
- return ['FOO']
- endfunction
-
- highlight RBP1 guibg=Red
- highlight RBP2 guibg=Yellow
- highlight RBP3 guibg=Green
- highlight RBP4 guibg=Blue
- let g:NUM_LVLS = 4
- function Redraw()
- redraw!
- return ''
- endfunction
- cnoremap <expr> {REDRAW} Redraw()
- function RainBowParens(cmdline)
- let ret = []
- let i = 0
- let lvl = 0
- while i < len(a:cmdline)
- if a:cmdline[i] is# '('
- call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
- let lvl += 1
- elseif a:cmdline[i] is# ')'
- let lvl -= 1
- call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
- endif
- let i += 1
- endwhile
- return ret
- 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},
- })
-end)
-
-describe('input()', function()
- it('works with multiline prompts', function()
- feed([[:call input("Test\nFoo")<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {SEP: }|
- Test |
- Foo^ |
- ]])
- end)
- it('works with multiline prompts and :echohl', function()
- feed([[:echohl Test | call input("Test\nFoo")<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {SEP: }|
- {T:Test} |
- {T:Foo}^ |
- ]])
- command('redraw!')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo}^ |
- ]])
- end)
- it('allows unequal numeric arguments when using multiple args', function()
- command('echohl Test')
- feed([[:call input(1, 2)<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}2^ |
- ]])
- feed('<BS>')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}^ |
- ]])
- end)
- it('allows unequal numeric values when using {opts} dictionary', function()
- command('echohl Test')
- meths.set_var('opts', {prompt=1, default=2, cancelreturn=3})
- feed([[:echo input(opts)<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}2^ |
- ]])
- feed('<BS>')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}^ |
- ]])
- feed('<Esc>')
- screen:expect([[
- ^ |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:3} |
- ]])
- end)
- it('works with redraw', function()
- command('echohl Test')
- meths.set_var('opts', {prompt='Foo>', default='Bar'})
- feed([[:echo inputdialog(opts)<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Bar^ |
- ]])
- command('mode')
- screen:expect{grid=[[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Bar^ |
- ]], reset=true}
- feed('<BS>')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Ba^ |
- ]])
- command('mode')
- screen:expect{grid=[[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Ba^ |
- ]], reset=true}
- end)
- it('allows omitting everything with dictionary argument', function()
- command('echohl Test')
- feed([[:call input({})<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- ^ |
- ]])
- end)
- it('supports completion', function()
- feed(':let var = input("", "", "custom,CustomCompl")<CR>')
- feed('<Tab><CR>')
- eq('TEST', meths.get_var('var'))
-
- feed(':let var = input({"completion": "customlist,CustomListCompl"})<CR>')
- feed('<Tab><CR>')
- eq('FOO', meths.get_var('var'))
- end)
- it('supports cancelreturn', function()
- feed(':let var = input({"cancelreturn": "BAR"})<CR>')
- feed('<Esc>')
- eq('BAR', meths.get_var('var'))
- end)
- it('supports default string', function()
- feed(':let var = input("", "DEF1")<CR>')
- feed('<CR>')
- eq('DEF1', meths.get_var('var'))
-
- feed(':let var = input({"default": "DEF2"})<CR>')
- feed('<CR>')
- eq('DEF2', meths.get_var('var'))
- end)
- it('errors out on invalid inputs', function()
- eq('Vim(call):E730: using List as a String',
- exc_exec('call input([])'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call input("", [])'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call input("", "", [])'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call input({"prompt": []})'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call input({"cancelreturn": []})'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call input({"default": []})'))
- eq('Vim(call):E730: using 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]')
- feed([[X]])
- feed('(())')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {RBP1:(}{RBP2:()}{RBP1:)}^ |
- ]])
- end)
- it('is not hidden by :silent', function()
- feed([[:silent call input('Foo: ')<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {SEP: }|
- Foo: ^ |
- |
- ]])
- feed('Bar')
- screen:expect([[
- |
- {EOB:~ }|
- {SEP: }|
- Foo: Bar^ |
- |
- ]])
- feed('<CR>')
- end)
-end)
-describe('inputdialog()', function()
- it('works with multiline prompts', function()
- feed([[:call inputdialog("Test\nFoo")<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {SEP: }|
- Test |
- Foo^ |
- ]])
- end)
- it('works with multiline prompts and :echohl', function()
- feed([[:echohl Test | call inputdialog("Test\nFoo")<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {SEP: }|
- {T:Test} |
- {T:Foo}^ |
- ]])
- command('redraw!')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo}^ |
- ]])
- end)
- it('allows unequal numeric arguments when using multiple args', function()
- command('echohl Test')
- feed([[:call inputdialog(1, 2)<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}2^ |
- ]])
- feed('<BS>')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}^ |
- ]])
- end)
- it('allows unequal numeric values when using {opts} dictionary', function()
- command('echohl Test')
- meths.set_var('opts', {prompt=1, default=2, cancelreturn=3})
- feed([[:echo input(opts)<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}2^ |
- ]])
- feed('<BS>')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:1}^ |
- ]])
- feed('<Esc>')
- screen:expect([[
- ^ |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:3} |
- ]])
- end)
- it('works with redraw', function()
- command('echohl Test')
- meths.set_var('opts', {prompt='Foo>', default='Bar'})
- feed([[:echo input(opts)<CR>]])
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Bar^ |
- ]])
- command('mode')
- screen:expect{grid=[[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Bar^ |
- ]], reset=true}
- feed('<BS>')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Ba^ |
- ]])
- command('mode')
- screen:expect{grid=[[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {T:Foo>}Ba^ |
- ]], reset=true}
- end)
- it('allows omitting everything with dictionary argument', function()
- command('echohl Test')
- feed(':echo inputdialog({})<CR>')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- ^ |
- ]])
- end)
- it('supports completion', function()
- feed(':let var = inputdialog({"completion": "customlist,CustomListCompl"})<CR>')
- feed('<Tab><CR>')
- eq('FOO', meths.get_var('var'))
- end)
- it('supports cancelreturn', function()
- feed(':let var = inputdialog("", "", "CR1")<CR>')
- feed('<Esc>')
- eq('CR1', meths.get_var('var'))
-
- feed(':let var = inputdialog({"cancelreturn": "BAR"})<CR>')
- feed('<Esc>')
- eq('BAR', meths.get_var('var'))
- end)
- it('supports default string', function()
- feed(':let var = inputdialog("", "DEF1")<CR>')
- feed('<CR>')
- eq('DEF1', meths.get_var('var'))
-
- feed(':let var = inputdialog({"default": "DEF2"})<CR>')
- feed('<CR>')
- eq('DEF2', meths.get_var('var'))
- end)
- it('errors out on invalid inputs', function()
- eq('Vim(call):E730: using List as a String',
- exc_exec('call inputdialog([])'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call inputdialog("", [])'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call inputdialog("", "", [])'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call inputdialog({"prompt": []})'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call inputdialog({"cancelreturn": []})'))
- eq('Vim(call):E730: using List as a String',
- exc_exec('call inputdialog({"default": []})'))
- eq('Vim(call):E730: using 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]')
- feed([[X]])
- feed('(())')
- screen:expect([[
- |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {RBP1:(}{RBP2:()}{RBP1:)}^ |
- ]])
- end)
-end)
-
-describe('confirm()', 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..[[
- {CONFIRM:test} |
- {CONFIRM:[O]k: }^ |
- ]])
- feed('<cr>')
- command('redraw')
- command('bdelete!')
- end
-
- -- With shortmess-=F
- command('set shortmess-=F')
- feed(':edit foo<cr>')
- check_and_clear('"foo" [New] |\n')
-
- -- With shortmess+=F
- command('set shortmess+=F')
- feed(':edit foo<cr>')
- check_and_clear(':edit foo |\n')
-
- -- With :silent
- feed(':silent edit foo<cr>')
- check_and_clear(':silent edit foo |\n')
-
- -- With API (via eval/VimL) call and shortmess+=F
- feed(':call nvim_command("edit x")<cr>')
- check_and_clear(':call nvim_command("edit |\n')
-
- nvim_async('command', 'edit x')
- check_and_clear(' |\n')
- end)
-end)
diff --git a/test/functional/eval/interrupt_spec.lua b/test/functional/eval/interrupt_spec.lua
deleted file mode 100644
index 05b1f4ff57..0000000000
--- a/test/functional/eval/interrupt_spec.lua
+++ /dev/null
@@ -1,61 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local command = helpers.command
-local meths = helpers.meths
-local clear = helpers.clear
-local sleep = helpers.sleep
-local poke_eventloop = helpers.poke_eventloop
-local feed = helpers.feed
-local eq = helpers.eq
-
-local dur
-local min_dur = 8
-local len = 131072
-
-describe('List support code', function()
- 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.
- setup(function()
- clear()
- dur = 0
- while true do
- command(([[
- let rt = reltime()
- let bl = range(%u)
- let dur = reltimestr(reltime(rt))
- ]]):format(len))
- dur = tonumber(meths.get_var('dur'))
- if dur >= min_dur then
- -- print(('Using len %u, dur %g'):format(len, dur))
- break
- else
- len = len * 2
- end
- end
- end)
- it('allows interrupting copy', function()
- feed(':let t_rt = reltime()<CR>:let t_bl = copy(bl)<CR>')
- sleep(min_dur / 16 * 1000)
- feed('<C-c>')
- poke_eventloop()
- command('let t_dur = reltimestr(reltime(t_rt))')
- local t_dur = tonumber(meths.get_var('t_dur'))
- if t_dur >= dur / 8 then
- eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8))
- end
- end)
- it('allows interrupting join', function()
- feed(':let t_rt = reltime()<CR>:let t_j = join(bl)<CR>')
- sleep(min_dur / 16 * 1000)
- feed('<C-c>')
- poke_eventloop()
- command('let t_dur = reltimestr(reltime(t_rt))')
- local t_dur = tonumber(meths.get_var('t_dur'))
- print(('t_dur: %g'):format(t_dur))
- if t_dur >= dur / 8 then
- eq(nil, ('Took too long to cancel: %g >= %g'):format(t_dur, dur / 8))
- end
- end)
-end)
diff --git a/test/functional/eval/json_functions_spec.lua b/test/functional/eval/json_functions_spec.lua
deleted file mode 100644
index 9b5e207c07..0000000000
--- a/test/functional/eval/json_functions_spec.lua
+++ /dev/null
@@ -1,795 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear = helpers.clear
-local funcs = helpers.funcs
-local meths = helpers.meths
-local eq = helpers.eq
-local eval = helpers.eval
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local redir_exec = helpers.redir_exec
-local NIL = helpers.NIL
-local source = helpers.source
-
-describe('json_decode() function', function()
- local restart = function(...)
- clear(...)
- source([[
- language C
- function Eq(exp, act)
- let act = a:act
- let exp = a:exp
- if type(exp) != type(act)
- return 0
- endif
- if type(exp) == type({})
- if sort(keys(exp)) !=# sort(keys(act))
- return 0
- endif
- if sort(keys(exp)) ==# ['_TYPE', '_VAL']
- let exp_typ = v:msgpack_types[exp._TYPE]
- let act_typ = act._TYPE
- if exp_typ isnot act_typ
- return 0
- endif
- return Eq(exp._VAL, act._VAL)
- else
- return empty(filter(copy(exp), '!Eq(v:val, act[v:key])'))
- endif
- else
- if type(exp) == type([])
- if len(exp) != len(act)
- return 0
- endif
- return empty(filter(copy(exp), '!Eq(v:val, act[v:key])'))
- endif
- return exp ==# act
- endif
- return 1
- endfunction
- function EvalEq(exp, act_expr)
- let act = eval(a:act_expr)
- if Eq(a:exp, act)
- return 1
- else
- return string(act)
- endif
- endfunction
- ]])
- end
- before_each(restart)
-
- local speq = function(expected, actual_expr)
- eq(1, funcs.EvalEq(expected, actual_expr))
- end
-
- it('accepts readfile()-style list', function()
- eq({Test=1}, funcs.json_decode({
- '{',
- '\t"Test": 1',
- '}',
- }))
- end)
-
- it('accepts strings with newlines', function()
- eq({Test=1}, funcs.json_decode([[
- {
- "Test": 1
- }
- ]]))
- end)
-
- it('parses null, true, false', function()
- eq(NIL, funcs.json_decode('null'))
- eq(true, funcs.json_decode('true'))
- eq(false, funcs.json_decode('false'))
- 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 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")'))
- end)
-
- it('parses integer numbers', function()
- eq(100000, funcs.json_decode('100000'))
- eq(-100000, funcs.json_decode('-100000'))
- eq(100000, funcs.json_decode(' 100000 '))
- eq(-100000, funcs.json_decode(' -100000 '))
- eq(0, funcs.json_decode('0'))
- eq(0, funcs.json_decode('-0'))
- 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")'))
- 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")'))
- 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+")'))
- end)
-
- it('parses floating-point numbers', function()
- eq('100000.0', eval('string(json_decode("100000.0"))'))
- eq(100000.5, funcs.json_decode('100000.5'))
- eq(-100000.5, funcs.json_decode('-100000.5'))
- eq(-100000.5e50, funcs.json_decode('-100000.5e50'))
- eq(100000.5e50, funcs.json_decode('100000.5e50'))
- eq(100000.5e50, funcs.json_decode('100000.5e+50'))
- eq(-100000.5e-50, funcs.json_decode('-100000.5e-50'))
- eq(100000.5e-50, funcs.json_decode('100000.5e-50'))
- eq(100000e-50, funcs.json_decode('100000e-50'))
- eq(0.5, funcs.json_decode('0.5'))
- eq(0.005, funcs.json_decode('0.005'))
- eq(0.005, funcs.json_decode('0.00500'))
- eq(0.5, funcs.json_decode('0.00500e+002'))
- eq(0.00005, funcs.json_decode('0.00500e-002'))
-
- eq(-0.0, funcs.json_decode('-0.0'))
- eq(-0.0, funcs.json_decode('-0.0e0'))
- eq(-0.0, funcs.json_decode('-0.0e+0'))
- eq(-0.0, funcs.json_decode('-0.0e-0'))
- eq(-0.0, funcs.json_decode('-0e-0'))
- eq(-0.0, funcs.json_decode('-0e-2'))
- eq(-0.0, funcs.json_decode('-0e+2'))
-
- eq(0.0, funcs.json_decode('0.0'))
- eq(0.0, funcs.json_decode('0.0e0'))
- eq(0.0, funcs.json_decode('0.0e+0'))
- eq(0.0, funcs.json_decode('0.0e-0'))
- eq(0.0, funcs.json_decode('0e-0'))
- eq(0.0, funcs.json_decode('0e-2'))
- eq(0.0, funcs.json_decode('0e+2'))
- 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")'))
- 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(" : ")'))
- end)
-
- it('parses empty containers', function()
- eq({}, funcs.json_decode('[]'))
- eq('[]', eval('string(json_decode("[]"))'))
- 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("[")'))
- 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("}")'))
- 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("[}")'))
- 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}")'))
- 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("{:}")'))
- 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,}")'))
- 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\\"}")'))
- 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}")'))
- end)
-
- it('fails to parse concat of two values', function()
- 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]}}]}'))
- 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")'))
- end)
-
- it('fails to parse unknown escape sequnces', function()
- eq('Vim(call):E474: Unknown escape sequence: \\a"',
- exc_exec('call json_decode("\\t\\"\\\\a\\"")'))
- end)
-
- it('parses strings properly', function()
- eq('\n', funcs.json_decode('"\\n"'))
- eq('', funcs.json_decode('""'))
- 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"',
- ']',
- }))
- 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\\""])'))
- -- 0xC2 starts 2-byte unicode character
- 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\\"")'))
- -- 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\\"")'))
- -- 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\\"")'))
- -- 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\\"")'))
- -- 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\\"")'))
- -- '"\249\128\128\128\128"',
- -- '"\252\144\128\128\128\128"',
- end)
-
- it('parses surrogate pairs properly', function()
- eq('\240\144\128\128', funcs.json_decode('"\\uD800\\uDC00"'))
- eq('\237\160\128a\237\176\128', funcs.json_decode('"\\uD800a\\uDC00"'))
- eq('\237\160\128\t\237\176\128', funcs.json_decode('"\\uD800\\t\\uDC00"'))
-
- eq('\237\160\128', funcs.json_decode('"\\uD800"'))
- eq('\237\160\128a', funcs.json_decode('"\\uD800a"'))
- eq('\237\160\128\t', funcs.json_decode('"\\uD800\\t"'))
-
- eq('\237\176\128', funcs.json_decode('"\\uDC00"'))
- eq('\237\176\128a', funcs.json_decode('"\\uDC00a"'))
- eq('\237\176\128\t', funcs.json_decode('"\\uDC00\\t"'))
-
- eq('\237\176\128', funcs.json_decode('"\\uDC00"'))
- eq('a\237\176\128', funcs.json_decode('"a\\uDC00"'))
- eq('\t\237\176\128', funcs.json_decode('"\\t\\uDC00"'))
-
- eq('\237\160\128¬', funcs.json_decode('"\\uD800\\u00AC"'))
-
- eq('\237\160\128\237\160\128', funcs.json_decode('"\\uD800\\uD800"'))
- end)
-
- local sp_decode_eq = function(expected, json)
- meths.set_var('__json', json)
- speq(expected, 'json_decode(g:__json)')
- command('unlet! g:__json')
- 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"')
- 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}}]')
- end)
-
- it('parses dictionaries with empty keys to special maps', function()
- sp_decode_eq({_TYPE='map', _VAL={{'', 4}}},
- '{"": 4}')
- sp_decode_eq({_TYPE='map', _VAL={{'b', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {'', 4}}},
- '{"b": 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={{'', 3}, {'a', 1}, {'c', 4}, {'d', 2}, {'', 4}}}},
- '[{"": 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}')
- end)
-
- it('parses U+00C3 correctly', function()
- eq('\195\131', funcs.json_decode('"\195\131"'))
- 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 ")'))
- 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 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))
- end)
-
- it('does not overflow when writing error message about decoding ["", ""]',
- function()
- eq('\nE474: Attempt to decode a blank string'
- .. '\nE474: Failed to parse \n',
- redir_exec('call json_decode(["", ""])'))
- end)
-end)
-
-describe('json_encode() function', function()
- before_each(function()
- clear()
- command('language C')
- end)
-
- it('dumps strings', function()
- eq('"Test"', funcs.json_encode('Test'))
- eq('""', funcs.json_encode(''))
- eq('"\\t"', funcs.json_encode('\t'))
- eq('"\\n"', funcs.json_encode('\n'))
- eq('"\\u001B"', funcs.json_encode('\27'))
- eq('"þÿþ"', funcs.json_encode('þÿþ'))
- end)
-
- it('dumps blobs', function()
- eq('[]', eval('json_encode(0z)'))
- eq('[222, 173, 190, 239]', eval('json_encode(0zDEADBEEF)'))
- end)
-
- it('dumps numbers', function()
- eq('0', funcs.json_encode(0))
- eq('10', funcs.json_encode(10))
- eq('-10', funcs.json_encode(-10))
- end)
-
- it('dumps floats', function()
- eq('0.0', eval('json_encode(0.0)'))
- eq('10.5', funcs.json_encode(10.5))
- eq('-10.5', funcs.json_encode(-10.5))
- eq('-1.0e-5', funcs.json_encode(-1e-5))
- eq('1.0e50', eval('json_encode(1.0e50)'))
- 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"))'))
- end)
-
- it('dumps lists', function()
- 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={}}))
- end)
-
- 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": []}')
- command('call add(todump._VAL, [todumpv1, todumpv2])')
- eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
- end)
-
- it('cannot dump generic mapping with ext key', function()
- command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
- eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
- end)
-
- it('cannot dump generic mapping with array key', function()
- command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
- eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
- end)
-
- it('cannot dump generic mapping with UINT64_MAX key', function()
- command('let todump = {"_TYPE": v:msgpack_types.integer}')
- command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
- eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
- end)
-
- it('cannot dump generic mapping with floating-point key', function()
- command('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
- eq('Vim(call):E474: Invalid key in special dictionary', exc_exec('call json_encode(todump)'))
- end)
-
- it('can dump generic mapping with STR special key and NUL', function()
- command('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n"]}')
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
- eq('{"\\u0000": 1}', eval('json_encode(todump)'))
- end)
-
- it('can dump generic mapping with BIN special key and NUL', function()
- command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n"]}')
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}')
- eq('{"\\u0000": 1}', eval('json_encode(todump)'))
- end)
-
- it('can dump STR special mapping with NUL and NL', function()
- command('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n", ""]}')
- eq('"\\u0000\\n"', eval('json_encode(todump)'))
- end)
-
- it('can dump BIN special mapping with NUL and NL', function()
- command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n", ""]}')
- eq('"\\u0000\\n"', eval('json_encode(todump)'))
- end)
-
- it('cannot dump special ext mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
- eq('Vim(call):E474: Unable to convert EXT string to JSON', exc_exec('call json_encode(todump)'))
- end)
-
- it('can dump special array mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
- eq('[5, [""]]', eval('json_encode(todump)'))
- end)
-
- it('can dump special UINT64_MAX mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.integer}')
- command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
- eq('18446744073709551615', eval('json_encode(todump)'))
- end)
-
- it('can dump special INT64_MIN mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.integer}')
- command('let todump._VAL = [-1, 2, 0, 0]')
- eq('-9223372036854775808', eval('json_encode(todump)'))
- end)
-
- it('can dump special BOOLEAN true mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}')
- eq('true', eval('json_encode(todump)'))
- end)
-
- it('can dump special BOOLEAN false mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}')
- eq('false', eval('json_encode(todump)'))
- end)
-
- it('can dump special NIL mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}')
- eq('null', eval('json_encode(todump)'))
- 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"))'))
- 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], {}))'))
- 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")])'))
- 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)'))
- 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])'))
- end)
-
- it('can dump dict with two same dicts inside', function()
- command('let inter = {}')
- command('let todump = {"a": inter, "b": inter}')
- eq('{"a": {}, "b": {}}', eval('json_encode(todump)'))
- end)
-
- it('can dump list with two same lists inside', function()
- command('let inter = []')
- command('let todump = [inter, inter]')
- eq('[[], []]', eval('json_encode(todump)'))
- end)
-
- 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)'))
- 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])'))
- 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)'))
- end)
-
- 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)'))
- 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()'))
- 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)'))
- end)
-
- it('ignores improper values in &isprint', function()
- meths.set_option('isprint', '1')
- eq(1, eval('"\1" =~# "\\\\p"'))
- eq('"\\u0001"', funcs.json_encode('\1'))
- 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")'))
- 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"]})'))
- end)
-
- it('can dump NULL string', function()
- eq('""', eval('json_encode($XXX_UNEXISTENT_VAR_XXX)'))
- end)
-
- it('can dump NULL blob', function()
- eq('[]', eval('json_encode(v:_null_blob)'))
- end)
-
- it('can dump NULL list', function()
- eq('[]', eval('json_encode(v:_null_list)'))
- end)
-
- it('can dump NULL dictionary', function()
- eq('{}', eval('json_encode(v:_null_dict)'))
- 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)'))
- end)
-end)
diff --git a/test/functional/eval/let_spec.lua b/test/functional/eval/let_spec.lua
deleted file mode 100644
index 5bc703b567..0000000000
--- a/test/functional/eval/let_spec.lua
+++ /dev/null
@@ -1,93 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local clear = helpers.clear
-local command = helpers.command
-local eval = helpers.eval
-local meths = helpers.meths
-local redir_exec = helpers.redir_exec
-local source = helpers.source
-local nvim_dir = helpers.nvim_dir
-
-before_each(clear)
-
-describe(':let', function()
- it('correctly lists variables with curly-braces', function()
- meths.set_var('v', {0})
- eq('\nv [0]', redir_exec('let {"v"}'))
- end)
-
- it('correctly lists variables with subscript', function()
- meths.set_var('v', {0})
- eq('\nv[0] #0', redir_exec('let v[0]'))
- eq('\ng:["v"][0] #0', redir_exec('let g:["v"][0]'))
- eq('\n{"g:"}["v"][0] #0', redir_exec('let {"g:"}["v"][0]'))
- end)
-
- 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.
- source([=[
- let [l1, l2] = [[], []]
- echo 'l1:' . id(l1)
- echo 'l2:' . id(l2)
- echo ''
- let [l3, l4] = [[], []]
- call add(l4, l4)
- call add(l4, l3)
- call add(l3, 1)
- call add(l2, l2)
- call add(l2, l1)
- call add(l1, 1)
- unlet l2
- 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()
- command("let $NVIM_TEST = 'AìaB'")
- eq('AìaB', eval('$NVIM_TEST'))
- command("let $NVIM_TEST = 'AaあB'")
- eq('AaあB', eval('$NVIM_TEST'))
- local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
- .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
- .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
- command("let $NVIM_TEST = '"..mbyte.."'")
- eq(mbyte, eval('$NVIM_TEST'))
- end)
-
- it("multibyte env var to child process #8398 #9267", function()
- local cmd_get_child_env = "let g:env_from_child = system(['"..nvim_dir.."/printenv-test', 'NVIM_TEST'])"
- command("let $NVIM_TEST = 'AìaB'")
- command(cmd_get_child_env)
- eq(eval('$NVIM_TEST'), eval('g:env_from_child'))
-
- command("let $NVIM_TEST = 'AaあB'")
- command(cmd_get_child_env)
- eq(eval('$NVIM_TEST'), eval('g:env_from_child'))
-
- local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
- .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
- .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
- command("let $NVIM_TEST = '"..mbyte.."'")
- command(cmd_get_child_env)
- eq(eval('$NVIM_TEST'), eval('g:env_from_child'))
- end)
-
- it("release of list assigned to l: variable does not trigger assertion #12387, #12430", function()
- source([[
- func! s:f()
- let l:x = [1]
- let g:x = l:
- endfunc
- for _ in range(2)
- call s:f()
- endfor
- call garbagecollect()
- call feedkeys('i', 't')
- ]])
- eq(1, eval('1'))
- end)
-end)
diff --git a/test/functional/eval/map_functions_spec.lua b/test/functional/eval/map_functions_spec.lua
deleted file mode 100644
index 275c72d212..0000000000
--- a/test/functional/eval/map_functions_spec.lua
+++ /dev/null
@@ -1,163 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local eq = helpers.eq
-local eval = helpers.eval
-local funcs = helpers.funcs
-local nvim = helpers.nvim
-local source = helpers.source
-local command = helpers.command
-
-describe('maparg()', function()
- before_each(clear)
-
- local foo_bar_map_table = {
- lhs='foo',
- script=0,
- silent=0,
- rhs='bar',
- expr=0,
- sid=0,
- buffer=0,
- nowait=0,
- mode='n',
- noremap=1,
- lnum=0,
- }
-
- it('returns a dictionary', function()
- nvim('command', 'nnoremap foo bar')
- eq('bar', funcs.maparg('foo'))
- eq(foo_bar_map_table, funcs.maparg('foo', 'n', false, true))
- end)
-
- it('returns 1 for silent when <silent> is used', function()
- nvim('command', 'nnoremap <silent> foo bar')
- eq(1, funcs.maparg('foo', 'n', false, true)['silent'])
-
- nvim('command', 'nnoremap baz bat')
- eq(0, funcs.maparg('baz', 'n', false, true)['silent'])
- end)
-
- it('returns an empty string when no map is present', function()
- eq('', funcs.maparg('not a mapping'))
- end)
-
- it('returns an empty dictionary when no map is present and dict is requested', function()
- eq({}, funcs.maparg('not a mapping', 'n', false, true))
- end)
-
- it('returns the same value for noremap and <script>', function()
- nvim('command', 'inoremap <script> hello world')
- nvim('command', 'inoremap this that')
- eq(
- funcs.maparg('hello', 'i', false, true)['noremap'],
- funcs.maparg('this', 'i', false, true)['noremap']
- )
- end)
-
- it('returns a boolean for buffer', function()
- -- Open enough windows to know we aren't on buffer number 1
- nvim('command', 'new')
- nvim('command', 'new')
- nvim('command', 'new')
- nvim('command', 'cnoremap <buffer> this that')
- eq(1, funcs.maparg('this', 'c', false, true)['buffer'])
-
- -- Global will return 0 always
- nvim('command', 'nnoremap other another')
- eq(0, funcs.maparg('other', 'n', false, true)['buffer'])
- end)
-
- it('returns script numbers', function()
- source([[
- function! s:maparg_test_function() abort
- return 'testing'
- endfunction
-
- nnoremap fizz :call <SID>maparg_test_function()<CR>
- ]])
- eq(1, funcs.maparg('fizz', 'n', false, true)['sid'])
- eq('testing', nvim('call_function', '<SNR>1_maparg_test_function', {}))
- end)
-
- it('works with <F12> and others', function()
- source([[
- let g:maparg_test_var = 0
-
- nnoremap <F12> :let g:maparg_test_var = 1<CR>
- ]])
- eq(0, eval('g:maparg_test_var'))
- source([[
- call feedkeys("\<F12>")
- ]])
- eq(1, eval('g:maparg_test_var'))
-
- eq(':let g:maparg_test_var = 1<CR>', funcs.maparg('<F12>', 'n', false, true)['rhs'])
- end)
-
- it('works with <expr>', function()
- source([[
- let counter = 0
- inoremap <expr> <C-L> ListItem()
- inoremap <expr> <C-R> ListReset()
-
- func ListItem()
- let g:counter += 1
- return g:counter . '. '
- endfunc
-
- func ListReset()
- let g:counter = 0
- return ''
- endfunc
-
- call feedkeys("i\<C-L>")
- ]])
- eq(1, eval('g:counter'))
-
- local map_dict = funcs.maparg('<C-L>', 'i', false, true)
- eq(1, map_dict['expr'])
- eq('i', map_dict['mode'])
- end)
-
- 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 ret = s:gsub('`', acute)
- return ret
- end
- command(ac([[
- nnoremap a b`
- nnoremap c` d
- 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('f`'), funcs.maparg(ac('e`')))
-
- local function acmap(lhs, rhs)
- return {
- lhs = ac(lhs),
- rhs = ac(rhs),
-
- buffer = 0,
- expr = 0,
- mode = 'n',
- noremap = 1,
- nowait = 0,
- script=0,
- sid = 0,
- silent = 0,
- lnum = 0,
- }
- 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(acmap('e`', 'f`'), funcs.maparg(ac('e`'), 'n', 0, 1))
- end)
-end)
diff --git a/test/functional/eval/match_functions_spec.lua b/test/functional/eval/match_functions_spec.lua
deleted file mode 100644
index 9f168c913a..0000000000
--- a/test/functional/eval/match_functions_spec.lua
+++ /dev/null
@@ -1,157 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local Screen = require('test.functional.ui.screen')
-
-local eq = helpers.eq
-local clear = helpers.clear
-local funcs = helpers.funcs
-local command = helpers.command
-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()
- 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())
- 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())
- end)
-end)
-
-describe('matchadd()', 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())
- 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])'))
- 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())
- funcs.matchdelete(4)
- 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())
- 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())
- funcs.matchdelete(4)
- 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())
- 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())
- 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([[
- ^a{1:b}cdef |
- {2:~ }|
- {2:~ }|
- {2:~ }|
- |
- ]], {[1] = {foreground = Screen.colors.Red}, [2] = {bold = true, foreground = Screen.colors.Blue1}})
- end)
-end)
diff --git a/test/functional/eval/minmax_functions_spec.lua b/test/functional/eval/minmax_functions_spec.lua
deleted file mode 100644
index c6eb754f91..0000000000
--- a/test/functional/eval/minmax_functions_spec.lua
+++ /dev/null
@@ -1,51 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local eval = helpers.eval
-local clear = helpers.clear
-local funcs = helpers.funcs
-local redir_exec = helpers.redir_exec
-
-before_each(clear)
-for _, func in ipairs({'min', 'max'}) do
- describe(func .. '()', function()
- it('gives a single error message when multiple values failed conversions',
- function()
- eq('\nE745: Using a List as a Number\n0',
- redir_exec('echo ' .. func .. '([-5, [], [], [], 5])'))
- eq('\nE745: Using a List as a Number\n0',
- redir_exec('echo ' .. func .. '({1:-5, 2:[], 3:[], 4:[], 5:5})'))
- for errmsg, errinput in pairs({
- ['E745: Using a List as a Number'] = '[]',
- ['E805: Using a Float as a Number'] = '0.0',
- ['E703: Using a Funcref as a Number'] = 'function("tr")',
- ['E728: Using a Dictionary as a Number'] = '{}',
- }) do
- eq('\n' .. errmsg .. '\n0',
- redir_exec('echo ' .. func .. '([' .. errinput .. '])'))
- eq('\n' .. errmsg .. '\n0',
- redir_exec('echo ' .. func .. '({1:' .. errinput .. '})'))
- end
- end)
- it('works with arrays/dictionaries with zero items', function()
- eq(0, funcs[func]({}))
- 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}))
- 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(('\nE712: Argument of %s() must be a List or Dictionary\n0'):format(
- func),
- redir_exec('echo ' .. func .. '(' .. errinput .. ')'))
- end
- end)
- end)
-end
diff --git a/test/functional/eval/modeline_spec.lua b/test/functional/eval/modeline_spec.lua
deleted file mode 100644
index b2346079a1..0000000000
--- a/test/functional/eval/modeline_spec.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-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()
- local tempfile = helpers.tmpname()
- before_each(clear)
-
- after_each(function()
- os.remove(tempfile)
- end)
-
- it('does not crash with a large version number', function()
- write_file(tempfile, 'vim100000000000000000000000')
- command('e! ' .. tempfile)
-
- assert_alive()
- end)
-end)
diff --git a/test/functional/eval/msgpack_functions_spec.lua b/test/functional/eval/msgpack_functions_spec.lua
deleted file mode 100644
index 837b629858..0000000000
--- a/test/functional/eval/msgpack_functions_spec.lua
+++ /dev/null
@@ -1,755 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear = helpers.clear
-local funcs = helpers.funcs
-local eval, eq = helpers.eval, helpers.eq
-local command = helpers.command
-local nvim = helpers.nvim
-local exc_exec = helpers.exc_exec
-
-describe('msgpack*() functions', function()
- before_each(clear)
-
- local obj_test = function(msg, obj)
- it(msg, function()
- nvim('set_var', 'obj', obj)
- eq(obj, eval('msgpackparse(msgpackdump(g:obj))'))
- eq(obj, eval('msgpackparse(msgpackdump(g:obj, "B"))'))
- end)
- end
-
- -- Regression test: msgpack_list_write was failing to write buffer with zero
- -- length.
- obj_test('are able to dump and restore {"file": ""}', {{file=''}})
- -- Regression test: msgpack_list_write was failing to write buffer with NL at
- -- the end.
- obj_test('are able to dump and restore {0, "echo mpack"}', {{0, 'echo mpack'}})
- obj_test('are able to dump and restore "Test\\n"', {'Test\n'})
- -- Regression test: msgpack_list_write was failing to write buffer with NL
- -- inside.
- obj_test('are able to dump and restore "Test\\nTest 2"', {'Test\nTest 2'})
- -- Test that big objects (requirement: dump to something that is bigger then
- -- IOSIZE) are also fine. This particular object is obtained by concatenating
- -- 5 identical shada files.
- local big_obj = {
- 1, 1436711454, 78, {
- encoding="utf-8",
- max_kbyte=10,
- pid=19269,
- version="NVIM 0.0.0-alpha+201507121634"
- },
- 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 8, 1436711391, 8, { file="" },
- 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
- 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
- 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
- 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
- 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
- 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
- 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
- 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
- 4, 1436708966, 6, { 0, "cq" },
- 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
- 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
- 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
- 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
- 4, 1436709634, 57, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
- },
- 4, 1436709651, 67, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
- },
- 4, 1436709660, 70, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
- },
- 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
- 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
- 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
- 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
- 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
- 4, 1436711142, 14, { 0, "echo mpack" },
- 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
- 4, 1436711206, 16, { 0, "echo lengths" },
- 4, 1436711244, 92, {
- 0,
- ("let sum = len(lengths) - 1 | call map(copy(lengths), "
- .. "'extend(g:, {\"sum\": sum + v:val})')")
- },
- 4, 1436711245, 12, { 0, "echo sum" },
- 4, 1436711398, 10, { 0, "echo s" },
- 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
- 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
- 4, 1436711415, 22, { 0, "echo shada_objects" },
- 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
- 4, 1436711454, 6, { 0, "qa" },
- 4, 1436711442, 9, { 1, "test", 47 },
- 4, 1436711443, 15, { 1, "aontsuesan", 47 },
- 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
- 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
- 3, 0, 3, { "" },
- 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 1, 1436711454, 78, {
- encoding="utf-8",
- max_kbyte=10,
- pid=19269,
- version="NVIM 0.0.0-alpha+201507121634"
- },
- 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 8, 1436711391, 8, { file="" },
- 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
- 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
- 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
- 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
- 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
- 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
- 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
- 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
- 4, 1436708966, 6, { 0, "cq" },
- 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
- 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
- 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
- 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
- 4, 1436709634, 57, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
- },
- 4, 1436709651, 67, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
- },
- 4, 1436709660, 70, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
- },
- 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
- 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
- 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
- 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
- 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
- 4, 1436711142, 14, { 0, "echo mpack" },
- 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
- 4, 1436711206, 16, { 0, "echo lengths" },
- 4, 1436711244, 92, {
- 0,
- ("let sum = len(lengths) - 1 | call map(copy(lengths), "
- .. "'extend(g:, {\"sum\": sum + v:val})')")
- },
- 4, 1436711245, 12, { 0, "echo sum" },
- 4, 1436711398, 10, { 0, "echo s" },
- 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
- 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
- 4, 1436711415, 22, { 0, "echo shada_objects" },
- 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
- 4, 1436711454, 6, { 0, "qa" },
- 4, 1436711442, 9, { 1, "test", 47 },
- 4, 1436711443, 15, { 1, "aontsuesan", 47 },
- 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
- 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
- 3, 0, 3, { "" },
- 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 1, 1436711454, 78, {
- encoding="utf-8",
- max_kbyte=10,
- pid=19269,
- version="NVIM 0.0.0-alpha+201507121634"
- },
- 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 8, 1436711391, 8, { file="" },
- 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
- 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
- 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
- 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
- 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
- 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
- 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
- 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
- 4, 1436708966, 6, { 0, "cq" },
- 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
- 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
- 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
- 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
- 4, 1436709634, 57, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
- },
- 4, 1436709651, 67, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
- },
- 4, 1436709660, 70, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
- },
- 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
- 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
- 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
- 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
- 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
- 4, 1436711142, 14, { 0, "echo mpack" },
- 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
- 4, 1436711206, 16, { 0, "echo lengths" },
- 4, 1436711244, 92, {
- 0,
- ("let sum = len(lengths) - 1 | call map(copy(lengths), "
- .. "'extend(g:, {\"sum\": sum + v:val})')")
- },
- 4, 1436711245, 12, { 0, "echo sum" },
- 4, 1436711398, 10, { 0, "echo s" },
- 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
- 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
- 4, 1436711415, 22, { 0, "echo shada_objects" },
- 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
- 4, 1436711454, 6, { 0, "qa" },
- 4, 1436711442, 9, { 1, "test", 47 },
- 4, 1436711443, 15, { 1, "aontsuesan", 47 },
- 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
- 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
- 3, 0, 3, { "" },
- 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 1, 1436711454, 78, {
- encoding="utf-8",
- max_kbyte=10,
- pid=19269,
- version="NVIM 0.0.0-alpha+201507121634"
- },
- 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 8, 1436711391, 8, { file="" },
- 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
- 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
- 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
- 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
- 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
- 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
- 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
- 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
- 4, 1436708966, 6, { 0, "cq" },
- 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
- 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
- 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
- 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
- 4, 1436709634, 57, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
- },
- 4, 1436709651, 67, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
- },
- 4, 1436709660, 70, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
- },
- 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
- 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
- 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
- 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
- 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
- 4, 1436711142, 14, { 0, "echo mpack" },
- 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
- 4, 1436711206, 16, { 0, "echo lengths" },
- 4, 1436711244, 92, {
- 0,
- ("let sum = len(lengths) - 1 | call map(copy(lengths), "
- .. "'extend(g:, {\"sum\": sum + v:val})')")
- },
- 4, 1436711245, 12, { 0, "echo sum" },
- 4, 1436711398, 10, { 0, "echo s" },
- 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
- 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
- 4, 1436711415, 22, { 0, "echo shada_objects" },
- 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
- 4, 1436711454, 6, { 0, "qa" },
- 4, 1436711442, 9, { 1, "test", 47 },
- 4, 1436711443, 15, { 1, "aontsuesan", 47 },
- 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
- 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
- 3, 0, 3, { "" },
- 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 1, 1436711454, 78, {
- encoding="utf-8",
- max_kbyte=10,
- pid=19269,
- version="NVIM 0.0.0-alpha+201507121634"
- },
- 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
- 8, 1436711391, 8, { file="" },
- 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
- 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
- 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
- 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
- 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
- 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
- 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
- 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
- 4, 1436708966, 6, { 0, "cq" },
- 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
- 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
- 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
- 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
- 4, 1436709634, 57, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
- },
- 4, 1436709651, 67, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
- },
- 4, 1436709660, 70, {
- 0,
- "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
- },
- 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
- 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
- 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
- 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
- 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
- 4, 1436711142, 14, { 0, "echo mpack" },
- 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
- 4, 1436711206, 16, { 0, "echo lengths" },
- 4, 1436711244, 92, {
- 0,
- ("let sum = len(lengths) - 1 | call map(copy(lengths), "
- .. "'extend(g:, {\"sum\": sum + v:val})')")
- },
- 4, 1436711245, 12, { 0, "echo sum" },
- 4, 1436711398, 10, { 0, "echo s" },
- 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
- 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
- 4, 1436711415, 22, { 0, "echo shada_objects" },
- 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
- 4, 1436711454, 6, { 0, "qa" },
- 4, 1436711442, 9, { 1, "test", 47 },
- 4, 1436711443, 15, { 1, "aontsuesan", 47 },
- 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
- 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
- 3, 0, 3, { "" },
- 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" }
- }
- obj_test('are able to dump and restore rather big object', big_obj)
-
- obj_test('are able to dump and restore floating-point value', {0.125})
-
- it('can restore and dump UINT64_MAX', function()
- command('let dumped = ["\\xCF" . repeat("\\xFF", 8)]')
- command('let parsed = msgpackparse(dumped)')
- command('let dumped2 = msgpackdump(parsed)')
- eq(1, eval('type(parsed[0]) == type(0) ' ..
- '|| parsed[0]._TYPE is v:msgpack_types.integer'))
- if eval('type(parsed[0]) == type(0)') == 1 then
- command('call assert_equal(0xFFFFFFFFFFFFFFFF, parsed[0])')
- eq({}, eval('v:errors'))
- else
- eq({_TYPE={}, _VAL={1, 3, 0x7FFFFFFF, 0x7FFFFFFF}}, eval('parsed[0]'))
- end
- eq(1, eval('dumped ==# dumped2'))
- end)
-
- it('can restore and dump INT64_MIN', function()
- command('let dumped = ["\\xD3\\x80" . repeat("\\n", 7)]')
- command('let parsed = msgpackparse(dumped)')
- command('let dumped2 = msgpackdump(parsed)')
- eq(1, eval('type(parsed[0]) == type(0) ' ..
- '|| parsed[0]._TYPE is v:msgpack_types.integer'))
- if eval('type(parsed[0]) == type(0)') == 1 then
- command('call assert_equal(-0x7fffffffffffffff - 1, parsed[0])')
- eq({}, eval('v:errors'))
- else
- eq({_TYPE={}, _VAL={-1, 2, 0, 0}}, eval('parsed[0]'))
- end
- eq(1, eval('dumped ==# dumped2'))
- end)
-
- it('can restore and dump BIN string with zero byte', function()
- command('let dumped = ["\\xC4\\x01\\n"]')
- command('let parsed = msgpackparse(dumped)')
- command('let dumped2 = msgpackdump(parsed)')
- eq({'\000'}, eval('parsed'))
- eq(1, eval('dumped ==# dumped2'))
- end)
-
- it('can restore and dump STR string with zero byte', function()
- command('let dumped = ["\\xA1\\n"]')
- command('let parsed = msgpackparse(dumped)')
- command('let dumped2 = msgpackdump(parsed)')
- eq({{_TYPE={}, _VAL={'\n'}}}, eval('parsed'))
- eq(1, eval('parsed[0]._TYPE is v:msgpack_types.string'))
- eq(1, eval('dumped ==# dumped2'))
- end)
-
- it('can restore and dump BIN string with NL', function()
- command('let dumped = ["\\xC4\\x01", ""]')
- command('let parsed = msgpackparse(dumped)')
- command('let dumped2 = msgpackdump(parsed)')
- eq({"\n"}, eval('parsed'))
- eq(1, eval('dumped ==# dumped2'))
- end)
-
- it('dump and restore special mapping with floating-point value', function()
- command('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
- eq({0.125}, eval('msgpackparse(msgpackdump([todump]))'))
- end)
-end)
-
-local blobstr = function(list)
- local l = {}
- for i,v in ipairs(list) do
- l[i] = v:gsub('\n', '\000')
- end
- return table.concat(l, '\n')
-end
-
--- Test msgpackparse() with a readfile()-style list and a blob argument
-local parse_eq = function(expect, list_arg)
- local blob_expr = '0z' .. blobstr(list_arg):gsub('(.)', function(c)
- return ('%.2x'):format(c:byte())
- end)
- eq(expect, funcs.msgpackparse(list_arg))
- command('let g:parsed = msgpackparse(' .. blob_expr .. ')')
- eq(expect, eval('g:parsed'))
-end
-
-describe('msgpackparse() function', function()
- before_each(clear)
-
- it('restores nil as v:null', function()
- parse_eq(eval('[v:null]'), {'\192'})
- end)
-
- it('restores boolean false as v:false', function()
- parse_eq({false}, {'\194'})
- end)
-
- it('restores boolean true as v:true', function()
- parse_eq({true}, {'\195'})
- end)
-
- it('restores FIXSTR as special dict', function()
- parse_eq({{_TYPE={}, _VAL={'ab'}}}, {'\162ab'})
- eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string'))
- end)
-
- it('restores BIN 8 as string', function()
- parse_eq({'ab'}, {'\196\002ab'})
- end)
-
- it('restores FIXEXT1 as special dictionary', function()
- parse_eq({{_TYPE={}, _VAL={0x10, {"", ""}}}}, {'\212\016', ''})
- eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext'))
- end)
-
- it('restores MAP with BIN key as special dictionary', function()
- parse_eq({{_TYPE={}, _VAL={{'a', ''}}}}, {'\129\196\001a\196\n'})
- eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
- end)
-
- it('restores MAP with duplicate STR keys as special dictionary', function()
- command('let dumped = ["\\x82\\xA1a\\xC4\\n\\xA1a\\xC4\\n"]')
- -- FIXME Internal error bug, can't use parse_eq() here
- command('silent! let parsed = msgpackparse(dumped)')
- eq({{_TYPE={}, _VAL={ {{_TYPE={}, _VAL={'a'}}, ''},
- {{_TYPE={}, _VAL={'a'}}, ''}}} }, eval('parsed'))
- eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
- eq(1, eval('g:parsed[0]._VAL[0][0]._TYPE is v:msgpack_types.string'))
- eq(1, eval('g:parsed[0]._VAL[1][0]._TYPE is v:msgpack_types.string'))
- end)
-
- it('restores MAP with MAP key as special dictionary', function()
- parse_eq({{_TYPE={}, _VAL={{{}, ''}}}}, {'\129\128\196\n'})
- eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
- end)
-
- it('msgpackparse(systemlist(...)) does not segfault. #3135', function()
- local cmd = "sort(keys(msgpackparse(systemlist('"
- ..helpers.nvim_prog.." --api-info'))[0]))"
- eval(cmd)
- eval(cmd) -- do it again (try to force segfault)
- local api_info = eval(cmd) -- do it again
- eq({'error_types', 'functions', 'types',
- 'ui_events', 'ui_options', 'version'}, api_info)
- end)
-
- it('fails when called with no arguments', function()
- eq('Vim(call):E119: Not enough arguments for function: msgpackparse',
- exc_exec('call msgpackparse()'))
- end)
-
- it('fails when called with two arguments', function()
- eq('Vim(call):E118: Too many arguments for function: msgpackparse',
- exc_exec('call msgpackparse(["", ""], 1)'))
- end)
-
- it('fails to parse a string', function()
- eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
- exc_exec('call msgpackparse("abcdefghijklmnopqrstuvwxyz")'))
- end)
-
- it('fails to parse a number', function()
- eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
- exc_exec('call msgpackparse(127)'))
- end)
-
- it('fails to parse a dictionary', function()
- eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
- exc_exec('call msgpackparse({})'))
- end)
-
- it('fails to parse a funcref', function()
- eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
- exc_exec('call msgpackparse(function("tr"))'))
- end)
-
- it('fails to parse a partial', function()
- command('function T() dict\nendfunction')
- eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
- exc_exec('call msgpackparse(function("T", [1, 2], {}))'))
- end)
-
- it('fails to parse a float', function()
- eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
- exc_exec('call msgpackparse(0.0)'))
- end)
-
- it('fails on incomplete msgpack string', function()
- local expected = 'Vim(call):E475: Invalid argument: Incomplete msgpack string'
- eq(expected, exc_exec([[call msgpackparse(["\xc4"])]]))
- eq(expected, exc_exec([[call msgpackparse(["\xca", "\x02\x03"])]]))
- eq(expected, exc_exec('call msgpackparse(0zc4)'))
- eq(expected, exc_exec('call msgpackparse(0zca0a0203)'))
- end)
-
- it('fails when unable to parse msgpack string', function()
- local expected = 'Vim(call):E475: Invalid argument: Failed to parse msgpack string'
- eq(expected, exc_exec([[call msgpackparse(["\xc1"])]]))
- eq(expected, exc_exec('call msgpackparse(0zc1)'))
- end)
-end)
-
-describe('msgpackdump() function', function()
- before_each(clear)
-
- local dump_eq = function(exp_list, arg_expr)
- eq(exp_list, eval('msgpackdump(' .. arg_expr .. ')'))
- eq(blobstr(exp_list), eval('msgpackdump(' .. arg_expr .. ', "B")'))
- end
-
- it('dumps string as BIN 8', function()
- dump_eq({'\196\004Test'}, '["Test"]')
- end)
-
- it('dumps blob as BIN 8', function()
- dump_eq({'\196\005Bl\nb!'}, '[0z426c006221]')
- end)
-
- it('can 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": []}')
- command('call add(todump._VAL, [todumpv1, todumpv2])')
- dump_eq({'\129\128\128'}, '[todump]')
- end)
-
- it('can dump v:true', function()
- dump_eq({'\195'}, '[v:true]')
- end)
-
- it('can dump v:false', function()
- dump_eq({'\194'}, '[v:false]')
- end)
-
- it('can dump v:null', function()
- dump_eq({'\192'}, '[v:null]')
- end)
-
- it('can dump special bool mapping (true)', function()
- command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}')
- dump_eq({'\195'}, '[todump]')
- end)
-
- it('can dump special bool mapping (false)', function()
- command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}')
- dump_eq({'\194'}, '[todump]')
- end)
-
- it('can dump special nil mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}')
- dump_eq({'\192'}, '[todump]')
- end)
-
- it('can dump special ext mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
- dump_eq({'\212\005', ''}, '[todump]')
- end)
-
- it('can dump special array mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
- dump_eq({'\146\005\145\196\n'}, '[todump]')
- end)
-
- it('can dump special UINT64_MAX mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.integer}')
- command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
- dump_eq({'\207\255\255\255\255\255\255\255\255'}, '[todump]')
- end)
-
- it('can dump special INT64_MIN mapping', function()
- command('let todump = {"_TYPE": v:msgpack_types.integer}')
- command('let todump._VAL = [-1, 2, 0, 0]')
- dump_eq({'\211\128\n\n\n\n\n\n\n'}, '[todump]')
- end)
-
- it('fails to dump a function reference', function()
- command('let Todump = function("tr")')
- eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference',
- exc_exec('call msgpackdump([Todump])'))
- end)
-
- it('fails to dump a partial', function()
- command('function T() dict\nendfunction')
- command('let Todump = function("T", [1, 2], {})')
- eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference',
- exc_exec('call msgpackdump([Todump])'))
- end)
-
- it('fails to dump a function reference in a list', function()
- command('let todump = [function("tr")]')
- eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, index 0: attempt to dump function reference',
- exc_exec('call msgpackdump([todump])'))
- end)
-
- it('fails to dump a recursive list', function()
- command('let todump = [[[]]]')
- command('call add(todump[0][0], todump)')
- eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 0, index 0',
- exc_exec('call msgpackdump([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):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key \'d\', key \'d\', key \'d\'',
- exc_exec('call msgpackdump([todump])'))
- end)
-
- it('can dump dict with two same dicts inside', function()
- command('let inter = {}')
- command('let todump = {"a": inter, "b": inter}')
- dump_eq({"\130\161a\128\161b\128"}, '[todump]')
- end)
-
- it('can dump list with two same lists inside', function()
- command('let inter = []')
- command('let todump = [inter, inter]')
- dump_eq({"\146\144\144"}, '[todump]')
- end)
-
- 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):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0',
- exc_exec('call msgpackdump([todump])'))
- end)
-
- it('fails to dump a recursive (key) map in a special dict', function()
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
- command('call add(todump._VAL, [todump, 0])')
- eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0',
- exc_exec('call msgpackdump([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, [0, todump])')
- eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key 0 at index 0 from special map',
- exc_exec('call msgpackdump([todump])'))
- end)
-
- it('fails to dump a recursive (key) map in a special dict, _VAL reference', function()
- command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
- command('call add(todump._VAL[0][0], todump._VAL)')
- eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [[[[...@0], []]]] at index 0 from special map, index 0',
- exc_exec('call msgpackdump([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):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [] at index 0 from special map, index 0',
- exc_exec('call msgpackdump([todump])'))
- end)
-
- 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, [0, todump._VAL])')
- eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 1',
- exc_exec('call msgpackdump([todump])'))
- end)
-
- it('fails when called with no arguments', function()
- eq('Vim(call):E119: Not enough arguments for function: msgpackdump',
- exc_exec('call msgpackdump()'))
- end)
-
- it('fails when called with three arguments', function()
- eq('Vim(call):E118: Too many arguments for function: msgpackdump',
- exc_exec('call msgpackdump(["", ""], 1, 2)'))
- end)
-
- it('fails to dump a string', function()
- eq('Vim(call):E686: Argument of msgpackdump() must be a List',
- exc_exec('call msgpackdump("abcdefghijklmnopqrstuvwxyz")'))
- end)
-
- it('fails to dump a number', function()
- eq('Vim(call):E686: Argument of msgpackdump() must be a List',
- exc_exec('call msgpackdump(127)'))
- end)
-
- it('fails to dump a dictionary', function()
- eq('Vim(call):E686: Argument of msgpackdump() must be a List',
- exc_exec('call msgpackdump({})'))
- end)
-
- it('fails to dump a funcref', function()
- eq('Vim(call):E686: Argument of msgpackdump() must be a List',
- exc_exec('call msgpackdump(function("tr"))'))
- end)
-
- it('fails to dump a partial', function()
- command('function T() dict\nendfunction')
- eq('Vim(call):E686: Argument of msgpackdump() must be a List',
- exc_exec('call msgpackdump(function("T", [1, 2], {}))'))
- end)
-
- it('fails to dump a float', function()
- eq('Vim(call):E686: Argument of msgpackdump() must be a List',
- exc_exec('call msgpackdump(0.0)'))
- end)
-
- it('fails to dump special value', function()
- for _, val in ipairs({'v:true', 'v:false', 'v:null'}) do
- eq('Vim(call):E686: Argument of msgpackdump() must be a List',
- exc_exec('call msgpackdump(' .. val .. ')'))
- end
- end)
-
- it('can dump NULL string', function()
- dump_eq({'\196\n'}, '[$XXX_UNEXISTENT_VAR_XXX]')
- dump_eq({'\196\n'}, '[{"_TYPE": v:msgpack_types.binary, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
- dump_eq({'\160'}, '[{"_TYPE": v:msgpack_types.string, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
- end)
-
- it('can dump NULL blob', function()
- eq({'\196\n'}, eval('msgpackdump([v:_null_blob])'))
- end)
-
- it('can dump NULL list', function()
- eq({'\144'}, eval('msgpackdump([v:_null_list])'))
- end)
-
- it('can dump NULL dictionary', function()
- eq({'\128'}, eval('msgpackdump([v:_null_dict])'))
- end)
-end)
diff --git a/test/functional/eval/null_spec.lua b/test/functional/eval/null_spec.lua
deleted file mode 100644
index bc88e6c8b3..0000000000
--- a/test/functional/eval/null_spec.lua
+++ /dev/null
@@ -1,170 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local curbufmeths = helpers.curbufmeths
-local redir_exec = helpers.redir_exec
-local exc_exec = helpers.exc_exec
-local command = helpers.command
-local clear = helpers.clear
-local meths = helpers.meths
-local funcs = helpers.funcs
-local eq = helpers.eq
-
-describe('NULL', function()
- before_each(function()
- clear()
- command('let L = v:_null_list')
- command('let D = v:_null_dict')
- command('let S = v:_null_string')
- command('let V = $XXX_NONEXISTENT_VAR_XXX')
- end)
- local tmpfname = 'Xtest-functional-viml-null'
- after_each(function()
- os.remove(tmpfname)
- end)
- local null_test = function(name, cmd, err)
- it(name, function()
- eq(err, exc_exec(cmd))
- end)
- 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))
- if val == nil then
- eq(0, funcs.exists('g:_var'))
- else
- eq(val, meths.get_var('_var'))
- end
- if after ~= nil then
- after()
- end
- end)
- end
- describe('list', function()
- -- Incorrect behaviour
- -- FIXME Should error out with different message
- null_test('makes :unlet act as if it is not a list', ':unlet L[0]',
- 'Vim(unlet):E689: Can only index a List, Dictionary or Blob')
-
- -- Subjectable behaviour
-
- null_expr_test('is equal to empty list', 'L == []', 0, 1)
- null_expr_test('is equal to empty list (reverse order)', '[] == L', 0, 1)
-
- -- Correct behaviour
- 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(1, L)', 0, 0, function()
- eq({''}, curbufmeths.get_lines(0, -1, false))
- end)
- null_expr_test('does not crash setline()', 'setline(1, L)', 0, 0, function()
- 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 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)
- null_expr_test('does not crash line()', 'line(L)', 0, 0)
- null_expr_test('does not crash line() with window id', 'line(L, 1000)', 0, 0)
- null_expr_test('does not crash count()', 'count(L, 1)', 0, 0)
- null_expr_test('does not crash cursor()', 'cursor(L)', 'E474: Invalid argument', -1)
- null_expr_test('does not crash map()', 'map(L, "v:val")', 0, {})
- null_expr_test('does not crash filter()', 'filter(L, "1")', 0, {})
- null_expr_test('is empty', 'empty(L)', 0, 1)
- null_expr_test('does not crash get()', 'get(L, 1, 10)', 0, 10)
- null_expr_test('has zero length', 'len(L)', 0, 0)
- null_expr_test('is accepted as an empty list by max()', 'max(L)', 0, 0)
- null_expr_test('is accepted as an empty list by min()', 'min(L)', 0, 0)
- null_expr_test('is stringified correctly', 'string(L)', 0, '[]')
- null_expr_test('is JSON encoded correctly', 'json_encode(L)', 0, '[]')
- 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('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_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")',
- '', '\n', 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)
- null_test('is accepted by :cexpr', 'cexpr L', 0)
- null_test('is accepted by :lexpr', 'lexpr L', 0)
- null_expr_test('does not crash execute()', 'execute(L)', 0, '')
- 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'))
- 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('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)
- null_expr_test('makes filter() return v:_null_dict', 'filter(D, "1") is# D', 0, 1)
- end)
- describe('string', function()
- null_test('does not crash :echomsg', 'echomsg S', 0)
- null_test('does not crash :execute', 'execute S', 0)
- null_expr_test('does not crash execute()', 'execute(S)', 0, '')
- null_expr_test('makes executable() error out', 'executable(S)', 'E928: String required', 0)
- 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, '')
- null_expr_test('does not crash getfperm()', 'getfperm(S)', 0, '')
- null_expr_test('does not crash getfsize()', 'getfsize(S)', 0, -1)
- null_expr_test('does not crash getftime()', 'getftime(S)', 0, -1)
- null_expr_test('does not crash getftype()', 'getftype(S)', 0, '')
- 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 split()', 'split(S)', 0, {})
- null_test('can be used to set an option', 'let &grepprg = S', 0)
-
- null_expr_test('is equal to non-existent variable', 'S == V', 0, 1)
- end)
-end)
diff --git a/test/functional/eval/operators_spec.lua b/test/functional/eval/operators_spec.lua
deleted file mode 100644
index 4d07bc1b05..0000000000
--- a/test/functional/eval/operators_spec.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq = helpers.eq
-local eval = helpers.eval
-local clear = helpers.clear
-
-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)'))
- 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)'))
- 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)'))
- end)
-end)
diff --git a/test/functional/eval/printf_spec.lua b/test/functional/eval/printf_spec.lua
deleted file mode 100644
index 27e24c4118..0000000000
--- a/test/functional/eval/printf_spec.lua
+++ /dev/null
@@ -1,92 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local clear = helpers.clear
-local eq = helpers.eq
-local eval = helpers.eval
-local funcs = helpers.funcs
-local meths = helpers.meths
-local exc_exec = helpers.exc_exec
-
-describe('printf()', function()
- before_each(clear)
-
- it('works with zero and %b', function()
- eq('0', funcs.printf('%lb', 0))
- eq('0', funcs.printf('%llb', 0))
- eq('0', funcs.printf('%zb', 0))
- end)
- it('works with one and %b', function()
- eq('1', funcs.printf('%b', 1))
- eq('1', funcs.printf('%lb', 1))
- eq('1', funcs.printf('%llb', 1))
- eq('1', funcs.printf('%zb', 1))
- end)
- it('works with 0xff and %b', function()
- eq('11111111', funcs.printf('%b', 0xff))
- eq('11111111', funcs.printf('%lb', 0xff))
- eq('11111111', funcs.printf('%llb', 0xff))
- eq('11111111', funcs.printf('%zb', 0xff))
- end)
- it('accepts width modifier with %b', function()
- eq(' 1', funcs.printf('%3b', 1))
- end)
- it('accepts prefix modifier with %b', function()
- eq('0b1', funcs.printf('%#b', 1))
- end)
- it('writes capital B with %B', function()
- eq('0B1', funcs.printf('%#B', 1))
- end)
- it('accepts prefix, zero-fill and width modifiers with %b', function()
- eq('0b001', funcs.printf('%#05b', 1))
- end)
- it('accepts prefix and width modifiers with %b', function()
- eq(' 0b1', funcs.printf('%#5b', 1))
- end)
- it('does not write prefix for zero with prefix and width modifier used with %b', function()
- eq(' 0', funcs.printf('%#5b', 0))
- end)
- it('accepts precision modifier with %b', function()
- eq('00000', funcs.printf('%.5b', 0))
- end)
- it('accepts all modifiers with %b at once', 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))
- 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", [])'))
- end)
- it('errors out when %b modifier is used for a float', function()
- eq('Vim(call):E805: Using a Float as a Number', exc_exec('call printf("%b", 3.1415926535)'))
- end)
- it('works with %p correctly', function()
- local null_ret = nil
- local seen_rets = {}
- -- Collect all args in an array to avoid possible allocation of the same
- -- address after freeing unreferenced values.
- meths.set_var('__args', {})
- local function check_printf(expr, is_null)
- eq(0, exc_exec('call add(__args, ' .. expr .. ')'))
- eq(0, exc_exec('let __result = printf("%p", __args[-1])'))
- local id_ret = eval('id(__args[-1])')
- eq(id_ret, meths.get_var('__result'))
- if is_null then
- if null_ret then
- eq(null_ret, id_ret)
- else
- null_ret = id_ret
- end
- else
- eq(nil, seen_rets[id_ret])
- seen_rets[id_ret] = expr
- end
- meths.del_var('__result')
- end
- check_printf('v:_null_list', true)
- check_printf('v:_null_dict', true)
- check_printf('[]')
- check_printf('{}')
- check_printf('function("tr", ["a"])')
- end)
-end)
diff --git a/test/functional/eval/reltime_spec.lua b/test/functional/eval/reltime_spec.lua
deleted file mode 100644
index d87943e485..0000000000
--- a/test/functional/eval/reltime_spec.lua
+++ /dev/null
@@ -1,53 +0,0 @@
-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 reltime, reltimestr, reltimefloat = funcs.reltime, funcs.reltimestr, funcs.reltimefloat
-
-describe('reltimestr(), reltimefloat()', function()
- before_each(clear)
-
- it('acceptance', function()
- local now = reltime()
- command('sleep 10m')
- local later = reltime()
- local elapsed = reltime(now)
-
- neq(reltimestr(elapsed), '0.0')
- ok(reltimefloat(elapsed) > 0.0)
- -- original vim test for < 0.1, but easily fails on travis
- ok(nil ~= string.match(reltimestr(elapsed), "0%."))
- ok(reltimefloat(elapsed) < 1.0)
-
- local same = reltime(now, now)
- local samestr = string.gsub(reltimestr(same), ' ', '')
- samestr = string.sub(samestr, 1, 5)
-
- eq('0.000', samestr)
- eq(0.0, reltimefloat(same))
-
- local differs = reltime(now, later)
- neq(reltimestr(differs), '0.0')
- ok(reltimefloat(differs) > 0.0)
- -- original vim test for < 0.1, but easily fails on travis
- ok(nil ~= string.match(reltimestr(differs), "0%."))
- ok(reltimefloat(differs) < 1.0)
- end)
-
- it('(start - end) returns negative #10452', function()
- local older_time = reltime()
- command('sleep 1m')
- local newer_time = reltime()
-
- -- Start/end swapped: should be something like -0.002123.
- local tm_s = tonumber(reltimestr(reltime(newer_time, older_time)))
- local tm_f = reltimefloat(reltime(newer_time, older_time))
- ok(tm_s < 0 and tm_s > -10)
- ok(tm_f < 0 and tm_f > -10)
-
- -- Not swapped: should be something like 0.002123.
- tm_s = tonumber(reltimestr(reltime(older_time, newer_time)))
- tm_f = reltimefloat(reltime(older_time, newer_time))
- ok(tm_s > 0 and tm_s < 10)
- ok(tm_f > 0 and tm_f < 10)
- end)
-end)
diff --git a/test/functional/eval/server_spec.lua b/test/functional/eval/server_spec.lua
deleted file mode 100644
index 238d1aeb0f..0000000000
--- a/test/functional/eval/server_spec.lua
+++ /dev/null
@@ -1,156 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
-local command = helpers.command
-local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
-local iswin = helpers.iswin
-local ok = helpers.ok
-local matches = helpers.matches
-local pcall_err = helpers.pcall_err
-
-local function clear_serverlist()
- for _, server in pairs(funcs.serverlist()) do
- funcs.serverstop(server)
- end
-end
-
-describe('server', function()
- before_each(clear)
-
- it('serverstart() sets $NVIM_LISTEN_ADDRESS on first invocation', function()
- -- Unset $NVIM_LISTEN_ADDRESS
- command('let $NVIM_LISTEN_ADDRESS = ""')
-
- local s = eval('serverstart()')
- assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
- eq(s, eval('$NVIM_LISTEN_ADDRESS'))
- 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='.'}})
- eq('.', eval('$NVIM_LISTEN_ADDRESS'))
- local servers = funcs.serverlist()
- eq(1, #servers)
- ok(string.len(servers[1]) > 4) -- Like /tmp/nvim…/… or \\.\pipe\…
- end)
-
- it('sets v:servername at startup or if all servers were stopped',
- function()
- local initial_server = meths.get_vvar('servername')
- 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")
- neq(initial_server, s)
-
- -- serverstop() does _not_ modify v:servername...
- eq(1, funcs.serverstop(s))
- eq(initial_server, meths.get_vvar('servername'))
-
- -- ...unless we stop _all_ servers.
- eq(1, funcs.serverstop(funcs.serverlist()[1]))
- eq('', meths.get_vvar('servername'))
-
- -- v:servername will take the next available server.
- local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
- or 'Xtest-functional-server-socket')
- funcs.serverstart(servername)
- eq(servername, meths.get_vvar('servername'))
- end)
-
- it('serverstop() returns false for invalid input', function()
- eq(0, eval("serverstop('')"))
- eq(0, eval("serverstop('bogus-socket-name')"))
- end)
-
- it('parses endpoints correctly', function()
- clear_serverlist()
- eq({}, funcs.serverlist())
-
- 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
- if #s > 0 then
- assert(string.match(s, '127.0.0.1:%d+'))
- eq(s, funcs.serverlist()[1])
- clear_serverlist()
- end
-
- local expected = {}
- local v4 = '127.0.0.1:12345'
- local status, _ = pcall(funcs.serverstart, v4)
- if status then
- table.insert(expected, v4)
- pcall(funcs.serverstart, v4) -- exists already; ignore
- end
-
- local v6 = '::1:12345'
- status, _ = pcall(funcs.serverstart, v6)
- if status then
- table.insert(expected, v6)
- pcall(funcs.serverstart, v6) -- exists already; ignore
- end
- eq(expected, funcs.serverlist())
- clear_serverlist()
-
- eq('Vim:Failed to start server: invalid argument',
- pcall_err(funcs.serverstart, '127.0.0.1:65536')) -- invalid port
- eq({}, funcs.serverlist())
- end)
-
- it('serverlist() returns the list of servers', function()
- -- There should already be at least one server.
- local n = eval('len(serverlist())')
-
- -- Add some servers.
- local servs = (iswin()
- and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
- or { [[Xtest-pipe0934]], [[Xtest-pipe4324]] })
- for _, s in ipairs(servs) do
- eq(s, eval("serverstart('"..s.."')"))
- end
-
- local new_servs = eval('serverlist()')
-
- -- Exactly #servs servers should be added.
- eq(n + #servs, #new_servs)
- -- 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].."')"))
- end
- -- After serverstop() the servers should NOT be in the list.
- eq(n, eval('len(serverlist())'))
- end)
-end)
-
-describe('startup --listen', function()
- it('validates', function()
- clear()
-
- local cmd = { unpack(helpers.nvim_argv) }
- table.insert(cmd, '--listen')
- matches('nvim.*: Argument missing after: "%-%-listen"', funcs.system(cmd))
-
- cmd = { unpack(helpers.nvim_argv) }
- table.insert(cmd, '--listen2')
- matches('nvim.*: Garbage after option argument: "%-%-listen2"', funcs.system(cmd))
- end)
-
- it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
- local addr = (iswin() 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'))
- end)
-end)
diff --git a/test/functional/eval/setpos_spec.lua b/test/functional/eval/setpos_spec.lua
deleted file mode 100644
index 935f387bcc..0000000000
--- a/test/functional/eval/setpos_spec.lua
+++ /dev/null
@@ -1,64 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local setpos = helpers.funcs.setpos
-local getpos = helpers.funcs.getpos
-local insert = helpers.insert
-local clear = helpers.clear
-local command = helpers.command
-local eval = helpers.eval
-local eq = helpers.eq
-local exc_exec = helpers.exc_exec
-
-
-describe('setpos() function', function()
- before_each(function()
- clear()
- insert([[
- First line of text
- Second line of text
- Third line of text]])
- command('new')
- insert([[
- Line of text 1
- Line of text 2
- Line of text 3]])
- end)
- it('can set the current cursor position', function()
- setpos(".", {0, 2, 1, 0})
- eq(getpos("."), {0, 2, 1, 0})
- setpos(".", {2, 1, 1, 0})
- eq(getpos("."), {0, 1, 1, 0})
- 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(getpos("'d"), {0, 2, 1, 0})
- command('undo')
- command('call setpos("\'d", [2, 3, 1, 0])')
- eq(getpos("'d"), {0, 3, 1, 0})
- end)
- it('can set lowercase marks in other buffers', function()
- local retval = setpos("'d", {1, 2, 1, 0})
- eq(0, retval)
- setpos("'d", {1, 2, 1, 0})
- eq(getpos("'d"), {0, 0, 0, 0})
- command('wincmd w')
- eq(eval('bufnr("%")'), 1)
- eq(getpos("'d"), {0, 2, 1, 0})
- end)
- it("fails when setting a mark in a buffer that doesn't exist", function()
- local retval = setpos("'d", {3, 2, 1, 0})
- eq(-1, retval)
- eq(getpos("'d"), {0, 0, 0, 0})
- retval = setpos("'D", {3, 2, 1, 0})
- eq(-1, retval)
- eq(getpos("'D"), {0, 0, 0, 0})
- end)
- it('can set uppercase marks', function()
- setpos("'D", {2, 2, 3, 0})
- eq(getpos("'D"), {2, 2, 3, 0})
- -- Can set a mark in another buffer
- setpos("'D", {1, 2, 2, 0})
- eq(getpos("'D"), {1, 2, 2, 0})
- end)
-end)
diff --git a/test/functional/eval/sort_spec.lua b/test/functional/eval/sort_spec.lua
deleted file mode 100644
index e1cc2c2924..0000000000
--- a/test/functional/eval/sort_spec.lua
+++ /dev/null
@@ -1,57 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local NIL = helpers.NIL
-local eval = helpers.eval
-local clear = helpers.clear
-local meths = helpers.meths
-local funcs = helpers.funcs
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local redir_exec = helpers.redir_exec
-
-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")'))
- 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})
- command('call insert(g:list, function("tr"))')
- 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,
- }, errors)
- 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()
- command([[
- function Cmp(a, b)
- if type(a:a) == type([]) || type(a:b) == type([])
- return []
- endif
- return (a:a > a:b) - (a:a < a:b)
- endfunction
- ]])
- eq('\nE745: Using a List as a Number\nE702: Sort compare function failed',
- redir_exec('let sl = sort([1, 0, [], 3, 2], "Cmp")'))
- eq({1, 0, {}, 3, 2}, meths.get_var('sl'))
- end)
-end)
diff --git a/test/functional/eval/special_vars_spec.lua b/test/functional/eval/special_vars_spec.lua
deleted file mode 100644
index 97a12d490d..0000000000
--- a/test/functional/eval/special_vars_spec.lua
+++ /dev/null
@@ -1,190 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local exc_exec = helpers.exc_exec
-local command = helpers.command
-local funcs = helpers.funcs
-local clear = helpers.clear
-local eval = helpers.eval
-local eq = helpers.eq
-local meths = helpers.meths
-local NIL = helpers.NIL
-
-describe('Special values', function()
- before_each(clear)
-
- it('do not cause error when freed', function()
- command([[
- function Test()
- try
- return v:true
- finally
- return 'something else'
- endtry
- endfunction
- ]])
- eq(0, exc_exec('call Test()'))
- end)
-
- it('work with empty()', function()
- eq(0, funcs.empty(true))
- eq(1, funcs.empty(false))
- eq(1, funcs.empty(NIL))
- end)
-
- it('can be stringified and eval’ed back', function()
- eq(true, funcs.eval(funcs.string(true)))
- eq(false, funcs.eval(funcs.string(false)))
- eq(NIL, funcs.eval(funcs.string(NIL)))
- end)
-
- it('work with is/isnot properly', function()
- eq(1, eval('v:null is v:null'))
- eq(0, eval('v:null is v:true'))
- eq(0, eval('v:null is v:false'))
- eq(1, eval('v:true is v:true'))
- eq(0, eval('v:true is v:false'))
- eq(1, eval('v:false is v:false'))
-
- eq(0, eval('v:null is 0'))
- eq(0, eval('v:true is 0'))
- eq(0, eval('v:false is 0'))
-
- eq(0, eval('v:null is 1'))
- eq(0, eval('v:true is 1'))
- eq(0, eval('v:false is 1'))
-
- eq(0, eval('v:null is ""'))
- eq(0, eval('v:true is ""'))
- eq(0, eval('v:false is ""'))
-
- eq(0, eval('v:null is "null"'))
- eq(0, eval('v:true is "true"'))
- eq(0, eval('v:false is "false"'))
-
- eq(0, eval('v:null is []'))
- eq(0, eval('v:true is []'))
- eq(0, eval('v:false is []'))
-
- eq(0, eval('v:null isnot v:null'))
- eq(1, eval('v:null isnot v:true'))
- eq(1, eval('v:null isnot v:false'))
- eq(0, eval('v:true isnot v:true'))
- eq(1, eval('v:true isnot v:false'))
- eq(0, eval('v:false isnot v:false'))
-
- eq(1, eval('v:null isnot 0'))
- eq(1, eval('v:true isnot 0'))
- eq(1, eval('v:false isnot 0'))
-
- eq(1, eval('v:null isnot 1'))
- eq(1, eval('v:true isnot 1'))
- eq(1, eval('v:false isnot 1'))
-
- eq(1, eval('v:null isnot ""'))
- eq(1, eval('v:true isnot ""'))
- eq(1, eval('v:false isnot ""'))
-
- eq(1, eval('v:null isnot "null"'))
- eq(1, eval('v:true isnot "true"'))
- eq(1, eval('v:false isnot "false"'))
-
- eq(1, eval('v:null isnot []'))
- eq(1, eval('v:true isnot []'))
- eq(1, eval('v:false isnot []'))
- end)
-
- it('work with +/-/* properly', function()
- eq(1, eval('0 + v:true'))
- eq(0, eval('0 + v:null'))
- 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(1, eval('1 * v:true'))
- eq(0, eval('1 * v:null'))
- eq(0, eval('1 * v:false'))
- end)
-
- it('does not work with +=/-=/.=', function()
- meths.set_var('true', true)
- meths.set_var('false', false)
- command('let null = v:null')
-
- eq('Vim(let):E734: Wrong variable type for +=', exc_exec('let true += 1'))
- eq('Vim(let):E734: Wrong variable type for +=', exc_exec('let false += 1'))
- eq('Vim(let):E734: Wrong variable type for +=', exc_exec('let null += 1'))
-
- eq('Vim(let):E734: Wrong variable type for -=', exc_exec('let true -= 1'))
- eq('Vim(let):E734: Wrong variable type for -=', exc_exec('let false -= 1'))
- eq('Vim(let):E734: Wrong variable type for -=', exc_exec('let null -= 1'))
-
- eq('Vim(let):E734: Wrong variable type for .=', exc_exec('let true .= 1'))
- eq('Vim(let):E734: Wrong variable type for .=', exc_exec('let false .= 1'))
- eq('Vim(let):E734: Wrong variable type for .=', exc_exec('let null .= 1'))
- end)
-
- it('work with . (concat) properly', function()
- eq("true", eval('"" . v:true'))
- eq("null", eval('"" . v:null'))
- eq("false", eval('"" . v:false'))
- end)
-
- it('work with type()', function()
- eq(6, funcs.type(true))
- eq(6, funcs.type(false))
- eq(7, funcs.type(NIL))
- end)
-
- it('work with copy() and deepcopy()', function()
- eq(true, funcs.deepcopy(true))
- eq(false, funcs.deepcopy(false))
- eq(NIL, funcs.deepcopy(NIL))
-
- eq(true, funcs.copy(true))
- eq(false, funcs.copy(false))
- eq(NIL, funcs.copy(NIL))
- end)
-
- it('fails in index', function()
- eq('Vim(echo):E909: Cannot index a special variable', exc_exec('echo v:true[0]'))
- eq('Vim(echo):E909: Cannot index a special variable', exc_exec('echo v:false[0]'))
- eq('Vim(echo):E909: Cannot index a special variable', exc_exec('echo v:null[0]'))
- end)
-
- it('is accepted by assert_true and assert_false', function()
- funcs.assert_false(false)
- funcs.assert_false(true)
- funcs.assert_false(NIL)
-
- funcs.assert_true(false)
- funcs.assert_true(true)
- funcs.assert_true(NIL)
-
- eq({
- 'Expected False but got v:true',
- 'Expected False but got v:null',
- 'Expected True but got v:false',
- 'Expected True but got v:null',
- }, meths.get_vvar('errors'))
- end)
-
- describe('compat', function()
- it('v:count is distinct from count', function()
- command('let count = []') -- v:count is readonly
- eq(1, eval('count is# g:["count"]'))
- end)
- it('v:errmsg is distinct from errmsg', function()
- command('let errmsg = 1')
- eq(1, eval('errmsg is# g:["errmsg"]'))
- end)
- it('v:shell_error is distinct from shell_error', function()
- command('let shell_error = []') -- v:shell_error is readonly
- eq(1, eval('shell_error is# g:["shell_error"]'))
- end)
- it('v:this_session is distinct from this_session', function()
- command('let this_session = []')
- eq(1, eval('this_session is# g:["this_session"]'))
- end)
- end)
-end)
diff --git a/test/functional/eval/string_spec.lua b/test/functional/eval/string_spec.lua
deleted file mode 100644
index adc1af9b8e..0000000000
--- a/test/functional/eval/string_spec.lua
+++ /dev/null
@@ -1,277 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear = helpers.clear
-local eq = helpers.eq
-local command = helpers.command
-local meths = helpers.meths
-local eval = helpers.eval
-local exc_exec = helpers.exc_exec
-local redir_exec = helpers.redir_exec
-local funcs = helpers.funcs
-local NIL = helpers.NIL
-local source = helpers.source
-local dedent = helpers.dedent
-
-describe('string() function', function()
- before_each(clear)
-
- describe('used to represent floating-point values', function()
- it('dumps NaN values', function()
- 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\'))'))
- end)
-
- it('dumps regular values', function()
- eq('1.5', funcs.string(1.5))
- eq('1.56e-20', funcs.string(1.56000e-020))
- eq('0.0', eval('string(0.0)'))
- end)
-
- it('dumps special v: values', function()
- eq('v:true', eval('string(v:true)'))
- eq('v:false', eval('string(v:false)'))
- eq('v:null', eval('string(v:null)'))
- eq('v:true', funcs.string(true))
- eq('v:false', funcs.string(false))
- eq('v:null', funcs.string(NIL))
- end)
-
- 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()
- eq('1234567.891235', funcs.string(1234567.89123456789123456789))
- eq('1.234568e7', funcs.string(12345678.9123456789123456789))
- end)
-
- it('dumps negative values', function()
- eq('-1.5', funcs.string(-1.5))
- eq('-1.56e-20', funcs.string(-1.56000e-020))
- eq('-1.234568e-20', funcs.string(-1.23456789123456789123456789e-020))
- eq('-1.234568', funcs.string(-1.23456789123456789123456789))
- eq('-1234567.891235', funcs.string(-1234567.89123456789123456789))
- eq('-1.234568e7', funcs.string(-12345678.9123456789123456789))
- end)
- end)
-
- describe('used to represent numbers', function()
- it('dumps regular values', function()
- eq('0', funcs.string(0))
- eq('-1', funcs.string(-1))
- eq('1', funcs.string(1))
- end)
-
- it('dumps large values', function()
- 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'))
- end)
-
- it('dumps empty strings', function()
- 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'))
- end)
-
- it('dumps NULL strings', function()
- eq('\'\'', eval('string($XXX_UNEXISTENT_VAR_XXX)'))
- end)
-
- it('dumps NULL lists', function()
- eq('[]', eval('string(v:_null_list)'))
- end)
-
- it('dumps NULL dictionaries', function()
- eq('{}', eval('string(v:_null_dict)'))
- end)
- end)
-
- describe('used to represent funcrefs', function()
- before_each(function()
- source([[
- function Test1()
- endfunction
-
- function s:Test2() dict
- endfunction
-
- function g:Test3() dict
- endfunction
-
- let g:Test2_f = function('s:Test2')
- ]])
- end)
-
- it('dumps references to built-in functions', 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"))'))
- end)
-
- it('dumps references to script functions', function()
- eq('function(\'<SNR>1_Test2\')', eval('string(Test2_f)'))
- end)
-
- it('dumps partials with self referencing a partial', function()
- source([[
- function TestDict() dict
- endfunction
- let d = {}
- let TestDictRef = function('TestDict', d)
- let d.tdr = TestDictRef
- ]])
- eq("\nE724: unable to correctly dump variable with self-referencing container\nfunction('TestDict', {'tdr': function('TestDict', {E724@1})})",
- redir_exec('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)'))
- 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]))'))
- end)
-
- it('does not crash or halt when dumping partials with reference cycles in self',
- function()
- meths.set_var('d', {v=true})
- eq(dedent([[
-
- E724: unable to correctly dump variable with self-referencing container
- {'p': function('<SNR>1_Test2', {E724@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]]),
- redir_exec('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()
- 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)])'))
- -- 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)])'))
- end)
-
- 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(dedent([=[
-
- E724: unable to correctly dump variable with self-referencing container
- function('Test1', [[{E724@2}, function('Test1', [{E724@2}])], function('Test1', [[{E724@4}, function('Test1', [{E724@4}])]])])]=]),
- redir_exec('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(dedent([=[
-
- E724: unable to correctly dump variable with self-referencing container
- {'p': function('<SNR>1_Test2', [[{E724@3}, function('Test1', [{E724@3}]), function('Test1', {E724@0})], function('Test1', [[{E724@5}, function('Test1', [{E724@5}]), function('Test1', {E724@0})]]), function('Test1', {E724@0})], {E724@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]=]),
- redir_exec('echo string(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))'))
- end)
- end)
-
- describe('used to represent lists', function()
- it('dumps empty list', function()
- eq('[]', funcs.string({}))
- end)
-
- it('dumps nested lists', function()
- eq('[[[[[]]]]]', funcs.string({{{{{}}}}}))
- end)
-
- it('dumps nested non-empty lists', function()
- 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)'))
- end)
-
- it('dumps recursive lists despite the error', function()
- meths.set_var('l', {})
- eval('add(l, l)')
- eq('\nE724: unable to correctly dump variable with self-referencing container\n[{E724@0}]',
- redir_exec('echo string(l)'))
- eq('\nE724: unable to correctly dump variable with self-referencing container\n[[{E724@1}]]',
- redir_exec('echo string([l])'))
- end)
- end)
-
- describe('used to represent dictionaries', function()
- it('dumps empty dictionary', function()
- eq('{}', eval('string({})'))
- end)
-
- 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)])'))
- end)
-
- it('dumps non-empty dictionary', function()
- eq('{\'t\'\'est\': 1}', funcs.string({['t\'est']=1}))
- end)
-
- it('errors when dumping recursive dictionaries', function()
- 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)'))
- end)
-
- it('dumps recursive dictionaries despite the error', function()
- meths.set_var('d', {d=1})
- eval('extend(d, {"d": d})')
- eq('\nE724: unable to correctly dump variable with self-referencing container\n{\'d\': {E724@0}}',
- redir_exec('echo string(d)'))
- eq('\nE724: unable to correctly dump variable with self-referencing container\n{\'out\': {\'d\': {E724@1}}}',
- redir_exec('echo string({"out": d})'))
- end)
- end)
-end)
diff --git a/test/functional/eval/system_spec.lua b/test/functional/eval/system_spec.lua
deleted file mode 100644
index 24a1f05390..0000000000
--- a/test/functional/eval/system_spec.lua
+++ /dev/null
@@ -1,589 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local assert_alive = helpers.assert_alive
-local nvim_dir = helpers.nvim_dir
-local eq, call, clear, eval, feed_command, feed, nvim =
- helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.feed_command,
- helpers.feed, helpers.nvim
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local iswin = helpers.iswin
-local os_kill = helpers.os_kill
-local pcall_err = helpers.pcall_err
-
-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
- end
-end
-
-local function delete_file(name)
- return function()
- eval("delete('"..name.."')")
- end
-end
-
-describe('system()', function()
- before_each(clear)
-
- describe('command passed as a List', function()
- local function printargs_path()
- return nvim_dir..'/printargs-test' .. (iswin() and '.exe' or '')
- end
-
- 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(-1, eval('v:shell_error'))
- end)
-
- it('parameter validation does NOT modify v:shell_error', function()
- -- 1. Call system() with invalid parameters.
- -- 2. Assert that v:shell_error was NOT set.
- feed_command('call system({})')
- eq('E475: Invalid argument: expected String or List', eval('v:errmsg'))
- eq(0, eval('v:shell_error'))
- feed_command('call system([])')
- eq('E474: Invalid argument', eval('v:errmsg'))
- 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' }))
- local old_val = eval('v:shell_error')
- eq(-1, old_val)
-
- -- 1. Call system() with invalid parameters.
- -- 2. Assert that v:shell_error was NOT modified.
- feed_command('call system({})')
- eq(old_val, eval('v:shell_error'))
- feed_command('call system([])')
- eq(old_val, eval('v:shell_error'))
- end)
-
- it('quotes arguments correctly #5280', function()
- local out = call('system',
- { printargs_path(), [[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)
-
- out = call('system', { printargs_path(), [['1]], [[2 "3]] })
- eq(0, eval('v:shell_error'))
- eq([[arg1='1;arg2=2 "3;]], out)
-
- out = call('system', { printargs_path(), "A\nB" })
- eq(0, eval('v:shell_error'))
- eq("arg1=A\nB;", out)
- end)
-
- it('calls executable in $PATH', function()
- if 0 == eval("executable('python')") then pending("missing `python`") end
- eq("foo\n", eval([[system(['python', '-c', 'print("foo")'])]]))
- eq(0, eval('v:shell_error'))
- end)
-
- it('does NOT run in shell', function()
- if iswin() then
- eq("%PATH%\n", eval("system(['powershell', '-NoProfile', '-NoLogo', '-ExecutionPolicy', 'RemoteSigned', '-Command', 'Write-Output', '%PATH%'])"))
- else
- eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])"))
- end
- end)
- end)
-
- it('sets v:shell_error', function()
- if iswin() then
- eval([[system("cmd.exe /c exit")]])
- eq(0, eval('v:shell_error'))
- eval([[system("cmd.exe /c exit 1")]])
- eq(1, eval('v:shell_error'))
- eval([[system("cmd.exe /c exit 5")]])
- eq(5, eval('v:shell_error'))
- eval([[system('this-should-not-exist')]])
- eq(1, eval('v:shell_error'))
- else
- eval([[system("sh -c 'exit'")]])
- eq(0, eval('v:shell_error'))
- eval([[system("sh -c 'exit 1'")]])
- eq(1, eval('v:shell_error'))
- eval([[system("sh -c 'exit 5'")]])
- eq(5, eval('v:shell_error'))
- eval([[system('this-should-not-exist')]])
- eq(127, eval('v:shell_error'))
- end
- end)
-
- describe('executes shell function', function()
- local screen
-
- before_each(function()
- screen = Screen.new()
- screen:attach()
- end)
-
- if iswin() then
- local function test_more()
- eq('root = true', eval([[get(split(system('"more" ".editorconfig"'), "\n"), 0, '')]]))
- end
- local function test_shell_unquoting()
- 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\^"''')]]))
- end
-
- it('with shell=cmd.exe', function()
- command('set shell=cmd.exe')
- eq('""\n', eval([[system('echo ""')]]))
- eq('"a b"\n', eval([[system('echo "a b"')]]))
- eq('a \nb\n', eval([[system('echo a & echo b')]]))
- eq('a \n', eval([[system('echo a 2>&1')]]))
- test_more()
- eval([[system('cd "C:\Program Files"')]])
- eq(0, eval('v:shell_error'))
- test_shell_unquoting()
- end)
-
- it('with shell=cmd', function()
- command('set shell=cmd')
- eq('"a b"\n', eval([[system('echo "a b"')]]))
- test_more()
- test_shell_unquoting()
- end)
-
- it('with shell=$COMSPEC', function()
- local comspecshell = eval("fnamemodify($COMSPEC, ':t')")
- if comspecshell == 'cmd.exe' then
- command('set shell=$COMSPEC')
- eq('"a b"\n', eval([[system('echo "a b"')]]))
- test_more()
- test_shell_unquoting()
- else
- pending('$COMSPEC is not cmd.exe: ' .. comspecshell)
- end
- end)
-
- it('works with powershell', function()
- helpers.set_shell_powershell()
- eq('a\nb\n', eval([[system('Write-Output a b')]]))
- eq('C:\\\n', eval([[system('cd c:\; (Get-Location).Path')]]))
- eq('a b\n', eval([[system('Write-Output "a b"')]]))
- end)
- end
-
- it('works with powershell w/ UTF-8 text (#13713)', function()
- if not helpers.has_powershell() then
- pending("not tested; powershell was not found", function() end)
- return
- end
- -- Should work with recommended config used in helper
- helpers.set_shell_powershell()
- eq('ああ\n', eval([[system('Write-Output "ああ"')]]))
- -- Sanity test w/ default encoding
- -- * on Windows, expected to default to Western European enc
- -- * on Linux, expected to default to UTF8
- command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
- eq(iswin() and '??\n' or 'ああ\n', eval([[system('Write-Output "ああ"')]]))
- end)
-
- it('`echo` and waits for its return', function()
- feed(':call system("echo")<cr>')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- :call system("echo") |
- ]])
- end)
-
- it('prints verbose information', function()
- nvim('set_option', 'shell', 'fake_shell')
- nvim('set_option', 'shellcmdflag', 'cmdflag')
-
- screen:try_resize(72, 14)
- feed(':4verbose echo system("echo hi")<cr>')
- if iswin() then
- screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' '"echo hi"'"]]}
- else
- screen:expect{any=[[Executing command: "'fake_shell' 'cmdflag' 'echo hi'"]]}
- end
- feed('<cr>')
- end)
-
- it('self and total time recorded separately', function()
- local tempfile = helpers.tmpname()
-
- feed(':function! AlmostNoSelfTime()<cr>')
- feed('echo system("echo hi")<cr>')
- feed('endfunction<cr>')
-
- feed(':profile start ' .. tempfile .. '<cr>')
- feed(':profile func AlmostNoSelfTime<cr>')
- feed(':call AlmostNoSelfTime()<cr>')
- feed(':profile dump<cr>')
-
- feed(':edit ' .. tempfile .. '<cr>')
-
- local command_total_time = tonumber(helpers.funcs.split(helpers.funcs.getline(7))[2])
- local command_self_time = tonumber(helpers.funcs.split(helpers.funcs.getline(7))[3])
-
- helpers.neq(nil, command_total_time)
- helpers.neq(nil, command_self_time)
- end)
-
- it('`yes` interrupted with CTRL-C', function()
- feed(':call system("' .. (iswin()
- and 'for /L %I in (1,0,2) do @echo y'
- or 'yes') .. '")<cr>')
- screen:expect([[
- |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
-]] .. (iswin()
- and [[
- :call system("for /L %I in (1,0,2) do @echo y") |]]
- or [[
- :call system("yes") |]]))
- feed('<c-c>')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- Type :qa and press <Enter> to exit Nvim |
- ]])
- end)
- end)
-
- describe('passing no input', function()
- it('returns the program output', function()
- if iswin() then
- eq("echoed\n", eval('system("echo echoed")'))
- else
- eq("echoed", eval('system("echo -n 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" : "echo -n echoed &")')
- local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
- if v_errnum then
- eq("E5677:", v_errnum)
- end
- assert_alive()
- end)
- end)
-
- describe('passing input', function()
- it('returns the program output', function()
- 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*:")
- if v_errnum then
- eq("E5677:", v_errnum)
- end
- assert_alive()
- end)
- it('works with an empty string', function()
- eq("test\n", eval('system("echo test", "")'))
- assert_alive()
- end)
- end)
-
- describe('passing a lot of input', function()
- it('returns the program output', function()
- local input = {}
- -- write more than 1mb of data, which should be enough to overcome
- -- the os buffer limit and force multiple event loop iterations to write
- -- everything
- for _ = 1, 0xffff do
- input[#input + 1] = '01234567890ABCDEFabcdef'
- end
- input = table.concat(input, '\n')
- nvim('set_var', 'input', input)
- eq(input, eval('system("cat -", g:input)'))
- end)
- end)
-
- describe('Number input', 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)'))
- end)
- end)
-
- describe('with output containing NULs', function()
- local fname = 'Xtest'
-
- before_each(create_file_with_nuls(fname))
- after_each(delete_file(fname))
-
- it('replaces NULs by SOH characters', function()
- 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'])"))
- end)
-
- -- Notice that NULs are converted to SOH when the data is read back. This
- -- is inconsistent and is a good reason for the existence of the
- -- `systemlist()` function, where input and output map to the same
- -- 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'])]]))
- 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"])]]))
- end)
- end)
- end)
-
- 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')", nvim_dir..'/streams-test'))
- assert(out:sub(0, 5) == 'pid: ', out)
- os_kill(out:match("%d+"))
- end)
-end)
-
-describe('systemlist()', function()
- -- Similar to `system()`, but returns List instead of String.
- before_each(clear)
-
- it('sets v:shell_error', function()
- if iswin() then
- eval([[systemlist("cmd.exe /c exit")]])
- eq(0, eval('v:shell_error'))
- eval([[systemlist("cmd.exe /c exit 1")]])
- eq(1, eval('v:shell_error'))
- eval([[systemlist("cmd.exe /c exit 5")]])
- eq(5, eval('v:shell_error'))
- eval([[systemlist('this-should-not-exist')]])
- eq(1, eval('v:shell_error'))
- else
- eval([[systemlist("sh -c 'exit'")]])
- eq(0, eval('v:shell_error'))
- eval([[systemlist("sh -c 'exit 1'")]])
- eq(1, eval('v:shell_error'))
- eval([[systemlist("sh -c 'exit 5'")]])
- eq(5, eval('v:shell_error'))
- eval([[systemlist('this-should-not-exist')]])
- eq(127, eval('v:shell_error'))
- end
- end)
-
- describe('executes shell function', function()
- local screen
-
- before_each(function()
- screen = Screen.new()
- screen:attach()
- end)
-
- after_each(function()
- screen:detach()
- end)
-
- it('`echo` and waits for its return', function()
- feed(':call systemlist("echo")<cr>')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- :call systemlist("echo") |
- ]])
- end)
-
- it('`yes` interrupted with CTRL-C', function()
- feed(':call systemlist("yes | xargs")<cr>')
- screen:expect([[
- |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- :call systemlist("yes | xargs") |
- ]])
- feed('<c-c>')
- screen:expect([[
- ^ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- ~ |
- Type :qa and press <Enter> to exit Nvim |
- ]])
- end)
- end)
-
- 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")]]))
- end)
- end)
-
- describe('passing a lot of input', function()
- it('returns the program output', function()
- local input = {}
- for _ = 1, 0xffff do
- input[#input + 1] = '01234567890ABCDEFabcdef'
- end
- nvim('set_var', 'input', input)
- eq(input, eval('systemlist("cat -", g:input)'))
- end)
- end)
-
- describe('with output containing NULs', function()
- local fname = 'Xtest'
-
- before_each(function()
- command('set ff=unix')
- create_file_with_nuls(fname)()
- end)
- after_each(delete_file(fname))
-
- it('replaces NULs by newline characters', function()
- 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'])"))
- end)
-
- -- Unlike `system()` which uses SOH to represent NULs, with `systemlist()`
- -- input and ouput 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'])]]))
- 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"])]]))
- 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'])"))
- end)
-
- it('in the beginning', function()
- 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)"))
- 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)"))
- 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')", nvim_dir..'/streams-test'))
- assert(out[1]:sub(0, 5) == 'pid: ', out)
- os_kill(out[1]:match("%d+"))
- end)
-
- it('works with powershell w/ UTF-8 text (#13713)', function()
- if not helpers.has_powershell() then
- pending("not tested; powershell was not found", function() end)
- return
- end
- -- Should work with recommended config used in helper
- helpers.set_shell_powershell()
- eq({iswin() and 'あ\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
- -- Sanity test w/ default encoding
- -- * on Windows, expected to default to Western European enc
- -- * on Linux, expected to default to UTF8
- command([[let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command ']])
- eq({iswin() and '?\r' or 'あ'}, eval([[systemlist('Write-Output あ')]]))
- end)
-
-end)
diff --git a/test/functional/eval/timer_spec.lua b/test/functional/eval/timer_spec.lua
deleted file mode 100644
index 9ee0735e40..0000000000
--- a/test/functional/eval/timer_spec.lua
+++ /dev/null
@@ -1,265 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local Screen = require('test.functional.ui.screen')
-local feed, eq, eval, ok = helpers.feed, helpers.eq, helpers.eval, helpers.ok
-local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run
-local clear, command, funcs = helpers.clear, helpers.command, helpers.funcs
-local curbufmeths = helpers.curbufmeths
-local load_adjust = helpers.load_adjust
-local retry = helpers.retry
-
-describe('timers', function()
- before_each(function()
- clear()
- source([[
- let g:val = 0
- func MyHandler(timer)
- let g:val += 1
- endfunc
- ]])
- end)
-
- 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"))
- 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"))
- 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"))
- end)
- end)
-
- it('are triggered during sleep', function()
- source([[
- let g:val = -1
- func! MyHandler(timer)
- if g:val >= 0
- let g:val += 1
- if g:val == 2
- call timer_stop(a:timer)
- endif
- endif
- 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")
- run(nil, nil, nil, load_adjust(20))
- retry(nil, nil, function()
- eq(2, eval("g:val"))
- end)
- end)
-
- it('works with zero timeout', 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"))
- end)
- end)
-
- it('can be started during sleep', function()
- 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)
- 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")
- -- 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))
- 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()")
- retry(nil, nil, function()
- local val = eval("g:val")
- ok(val >= 2, "expected >= 2, got: "..tostring(val))
- eq(0, eval("getchar(1)"))
- end)
- 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},
- })
-
- curbufmeths.set_lines(0, -1, true, {"ITEM 1", "ITEM 2"})
- source([[
- let g:cont = 0
- func! AddItem(timer)
- if !g:cont
- return
- endif
- call timer_stop(a:timer)
-
- call nvim_buf_set_lines(0, 2, 2, v:true, ['ITEM 3'])
-
- " Meant to test for what Vim tests in Test_peek_and_get_char.
- call getchar(1)
-
- redraw
- endfunc
- ]])
- nvim_async("command", "let g:c2 = getchar()")
- nvim_async("command", "call timer_start("..load_adjust(100)..", 'AddItem', {'repeat': -1})")
-
- screen:expect([[
- ITEM 1 |
- ITEM 2 |
- {1:~ }|
- {1:~ }|
- {1:~ }|
- ^ |
- ]])
- nvim_async("command", "let g:cont = 1")
-
- screen:expect([[
- ITEM 1 |
- ITEM 2 |
- ITEM 3 |
- {1:~ }|
- {1:~ }|
- ^ |
- ]])
-
- feed("3")
- eq(51, eval("g:c2"))
- screen:expect([[
- ^ITEM 1 |
- ITEM 2 |
- ITEM 3 |
- {1:~ }|
- {1:~ }|
- |
- ]])
- end)
-
- it('can be stopped', function()
- local t_init_val = eval("[timer_start(5, 'MyHandler', {'repeat': -1}), g:val]")
- 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")
- run(nil, load_adjust(300), nil, load_adjust(30))
- local count2 = eval("g:val")
- -- when count is eval:ed after timer_stop this should be non-racy
- eq(count, count2)
- end)
-
- it('can be stopped from the handler', function()
- source([[
- func! MyHandler(timer)
- let g:val += 1
- if g:val == 3
- call timer_stop(a:timer)
- " check double stop is ignored
- call timer_stop(a:timer)
- endif
- endfunc
- ]])
- eq(0, eval("g:val"))
- command("call timer_start(10, 'MyHandler', {'repeat': -1})")
- retry(nil, nil, function()
- eq(3, eval("g:val"))
- end)
- end)
-
- it('can have two timers', function()
- source([[
- let g:val2 = 0
- func! MyHandler2(timer)
- let g:val2 += 1
- endfunc
- ]])
- 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"))
- end)
- end)
-
- it('do not crash when processing events in the handler', function()
- source([[
- let g:val = 0
- func! MyHandler(timer)
- call timer_stop(a:timer)
- sleep 10m
- let g:val += 1
- endfunc
- ]])
- 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"))
- 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}} )
- source([[
- let g:val = 0
- func! MyHandler(timer)
- while !g:val
- return
- endwhile
- call timer_stop(a:timer)
-
- echo "evil"
- redraw
- let g:val = 2
- endfunc
- ]])
- command("call timer_start(100, 'MyHandler', {'repeat': -1})")
- feed(":good")
- screen:expect([[
- |
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
- :good^ |
- ]])
- command('let g:val = 1')
-
- screen:expect{grid=[[
- |
- {0:~ }|
- {0:~ }|
- {0:~ }|
- {0:~ }|
- :good^ |
- ]], intermediate=true, timeout=load_adjust(200)}
-
- eq(2, eval('g:val'))
- end)
-end)
diff --git a/test/functional/eval/uniq_spec.lua b/test/functional/eval/uniq_spec.lua
deleted file mode 100644
index 5cdba0a0f6..0000000000
--- a/test/functional/eval/uniq_spec.lua
+++ /dev/null
@@ -1,31 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local clear = helpers.clear
-local meths = helpers.meths
-local command = helpers.command
-local exc_exec = helpers.exc_exec
-local redir_exec = helpers.redir_exec
-
-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")'))
- end)
-
- it('can yield E882 and stop filtering after that', function()
- command([[
- function Cmp(a, b)
- if type(a:a) == type([]) || type(a:b) == type([])
- return []
- endif
- return (a:a > a:b) - (a:a < a:b)
- endfunction
- ]])
- eq('\nE745: Using a List as a Number\nE882: Uniq compare function failed',
- redir_exec('let fl = uniq([0, 0, [], 1, 1], "Cmp")'))
- eq({0, {}, 1, 1}, meths.get_var('fl'))
- end)
-end)
diff --git a/test/functional/eval/vvar_event_spec.lua b/test/functional/eval/vvar_event_spec.lua
deleted file mode 100644
index eec8aa917a..0000000000
--- a/test/functional/eval/vvar_event_spec.lua
+++ /dev/null
@@ -1,15 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear, eval, eq = helpers.clear, helpers.eval, helpers.eq
-local command = helpers.command
-describe('v:event', function()
- before_each(clear)
- it('is empty before any autocommand', function()
- eq({}, eval('v:event'))
- end)
-
- it('is immutable', function()
- eq(false, pcall(command, 'let v:event = {}'))
- eq(false, pcall(command, 'let v:event.mykey = {}'))
- end)
-end)
-
diff --git a/test/functional/eval/wait_spec.lua b/test/functional/eval/wait_spec.lua
deleted file mode 100644
index ee95e02a7f..0000000000
--- a/test/functional/eval/wait_spec.lua
+++ /dev/null
@@ -1,78 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local call = helpers.call
-local clear = helpers.clear
-local command = helpers.command
-local eval = helpers.eval
-local eq = helpers.eq
-local feed = helpers.feed
-local feed_command = helpers.feed_command
-local next_msg = helpers.next_msg
-local nvim = helpers.nvim
-local source = helpers.source
-local pcall_err = helpers.pcall_err
-
-before_each(function()
- clear()
- local channel = nvim('get_api_info')[1]
- nvim('set_var', 'channel', channel)
-end)
-
-describe('wait()', function()
- it('waits and returns 0 when condition is satisfied', function()
- source([[
- let g:_awake = 0
- call timer_start(100, { -> nvim_command('let g:_awake = 1') })
- ]])
- eq(0, eval('g:_awake'))
- eq(0, eval('wait(1500, { -> g:_awake })'))
- eq(1, eval('g:_awake'))
-
- eq(0, eval('wait(0, 1)'))
- end)
-
- it('returns -1 on timeout', function()
- eq(-1, eval('wait(0, 0)'))
- eq(-1, eval('wait(50, 0)'))
- 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('<c-c>')
- eq({'notification', 'wait', {-2}}, next_msg())
- end)
-
- it('returns -3 on error', function()
- command('silent! let ret = wait(-1, "error")')
- eq(-3, eval('ret'))
- command('let ret = 0 | silent! let ret = wait(-1, { -> error })')
- eq(-3, eval('ret'))
- end)
-
- it('evaluates the condition on given interval', function()
- source([[
- function Count()
- let g:counter += 1
- return g:counter
- endfunction
- ]])
-
- -- XXX: flaky (#11137)
- helpers.retry(nil, nil, function()
- nvim('set_var', 'counter', 0)
- eq(-1, call('wait', 20, 'Count() >= 5', 99999))
- end)
-
- nvim('set_var', 'counter', 0)
- eq(0, call('wait', 10000, 'Count() >= 5', 5))
- eq(5, nvim('get_var', 'counter'))
- end)
-
- it('validates args', function()
- eq('Vim:E475: Invalid value for argument 1', pcall_err(call, 'wait', '', 1))
- eq('Vim:E475: Invalid value for argument 3', pcall_err(call, 'wait', 0, 1, -1))
- eq('Vim:E475: Invalid value for argument 3', pcall_err(call, 'wait', 0, 1, 0))
- eq('Vim:E475: Invalid value for argument 3', pcall_err(call, 'wait', 0, 1, ''))
- end)
-end)
diff --git a/test/functional/eval/writefile_spec.lua b/test/functional/eval/writefile_spec.lua
deleted file mode 100644
index 14be8c377c..0000000000
--- a/test/functional/eval/writefile_spec.lua
+++ /dev/null
@@ -1,156 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local lfs = require('lfs')
-
-local clear = helpers.clear
-local eq = helpers.eq
-local funcs = helpers.funcs
-local meths = helpers.meths
-local exc_exec = helpers.exc_exec
-local read_file = helpers.read_file
-local write_file = helpers.write_file
-local redir_exec = helpers.redir_exec
-
-local fname = 'Xtest-functional-eval-writefile'
-local dname = fname .. '.d'
-local dfname_tail = '1'
-local dfname = dname .. '/' .. dfname_tail
-local ddname_tail = '2'
-local ddname = dname .. '/' .. ddname_tail
-
-before_each(function()
- lfs.mkdir(dname)
- lfs.mkdir(ddname)
- clear()
-end)
-
-after_each(function()
- os.remove(fname)
- os.remove(dfname)
- lfs.rmdir(ddname)
- lfs.rmdir(dname)
-end)
-
-describe('writefile()', function()
- it('writes empty list to a file', function()
- eq(nil, read_file(fname))
- eq(0, funcs.writefile({}, fname))
- eq('', read_file(fname))
- os.remove(fname)
- eq(nil, read_file(fname))
- eq(0, funcs.writefile({}, fname, 'b'))
- eq('', read_file(fname))
- os.remove(fname)
- eq(nil, read_file(fname))
- eq(0, funcs.writefile({}, fname, 'ab'))
- eq('', read_file(fname))
- os.remove(fname)
- eq(nil, read_file(fname))
- eq(0, funcs.writefile({}, fname, 'a'))
- eq('', read_file(fname))
- 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('', read_file(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('', read_file(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('abc\ndef\nghi\n', read_file(fname))
- 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('abc\ndef\nghi', read_file(fname))
- 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('\0a\0b\0', read_file(fname))
- 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('\0a\0b\0', read_file(fname))
- 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('\0a\0b\0', read_file(fname))
- 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('\nE482: Can\'t open file 2 for writing: illegal operation on a directory',
- redir_exec(('call writefile([42], %s)'):format(ddname_tail)))
- end)
-
- it('errors out with invalid arguments', function()
- write_file(fname, 'TEST')
- eq('\nE119: Not enough arguments for function: writefile',
- redir_exec('call writefile()'))
- eq('\nE119: Not enough arguments for function: writefile',
- redir_exec('call writefile([])'))
- eq('\nE118: Too many arguments for function: writefile',
- redir_exec(('call writefile([], "%s", "b", 1)'):format(fname)))
- for _, arg in ipairs({'0', '0.0', 'function("tr")', '{}', '"test"'}) do
- eq('\nE475: Invalid argument: writefile() first argument must be a List or a Blob',
- redir_exec(('call writefile(%s, "%s", "b")'):format(arg, fname)))
- end
- for _, args in ipairs({'[], %s, "b"', '[], "' .. fname .. '", %s'}) do
- eq('\nE806: using Float as a String',
- redir_exec(('call writefile(%s)'):format(args:format('0.0'))))
- eq('\nE730: using List as a String',
- redir_exec(('call writefile(%s)'):format(args:format('[]'))))
- eq('\nE731: using Dictionary as a String',
- redir_exec(('call writefile(%s)'):format(args:format('{}'))))
- eq('\nE729: using Funcref as a String',
- redir_exec(('call writefile(%s)'):format(args:format('function("tr")'))))
- end
- eq('\nE5060: Unknown flag: «»',
- redir_exec(('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('\nE805: Expected a Number or a String, Float found',
- redir_exec(('call writefile(%s)'):format(args:format('0.0'))))
- eq(nil, read_file(fname))
- write_file(fname, 'TEST')
- eq('\nE745: Expected a Number or a String, List found',
- redir_exec(('call writefile(%s)'):format(args:format('[]'))))
- eq('TEST', read_file(fname))
- eq('\nE728: Expected a Number or a String, Dictionary found',
- redir_exec(('call writefile(%s)'):format(args:format('{}'))))
- eq('TEST', read_file(fname))
- eq('\nE703: Expected a Number or a String, Funcref found',
- redir_exec(('call writefile(%s)'):format(args:format('function("tr")'))))
- eq('TEST', read_file(fname))
- end)
-end)