diff options
Diffstat (limited to 'test/functional')
-rw-r--r-- | test/functional/core/job_spec.lua | 5 | ||||
-rw-r--r-- | test/functional/eval/null_spec.lua | 26 | ||||
-rw-r--r-- | test/functional/eval/writefile_spec.lua | 10 | ||||
-rw-r--r-- | test/functional/lua/buffer_updates_spec.lua | 77 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 23 | ||||
-rw-r--r-- | test/functional/terminal/buffer_spec.lua | 7 | ||||
-rw-r--r-- | test/functional/treesitter/language_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/ui/cmdline_spec.lua | 13 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 157 | ||||
-rw-r--r-- | test/functional/ui/searchhl_spec.lua | 14 |
10 files changed, 310 insertions, 24 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) |