aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/core/job_spec.lua5
-rw-r--r--test/functional/eval/null_spec.lua26
-rw-r--r--test/functional/eval/writefile_spec.lua10
-rw-r--r--test/functional/lua/buffer_updates_spec.lua77
-rw-r--r--test/functional/plugin/lsp_spec.lua23
-rw-r--r--test/functional/terminal/buffer_spec.lua7
-rw-r--r--test/functional/treesitter/language_spec.lua2
-rw-r--r--test/functional/ui/cmdline_spec.lua13
-rw-r--r--test/functional/ui/float_spec.lua157
-rw-r--r--test/functional/ui/searchhl_spec.lua14
-rw-r--r--test/helpers.lua6
11 files changed, 315 insertions, 25 deletions
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index b59d87eb12..9de0d08e79 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -963,8 +963,10 @@ describe('jobs', function()
return rv
end
+ local j
local function send(str)
- nvim('command', 'call jobsend(j, "'..str..'")')
+ -- check no nvim_chan_free double free with pty job (#14198)
+ meths.chan_send(j, str)
end
before_each(function()
@@ -979,6 +981,7 @@ describe('jobs', function()
nvim('command', 'let g:job_opts.pty = 1')
nvim('command', 'let exec = [expand("<cfile>:p")]')
nvim('command', "let j = jobstart(exec, g:job_opts)")
+ j = eval'j'
eq('tty ready', next_chunk())
end)
diff --git a/test/functional/eval/null_spec.lua b/test/functional/eval/null_spec.lua
index fa8f7d873f..d403fbc878 100644
--- a/test/functional/eval/null_spec.lua
+++ b/test/functional/eval/null_spec.lua
@@ -14,7 +14,8 @@ describe('NULL', function()
clear()
command('let L = v:_null_list')
command('let D = v:_null_dict')
- command('let S = $XXX_NONEXISTENT_VAR_XXX')
+ command('let S = v:_null_string')
+ command('let V = $XXX_NONEXISTENT_VAR_XXX')
end)
local tmpfname = 'Xtest-functional-viml-null'
after_each(function()
@@ -129,6 +130,7 @@ describe('NULL', function()
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()
@@ -142,4 +144,26 @@ describe('NULL', function()
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('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/writefile_spec.lua b/test/functional/eval/writefile_spec.lua
index 0bb7523d7e..356680ba7c 100644
--- a/test/functional/eval/writefile_spec.lua
+++ b/test/functional/eval/writefile_spec.lua
@@ -59,6 +59,16 @@ describe('writefile()', function()
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))
diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua
index e79a5b7673..3cb14ca93f 100644
--- a/test/functional/lua/buffer_updates_spec.lua
+++ b/test/functional/lua/buffer_updates_spec.lua
@@ -537,20 +537,65 @@ describe('lua: nvim_buf_attach on_bytes', function()
end)
it('inccomand=nosplit and substitute', function()
- local check_events = setup_eventcheck(verify, {"abcde"})
+ local check_events = setup_eventcheck(verify,
+ {"abcde", "12345"})
meths.set_option('inccommand', 'nosplit')
- feed ':%s/bcd/'
+ -- linewise substitute
+ feed(':%s/bcd/')
check_events {
{ "test1", "bytes", 1, 3, 0, 1, 1, 0, 3, 3, 0, 0, 0 };
{ "test1", "bytes", 1, 5, 0, 1, 1, 0, 0, 0, 0, 3, 3 };
}
- feed 'a'
+ feed('a')
check_events {
{ "test1", "bytes", 1, 3, 0, 1, 1, 0, 3, 3, 0, 1, 1 };
{ "test1", "bytes", 1, 5, 0, 1, 1, 0, 1, 1, 0, 3, 3 };
}
+
+ feed("<esc>")
+
+ -- splitting lines
+ feed([[:%s/abc/\r]])
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 0, 0, 0, 3, 3, 1, 0, 1 };
+ { "test1", "bytes", 1, 6, 0, 0, 0, 1, 0, 1, 0, 3, 3 };
+ }
+
+ feed("<esc>")
+ -- multi-line regex
+ feed([[:%s/de\n123/a]])
+
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 3, 3, 1, 3, 6, 0, 1, 1 };
+ { "test1", "bytes", 1, 6, 0, 3, 3, 0, 1, 1, 1, 3, 6 };
+ }
+
+ feed("<esc>")
+ -- replacing with unicode
+ feed(":%s/b/→")
+
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 3, 3 };
+ { "test1", "bytes", 1, 5, 0, 1, 1, 0, 3, 3, 0, 1, 1 };
+ }
+
+ feed("<esc>")
+ -- replacing with escaped characters
+ feed([[:%s/b/\\]])
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 1, 1 };
+ { "test1", "bytes", 1, 5, 0, 1, 1, 0, 1, 1, 0, 1, 1 };
+ }
+
+ feed("<esc>")
+ -- replacing with expression register
+ feed([[:%s/b/\=5+5]])
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 1, 1, 0, 1, 1, 0, 2, 2 };
+ { "test1", "bytes", 1, 5, 0, 1, 1, 0, 2, 2, 0, 1, 1 };
+ }
end)
it('nvim_buf_set_text insert', function()
@@ -670,7 +715,7 @@ describe('lua: nvim_buf_attach on_bytes', function()
command("set noet")
command("set ts=4")
command("set sw=2")
- command("set sts=2")
+ command("set sts=4")
local check_events = setup_eventcheck(verify, {'asdfasdf'})
@@ -689,6 +734,7 @@ describe('lua: nvim_buf_attach on_bytes', function()
{ "test1", "bytes", 1, 7, 0, 0, 0, 0, 4, 4, 0, 1, 1 },
}
+
feed("<esc>u")
check_events {
{ "test1", "bytes", 1, 8, 0, 0, 0, 0, 1, 1, 0, 4, 4 },
@@ -728,6 +774,29 @@ describe('lua: nvim_buf_attach on_bytes', function()
{ "test1", "bytes", 1, 29, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
{ "test1", "bytes", 1, 31, 0, 0, 0, 0, 4, 4, 0, 1, 1 };
}
+
+ -- inserting tab after other tabs
+ command("set sw=4")
+ feed("<esc>0a<tab>")
+ check_events {
+ { "test1", "bytes", 1, 32, 0, 1, 1, 0, 0, 0, 0, 1, 1 };
+ { "test1", "bytes", 1, 33, 0, 2, 2, 0, 0, 0, 0, 1, 1 };
+ { "test1", "bytes", 1, 34, 0, 3, 3, 0, 0, 0, 0, 1, 1 };
+ { "test1", "bytes", 1, 35, 0, 4, 4, 0, 0, 0, 0, 1, 1 };
+ { "test1", "bytes", 1, 36, 0, 1, 1, 0, 4, 4, 0, 1, 1 };
+ }
+ end)
+
+ it("retab", function()
+ command("set noet")
+ command("set ts=4")
+
+ local check_events = setup_eventcheck(verify, {" asdf"})
+ command("retab 8")
+
+ check_events {
+ { "test1", "bytes", 1, 3, 0, 0, 0, 0, 7, 7, 0, 9, 9 };
+ }
end)
it("sends events when undoing with undofile", function()
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 6d3af115fa..66b33cc9e1 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -29,6 +29,16 @@ teardown(function()
os.remove(fake_lsp_logfile)
end)
+local function clear_notrace()
+ -- problem: here be dragons
+ -- solution: don't look for dragons to closely
+ clear {env={
+ NVIM_LUA_NOTRACK="1";
+ VIMRUNTIME=os.getenv"VIMRUNTIME";
+ }}
+end
+
+
local function fake_lsp_server_setup(test_name, timeout_ms, options)
exec_lua([=[
lsp = require('vim.lsp')
@@ -36,6 +46,7 @@ local function fake_lsp_server_setup(test_name, timeout_ms, options)
TEST_RPC_CLIENT_ID = lsp.start_client {
cmd_env = {
NVIM_LOG_FILE = logfile;
+ NVIM_LUA_NOTRACK = "1";
};
cmd = {
vim.v.progpath, '-Es', '-u', 'NONE', '--headless',
@@ -65,7 +76,7 @@ end
local function test_rpc_server(config)
if config.test_name then
- clear()
+ clear_notrace()
fake_lsp_server_setup(config.test_name, config.timeout_ms or 1e3, config.options)
end
local client = setmetatable({}, {
@@ -120,7 +131,7 @@ end
describe('LSP', function()
describe('server_name specified', function()
before_each(function()
- clear()
+ clear_notrace()
-- Run an instance of nvim on the file which contains our "scripts".
-- Pass TEST_NAME to pick the script.
local test_name = "basic_init"
@@ -250,6 +261,10 @@ describe('LSP', function()
end)
it('should succeed with manual shutdown', function()
+ if 'openbsd' == helpers.uname() then
+ pending('hangs the build on openbsd #14028, re-enable with freeze timeout #14204')
+ return
+ end
local expected_callbacks = {
{NIL, "shutdown", {}, 1, NIL};
{NIL, "test", {}, 1};
@@ -314,7 +329,7 @@ describe('LSP', function()
}
end)
it('workspace/configuration returns NIL per section if client was started without config.settings', function()
- clear()
+ clear_notrace()
fake_lsp_server_setup('workspace/configuration no settings')
eq({ NIL, NIL, }, exec_lua [[
local params = {
@@ -941,7 +956,7 @@ end)
describe('LSP', function()
before_each(function()
- clear()
+ clear_notrace()
end)
local function make_edit(y_0, x_0, y_1, x_1, text)
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 209537831f..c61bf108cb 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -258,6 +258,13 @@ describe(':terminal buffer', function()
it('handles wqall', function()
eq('Vim(wqall):E948: Job still running', exc_exec('wqall'))
end)
+
+ it('does not segfault when pasting empty buffer #13955', function()
+ feed_command('terminal')
+ feed('<c-\\><c-n>')
+ feed_command('put a') -- buffer a is empty
+ helpers.assert_alive()
+ end)
end)
describe('No heap-buffer-overflow when using', function()
diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua
index a5801271cb..afb17dd2cf 100644
--- a/test/functional/treesitter/language_spec.lua
+++ b/test/functional/treesitter/language_spec.lua
@@ -45,7 +45,7 @@ describe('treesitter API', function()
return {keys, lang.fields, symbols}
]]))
- eq({fields=true, symbols=true}, keys)
+ eq({fields=true, symbols=true, _abi_version=true}, keys)
local fset = {}
for _,f in pairs(fields) do
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 21c01b3458..0ea8bab957 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local clear, feed = helpers.clear, helpers.feed
local source = helpers.source
local command = helpers.command
+local assert_alive = helpers.assert_alive
local function new_screen(opt)
local screen = Screen.new(25, 5)
@@ -758,6 +759,7 @@ local function test_cmdline(linegrid)
end)
it("doesn't send invalid events when aborting mapping #10000", function()
+ command('set notimeout')
command('cnoremap ab c')
feed(':xa')
@@ -842,3 +844,14 @@ describe('cmdline redraw', function()
]], unchanged=true}
end)
end)
+
+describe("cmdline height", function()
+ it("does not crash resized screen #14263", function()
+ clear()
+ local screen = Screen.new(25, 10)
+ screen:attach()
+ command('set cmdheight=9999')
+ screen:try_resize(25, 5)
+ assert_alive()
+ end)
+end)
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 664b8e7ab7..3e73d8b3de 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -42,6 +42,10 @@ describe('float window', function()
[20] = {bold = true, foreground = Screen.colors.Brown},
[21] = {background = Screen.colors.Gray90},
[22] = {background = Screen.colors.LightRed},
+ [23] = {foreground = Screen.colors.Black, background = Screen.colors.White};
+ [24] = {foreground = Screen.colors.Black, background = Screen.colors.Grey80};
+ [25] = {blend = 100, background = Screen.colors.Gray0};
+ [26] = {blend = 80, background = Screen.colors.Gray0};
}
it('behavior', function()
@@ -644,7 +648,6 @@ describe('float window', function()
end
meths.win_set_config(win, {border="single"})
-
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -687,9 +690,51 @@ describe('float window', function()
]]}
end
+ meths.win_set_config(win, {border="solid"})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ {5: }|
+ {5: }{1: halloj! }{5: }|
+ {5: }{1: BORDAA }{5: }|
+ {5: }|
+ ]], float_pos={
+ [5] = { { id = 1002 }, "NW", 1, 2, 5, true }
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ }}
+ else
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }{5: }{0: }|
+ {0:~ }{5: }{1: halloj! }{5: }{0: }|
+ {0:~ }{5: }{1: BORDAA }{5: }{0: }|
+ {0:~ }{5: }{0: }|
+ |
+ ]]}
+ end
+
-- support: ascii char, UTF-8 char, composed char, highlight per char
meths.win_set_config(win, {border={"x", {"å", "ErrorMsg"}, {"\\"}, {"n̈̊", "Search"}}})
-
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -710,10 +755,10 @@ describe('float window', function()
## grid 3
|
## grid 5
- {5:xååååååååå\}|
- {5:n̈̊}{1: halloj! }{5:n̈̊}|
- {5:n̈̊}{1: BORDAA }{5:n̈̊}|
- {5:\åååååååååx}|
+ {5:x}{7:ååååååååå}{5:\}|
+ {17:n̈̊}{1: halloj! }{17:n̈̊}|
+ {17:n̈̊}{1: BORDAA }{17:n̈̊}|
+ {5:\}{7:ååååååååå}{5:x}|
]], float_pos={
[5] = { { id = 1002 }, "NW", 1, 2, 5, true }
}, win_viewport={
@@ -772,6 +817,97 @@ describe('float window', function()
|
]]}
end
+
+ meths.win_set_config(win, {border={"", "", "", ">", "", "", "", "<"}})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ ^ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ ## grid 3
+ |
+ ## grid 5
+ {5:<}{1: halloj! }{5:>}|
+ {5:<}{1: BORDAA }{5:>}|
+ ]], float_pos={
+ [5] = { { id = 1002 }, "NW", 1, 2, 5, true }
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ }}
+ else
+ screen:expect{grid=[[
+ ^ |
+ {0:~ }|
+ {0:~ }{5:<}{1: halloj! }{5:>}{0: }|
+ {0:~ }{5:<}{1: BORDAA }{5:>}{0: }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]]}
+ end
+
+ insert [[
+ neeed some dummy
+ background text
+ to show the effect
+ of color blending
+ of border shadow
+ ]]
+
+ meths.win_set_config(win, {border="shadow"})
+ if multigrid then
+ screen:expect{grid=[[
+ ## grid 1
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [2:----------------------------------------]|
+ [3:----------------------------------------]|
+ ## grid 2
+ neeed some dummy |
+ background text |
+ to show the effect |
+ of color blending |
+ of border shadow |
+ ^ |
+ ## grid 3
+ |
+ ## grid 5
+ {1: halloj! }{25: }|
+ {1: BORDAA }{26: }|
+ {25: }{26: }|
+ ]], float_pos={
+ [5] = { { id = 1002 }, "NW", 1, 2, 5, true }
+ }, win_viewport={
+ [2] = {win = {id = 1000}, topline = 0, botline = 6, curline = 5, curcol = 0};
+ [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0};
+ }}
+ else
+ screen:expect{grid=[[
+ neeed some dummy |
+ background text |
+ to {1: halloj! }{23:e}ffect |
+ of {1: BORDAA }{24:n}ding |
+ of {23:b}{24:order sha}dow |
+ ^ |
+ |
+ ]]}
+ end
end)
it('with border show popupmenu', function()
@@ -835,7 +971,6 @@ describe('float window', function()
end
feed 'i<c-x><c-p>'
-
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -873,12 +1008,8 @@ describe('float window', function()
{1: abb }|
{13: acc }|
]], float_pos={
- [5] = { {
- id = 1002
- }, "NW", 1, 0, 5, true },
- [6] = { {
- id = -1
- }, "NW", 5, 4, 0, false }
+ [5] = { { id = 1002 }, "NW", 1, 0, 5, true },
+ [6] = { { id = -1 }, "NW", 5, 4, 0, false }
}, win_viewport={
[2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0};
[5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 2, curcol = 3};
diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua
index 656f613c6a..5540b3c2dc 100644
--- a/test/functional/ui/searchhl_spec.lua
+++ b/test/functional/ui/searchhl_spec.lua
@@ -507,7 +507,21 @@ describe('search highlighting', function()
{1:~ }|
:syntax keyword MyGroup special |
]])
+ end)
+ it('highlights entire pattern on :%g@a/b', function()
+ command('set inccommand=nosplit')
+ feed('ia/b/c<Esc>')
+ feed(':%g@a/b')
+ screen:expect([[
+ {3:a/b}/c |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ :%g@a/b^ |
+ ]])
end)
end)
diff --git a/test/helpers.lua b/test/helpers.lua
index 8dbd82cb8c..12d9f19187 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -365,7 +365,11 @@ function module.check_cores(app, force)
db_cmd = lldb_db_cmd
else
initial_path = '.'
- re = '/core[^/]*$'
+ if 'freebsd' == module.uname() then
+ re = '/nvim.core$'
+ else
+ re = '/core[^/]*$'
+ end
exc_re = { '^/%.deps$', '^/%'..deps_prefix()..'$', local_tmpdir, '^/%node_modules$' }
db_cmd = gdb_db_cmd
random_skip = true