aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/vim_spec.lua30
-rw-r--r--test/functional/eval/input_spec.lua354
-rw-r--r--test/functional/ex_cmds/encoding_spec.lua4
-rw-r--r--test/functional/fixtures/tty-test.c9
-rw-r--r--test/functional/ui/cursor_spec.lua4
-rw-r--r--test/unit/eval/typval_spec.lua49
-rw-r--r--test/unit/os/env_spec.lua2
-rw-r--r--test/unit/path_spec.lua55
8 files changed, 485 insertions, 22 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 282ecbfd87..61ec6ea829 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -81,6 +81,36 @@ describe('api', function()
end)
end)
+ describe('nvim_execute_lua', function()
+ it('works', function()
+ meths.execute_lua('vim.api.nvim_set_var("test", 3)', {})
+ eq(3, meths.get_var('test'))
+
+ eq(17, meths.execute_lua('a, b = ...\nreturn a + b', {10,7}))
+
+ eq(NIL, meths.execute_lua('function xx(a,b)\nreturn a..b\nend',{}))
+ eq("xy", meths.execute_lua('return xx(...)', {'x','y'}))
+ end)
+
+ it('reports errors', function()
+ eq({false, 'Error loading lua: [string "<nvim>"]:1: '..
+ "'=' expected near '+'"},
+ meth_pcall(meths.execute_lua, 'a+*b', {}))
+
+ eq({false, 'Error loading lua: [string "<nvim>"]:1: '..
+ "unexpected symbol near '1'"},
+ meth_pcall(meths.execute_lua, '1+2', {}))
+
+ eq({false, 'Error loading lua: [string "<nvim>"]:1: '..
+ "unexpected symbol"},
+ meth_pcall(meths.execute_lua, 'aa=bb\0', {}))
+
+ eq({false, 'Error executing lua: [string "<nvim>"]:1: '..
+ "attempt to call global 'bork' (a nil value)"},
+ meth_pcall(meths.execute_lua, 'bork()', {}))
+ end)
+ end)
+
describe('nvim_input', function()
it("VimL error: does NOT fail, updates v:errmsg", function()
local status, _ = pcall(nvim, "input", ":call bogus_fn()<CR>")
diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua
index 393fc10175..74ad32bc6c 100644
--- a/test/functional/eval/input_spec.lua
+++ b/test/functional/eval/input_spec.lua
@@ -1,9 +1,13 @@
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 screen
@@ -11,28 +15,352 @@ 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
+ ]])
+ screen:set_default_attr_ids({
+ EOB={bold = true, foreground = Screen.colors.Blue1},
+ T={foreground=Screen.colors.Red},
+ })
end)
describe('input()', function()
- it('works correctly with multiline prompts', function()
+ it('works with multiline prompts', function()
feed([[:call input("Test\nFoo")<CR>]])
screen:expect([[
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
Test |
Foo^ |
- ]], {{bold=true, foreground=Screen.colors.Blue}})
+ ]])
end)
- it('works correctly with multiline prompts and :echohl', function()
- command('hi Test ctermfg=Red guifg=Red term=bold')
+ it('works with multiline prompts and :echohl', function()
feed([[:echohl Test | call input("Test\nFoo")<CR>]])
screen:expect([[
- {1:~ }|
- {1:~ }|
- {1:~ }|
- {2:Test} |
- {2:Foo}^ |
- ]], {{bold=true, foreground=Screen.colors.Blue}, {foreground=Screen.colors.Red}})
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {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('redraw!')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {T:Foo>}Bar^ |
+ ]])
+ feed('<BS>')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {T:Foo>}Ba^ |
+ ]])
+ command('redraw!')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {T:Foo>}Ba^ |
+ ]])
+ 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)
+end)
+describe('inputdialog()', function()
+ it('works with multiline prompts', function()
+ feed([[:call inputdialog("Test\nFoo")<CR>]])
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ Test |
+ Foo^ |
+ ]])
+ end)
+ it('works with multiline prompts and :echohl', function()
+ feed([[:echohl Test | call inputdialog("Test\nFoo")<CR>]])
+ screen:expect([[
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {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('redraw!')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {T:Foo>}Bar^ |
+ ]])
+ feed('<BS>')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {T:Foo>}Ba^ |
+ ]])
+ command('redraw!')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {T:Foo>}Ba^ |
+ ]])
+ 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)
end)
diff --git a/test/functional/ex_cmds/encoding_spec.lua b/test/functional/ex_cmds/encoding_spec.lua
index 0769259be4..7f2bd78a47 100644
--- a/test/functional/ex_cmds/encoding_spec.lua
+++ b/test/functional/ex_cmds/encoding_spec.lua
@@ -15,7 +15,7 @@ describe('&encoding', function()
feed_command('set encoding=latin1')
-- error message expected
feed('<cr>')
- neq(nil, string.find(eval('v:errmsg'), '^E474:'))
+ neq(nil, string.find(eval('v:errmsg'), '^E519:'))
eq('utf-8', eval('&encoding'))
-- check nvim is still in utf-8 mode
eq(3, eval('strwidth("Bär")'))
@@ -25,7 +25,7 @@ describe('&encoding', function()
clear('--cmd', 'set enc=latin1')
-- error message expected
feed('<cr>')
- neq(nil, string.find(eval('v:errmsg'), '^E474:'))
+ neq(nil, string.find(eval('v:errmsg'), '^E519:'))
eq('utf-8', eval('&encoding'))
eq(3, eval('strwidth("Bär")'))
end)
diff --git a/test/functional/fixtures/tty-test.c b/test/functional/fixtures/tty-test.c
index 3406b3a202..7ba21d652a 100644
--- a/test/functional/fixtures/tty-test.c
+++ b/test/functional/fixtures/tty-test.c
@@ -6,6 +6,9 @@
#include <stdlib.h>
#include <uv.h>
+// -V:STRUCT_CAST:641
+#define STRUCT_CAST(Type, obj) ((Type *)(obj))
+
uv_tty_t tty;
#ifdef _WIN32
@@ -88,9 +91,9 @@ static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
uv_tty_init(&write_loop, &out, 1, 0);
uv_write_t req;
uv_buf_t b = {.base = buf->base, .len = (size_t)cnt};
- uv_write(&req, (uv_stream_t *)&out, &b, 1, NULL);
+ uv_write(&req, STRUCT_CAST(uv_stream_t, &out), &b, 1, NULL);
uv_run(&write_loop, UV_RUN_DEFAULT);
- uv_close((uv_handle_t *)&out, NULL);
+ uv_close(STRUCT_CAST(uv_handle_t, &out), NULL);
uv_run(&write_loop, UV_RUN_DEFAULT);
if (uv_loop_close(&write_loop)) {
abort();
@@ -149,7 +152,7 @@ int main(int argc, char **argv)
uv_tty_init(uv_default_loop(), &tty, fileno(stderr), 1);
uv_tty_set_mode(&tty, UV_TTY_MODE_RAW);
tty.data = &interrupted;
- uv_read_start((uv_stream_t *)&tty, alloc_cb, read_cb);
+ uv_read_start(STRUCT_CAST(uv_stream_t, &tty), alloc_cb, read_cb);
#ifndef WIN32
struct sigaction sa;
sigemptyset(&sa.sa_mask);
diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua
index f4eec4bdc7..b47210a777 100644
--- a/test/functional/ui/cursor_spec.lua
+++ b/test/functional/ui/cursor_spec.lua
@@ -194,8 +194,8 @@ describe('ui/cursor', function()
if m.blinkoff then m.blinkoff = 400 end
if m.blinkwait then m.blinkwait = 700 end
end
- if m.hl_id then m.hl_id = 47 end
- if m.id_lm then m.id_lm = 48 end
+ if m.hl_id then m.hl_id = 48 end
+ if m.id_lm then m.id_lm = 49 end
end
-- Assert the new expectation.
diff --git a/test/unit/eval/typval_spec.lua b/test/unit/eval/typval_spec.lua
index 6308ae7367..5d543f914f 100644
--- a/test/unit/eval/typval_spec.lua
+++ b/test/unit/eval/typval_spec.lua
@@ -1751,6 +1751,55 @@ describe('typval.c', function()
eq('2', s)
end)
end)
+ describe('get_string_buf_chk()', function()
+ local function tv_dict_get_string_buf_chk(d, key, len, buf, def, emsg)
+ buf = buf or ffi.gc(lib.xmalloc(lib.NUMBUFLEN), lib.xfree)
+ def = def or ffi.gc(lib.xstrdup('DEFAULT'), lib.xfree)
+ len = len or #key
+ alloc_log:clear()
+ local ret = check_emsg(function() return lib.tv_dict_get_string_buf_chk(d, key, len, buf, def) end,
+ emsg)
+ local s_ret = (ret ~= nil) and ffi.string(ret) or nil
+ if not emsg then
+ alloc_log:check({})
+ end
+ return s_ret, ret, buf, def
+ end
+ itp('works with NULL dict', function()
+ eq('DEFAULT', tv_dict_get_string_buf_chk(nil, 'test'))
+ end)
+ itp('works', function()
+ local lua_d = {
+ ['']={},
+ t=1,
+ te=int(2),
+ tes=empty_list,
+ test='tset',
+ testt=5,
+ }
+ local d = dict(lua_d)
+ alloc_log:clear()
+ eq(lua_d, dct2tbl(d))
+ alloc_log:check({})
+ local s, r, b, def
+ s, r, b, def = tv_dict_get_string_buf_chk(d, 'test')
+ neq(r, b)
+ neq(r, def)
+ eq('tset', s)
+ s, r, b, def = tv_dict_get_string_buf_chk(d, 'test', 1, nil, nil, 'E806: using Float as a String')
+ neq(r, b)
+ neq(r, def)
+ eq(nil, s)
+ s, r, b, def = tv_dict_get_string_buf_chk(d, 'te')
+ eq(r, b)
+ neq(r, def)
+ eq('2', s)
+ s, r, b, def = tv_dict_get_string_buf_chk(d, 'TEST')
+ eq(r, def)
+ neq(r, b)
+ eq('DEFAULT', s)
+ end)
+ end)
describe('get_callback()', function()
local function tv_dict_get_callback(d, key, key_len, emsg)
key_len = key_len or #key
diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua
index 575787a25e..cefd0315b7 100644
--- a/test/unit/os/env_spec.lua
+++ b/test/unit/os/env_spec.lua
@@ -13,7 +13,7 @@ require('lfs')
local cimp = cimport('./src/nvim/os/os.h')
-describe('env function', function()
+describe('env.c', function()
local function os_setenv(name, value, override)
return cimp.os_setenv(to_cstr(name), to_cstr(value), override)
end
diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua
index 6b9e2c8695..a9cba7df84 100644
--- a/test/unit/path_spec.lua
+++ b/test/unit/path_spec.lua
@@ -18,7 +18,7 @@ local cimp = cimport('./src/nvim/os/os.h', './src/nvim/path.h')
local length = 0
local buffer = nil
-describe('path function', function()
+describe('path.c', function()
describe('path_full_dir_name', function()
setup(function()
lfs.mkdir('unit-test-directory')
@@ -293,6 +293,59 @@ describe('path_shorten_fname_if_possible', function()
end)
end)
+describe('path.c path_guess_exepath', function()
+ local cwd = lfs.currentdir()
+
+ for _,name in ipairs({'./nvim', '.nvim', 'foo/nvim'}) do
+ itp('"'..name..'" returns name catenated with CWD', function()
+ local bufsize = 255
+ local buf = cstr(bufsize, '')
+ cimp.path_guess_exepath(name, buf, bufsize)
+ eq(cwd..'/'..name, ffi.string(buf))
+ end)
+ end
+
+ itp('absolute path returns the name unmodified', function()
+ local name = '/foo/bar/baz'
+ local bufsize = 255
+ local buf = cstr(bufsize, '')
+ cimp.path_guess_exepath(name, buf, bufsize)
+ eq(name, ffi.string(buf))
+ end)
+
+ itp('returns the name unmodified if not found in $PATH', function()
+ local name = '23u0293_not_in_path'
+ local bufsize = 255
+ local buf = cstr(bufsize, '')
+ cimp.path_guess_exepath(name, buf, bufsize)
+ eq(name, ffi.string(buf))
+ end)
+
+ itp('does not crash if $PATH item exceeds MAXPATHL', function()
+ local orig_path_env = os.getenv('PATH')
+ local name = 'cat' -- Some executable in $PATH.
+ local bufsize = 255
+ local buf = cstr(bufsize, '')
+ local insane_path = orig_path_env..':'..(("x/"):rep(4097))
+
+ cimp.os_setenv('PATH', insane_path, true)
+ cimp.path_guess_exepath(name, buf, bufsize)
+ eq('bin/' .. name, ffi.string(buf):sub(-#('bin/' .. name), -1))
+
+ -- Restore $PATH.
+ cimp.os_setenv('PATH', orig_path_env, true)
+ end)
+
+ itp('returns full path found in $PATH', function()
+ local name = 'cat' -- Some executable in $PATH.
+ local bufsize = 255
+ local buf = cstr(bufsize, '')
+ cimp.path_guess_exepath(name, buf, bufsize)
+ -- Usually "/bin/cat" on unix, "/path/to/nvim/cat" on Windows.
+ eq('bin/' .. name, ffi.string(buf):sub(-#('bin/' .. name), -1))
+ end)
+end)
+
describe('path.c', function()
setup(function()
lfs.mkdir('unit-test-directory');