diff options
author | Josh Rahm <rahm@google.com> | 2022-10-11 19:00:52 +0000 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2022-10-11 19:00:52 +0000 |
commit | 21e2e46242033c7aaa6ccfb23e256680816c063c (patch) | |
tree | f089522cfb145d6e9c8a86a01d8e454ce5501e20 /test/functional/lua | |
parent | 179d3ed87b17988f5fe00d8b99f2611a28212be7 (diff) | |
parent | 760b399f6c0c6470daa0663752bd22886997f9e6 (diff) | |
download | rneovim-floattitle.tar.gz rneovim-floattitle.tar.bz2 rneovim-floattitle.zip |
Merge remote-tracking branch 'upstream/master' into floattitlefloattitle
Diffstat (limited to 'test/functional/lua')
-rw-r--r-- | test/functional/lua/api_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/lua/buffer_updates_spec.lua | 20 | ||||
-rw-r--r-- | test/functional/lua/diagnostic_spec.lua | 46 | ||||
-rw-r--r-- | test/functional/lua/filetype_spec.lua | 8 | ||||
-rw-r--r-- | test/functional/lua/fs_spec.lua | 17 | ||||
-rw-r--r-- | test/functional/lua/help_spec.lua | 49 | ||||
-rw-r--r-- | test/functional/lua/ui_event_spec.lua | 120 | ||||
-rw-r--r-- | test/functional/lua/uri_spec.lua | 14 | ||||
-rw-r--r-- | test/functional/lua/vim_spec.lua | 117 |
9 files changed, 368 insertions, 25 deletions
diff --git a/test/functional/lua/api_spec.lua b/test/functional/lua/api_spec.lua index f173a15d32..03832978a4 100644 --- a/test/functional/lua/api_spec.lua +++ b/test/functional/lua/api_spec.lua @@ -166,7 +166,7 @@ describe('luaeval(vim.api.…)', function() eq({v={}}, funcs.luaeval('vim.api.nvim__id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2}})')) -- If API requests dictionary, then empty table will be the one. This is not - -- the case normally because empty table is an empty arrray. + -- the case normally because empty table is an empty array. eq({}, funcs.luaeval('vim.api.nvim__id_dictionary({})')) eq(4, eval([[type(luaeval('vim.api.nvim__id_dictionary({})'))]])) end) diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 10de45274c..2fd44b8b5f 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -118,6 +118,24 @@ describe('lua buffer event callbacks: on_lines', function() } tick = tick + 1 + tick = tick + 1 + command('redo') + check_events { + { "test1", "lines", 1, tick, 3, 5, 4, 32 }; + { "test2", "lines", 1, tick, 3, 5, 4, 32 }; + { "test2", "changedtick", 1, tick+1 }; + } + tick = tick + 1 + + tick = tick + 1 + command('undo!') + check_events { + { "test1", "lines", 1, tick, 3, 4, 5, 13 }; + { "test2", "lines", 1, tick, 3, 4, 5, 13 }; + { "test2", "changedtick", 1, tick+1 }; + } + tick = tick + 1 + -- simulate next callback returning true exec_lua("test_unreg = 'test1'") @@ -315,7 +333,7 @@ describe('lua: nvim_buf_attach on_bytes', function() start_txt = meths.buf_get_lines(0, 0, -1, true) end local shadowbytes = table.concat(start_txt, '\n') .. '\n' - -- TODO: while we are brewing the real strong coffe, + -- TODO: while we are brewing the real strong coffee, -- verify should check buf_get_offset after every check_events if verify then local len = meths.buf_get_offset(0, meths.buf_line_count(0)) diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index f9647f5b6a..28a8679205 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -128,6 +128,37 @@ describe('vim.diagnostic', function() eq('Diagnostic #1', result[1].message) end) + it('removes diagnostics from the cache when a buffer is removed', function() + eq(2, exec_lua [[ + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) + local other_bufnr = vim.fn.bufadd('test | test') + local lines = vim.api.nvim_buf_get_lines(diagnostic_bufnr, 0, -1, true) + vim.api.nvim_buf_set_lines(other_bufnr, 0, 1, false, lines) + vim.cmd('bunload! ' .. other_bufnr) + + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + make_error('Diagnostic #2', 2, 1, 2, 1), + }) + vim.diagnostic.set(diagnostic_ns, other_bufnr, { + make_error('Diagnostic #3', 3, 1, 3, 1), + }) + vim.api.nvim_set_current_buf(other_bufnr) + vim.opt_local.buflisted = true + vim.cmd('bwipeout!') + return #vim.diagnostic.get() + ]]) + eq(2, exec_lua [[ + vim.api.nvim_set_current_buf(diagnostic_bufnr) + vim.opt_local.buflisted = false + return #vim.diagnostic.get() + ]]) + eq(0, exec_lua [[ + vim.cmd('bwipeout!') + return #vim.diagnostic.get() + ]]) + end) + it('resolves buffer number 0 to the current buffer', function() eq(2, exec_lua [[ vim.api.nvim_set_current_buf(diagnostic_bufnr) @@ -1952,19 +1983,26 @@ end) end) it('triggers the autocommand when diagnostics are set', function() - eq(true, exec_lua [[ + eq({true, true}, exec_lua [[ -- Set a different buffer as current to test that <abuf> is being set properly in -- DiagnosticChanged callbacks local tmp = vim.api.nvim_create_buf(false, true) vim.api.nvim_set_current_buf(tmp) - vim.g.diagnostic_autocmd_triggered = 0 - vim.cmd('autocmd DiagnosticChanged * let g:diagnostic_autocmd_triggered = +expand("<abuf>")') + local triggered = {} + vim.api.nvim_create_autocmd('DiagnosticChanged', { + callback = function(args) + triggered = {args.buf, #args.data.diagnostics} + end, + }) vim.api.nvim_buf_set_name(diagnostic_bufnr, "test | test") vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error('Diagnostic', 0, 0, 0, 0) }) - return vim.g.diagnostic_autocmd_triggered == diagnostic_bufnr + return { + triggered[1] == diagnostic_bufnr, + triggered[2] == 1, + } ]]) end) diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index be57b2db31..2a7be53164 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -1,6 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local exec_lua = helpers.exec_lua local eq = helpers.eq +local meths = helpers.meths local clear = helpers.clear local pathroot = helpers.pathroot local command = helpers.command @@ -94,3 +95,10 @@ describe('vim.filetype', function() ]]) end) end) + +describe('filetype.lua', function() + it('does not override user autocommands that set filetype #20333', function() + clear({args={'--clean', '--cmd', 'autocmd BufRead *.md set filetype=notmarkdown', 'README.md'}}) + eq('notmarkdown', meths.buf_get_option(0, 'filetype')) + end) +end) diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 2bcc84db0f..3123ec324c 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -78,6 +78,23 @@ describe('vim.fs', function() return vim.fs.find(nvim, { path = dir, type = 'file' }) ]], test_build_dir, nvim_prog_basename)) end) + + it('accepts predicate as names', function() + eq({test_build_dir}, exec_lua([[ + local dir = ... + local opts = { path = dir, upward = true, type = 'directory' } + return vim.fs.find(function(x) return x == 'build' end, opts) + ]], nvim_dir)) + eq({nvim_prog}, exec_lua([[ + local dir, nvim = ... + return vim.fs.find(function(x) return x == nvim end, { path = dir, type = 'file' }) + ]], test_build_dir, nvim_prog_basename)) + eq({}, exec_lua([[ + local dir = ... + local opts = { path = dir, upward = true, type = 'directory' } + return vim.fs.find(function(x) return x == 'no-match' end, opts) + ]], nvim_dir)) + end) end) describe('normalize()', function() diff --git a/test/functional/lua/help_spec.lua b/test/functional/lua/help_spec.lua new file mode 100644 index 0000000000..251275b5cc --- /dev/null +++ b/test/functional/lua/help_spec.lua @@ -0,0 +1,49 @@ +-- Tests for gen_help_html.lua. Validates :help tags/links and HTML doc generation. +-- +-- TODO: extract parts of gen_help_html.lua into Nvim stdlib? + +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local exec_lua = helpers.exec_lua +local eq = helpers.eq +local ok = helpers.ok + +describe(':help docs', function() + before_each(clear) + it('validate', function() + -- If this test fails, try these steps (in order): + -- 1. Fix/cleanup the :help docs. + -- 2. Fix the parser: https://github.com/neovim/tree-sitter-vimdoc + -- 3. File a parser bug, and adjust the tolerance of this test in the meantime. + + local rv = exec_lua([[return require('scripts.gen_help_html').validate('./build/runtime/doc')]]) + -- Check that we actually found helpfiles. + ok(rv.helpfiles > 100, '>100 :help files', rv.helpfiles) + -- Check that parse errors did not increase wildly. + -- TODO: Fix all parse errors in :help files. + ok(rv.err_count < 150, '<150 parse errors', rv.err_count) + eq({}, rv.invalid_links, exec_lua([[return 'found invalid :help tag links:\n'..vim.inspect(...)]], rv.invalid_links)) + end) + + it('gen_help_html.lua generates HTML', function() + -- 1. Test that gen_help_html.lua actually works. + -- 2. Test that parse errors did not increase wildly. Because we explicitly test only a few + -- :help files, we can be precise about the tolerances here. + + local tmpdir = exec_lua('return vim.fs.dirname(vim.fn.tempname())') + -- Because gen() is slow (~30s), this test is limited to a few files. + local rv = exec_lua([[ + local to_dir = ... + return require('scripts.gen_help_html').gen( + './build/runtime/doc', + to_dir, + { 'pi_health.txt', 'help.txt', 'index.txt', 'nvim.txt', } + ) + ]], + tmpdir + ) + eq(4, #rv.helpfiles) + ok(rv.err_count <= 1, '<=1 parse errors', rv.err_count) + eq({}, rv.invalid_links, exec_lua([[return 'found invalid :help tag links:\n'..vim.inspect(...)]], rv.invalid_links)) + end) +end) diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua new file mode 100644 index 0000000000..57ffcf7b4e --- /dev/null +++ b/test/functional/lua/ui_event_spec.lua @@ -0,0 +1,120 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') +local eq = helpers.eq +local exec_lua = helpers.exec_lua +local clear = helpers.clear +local feed = helpers.feed +local funcs = helpers.funcs +local inspect = require'vim.inspect' + +describe('vim.ui_attach', function() + local screen + before_each(function() + clear() + exec_lua [[ + ns = vim.api.nvim_create_namespace 'testspace' + events = {} + function on_event(event, ...) + events[#events+1] = {event, ...} + return true + end + + function get_events() + local ret_events = events + events = {} + return ret_events + end + ]] + + screen = Screen.new(40,5) + screen:set_default_attr_ids({ + [1] = {bold = true, foreground = Screen.colors.Blue1}; + [2] = {bold = true}; + [3] = {background = Screen.colors.Grey}; + [4] = {background = Screen.colors.LightMagenta}; + }) + screen:attach() + end) + + local function expect_events(expected) + local evs = exec_lua "return get_events(...)" + eq(expected, evs, inspect(evs)) + end + + it('can receive popupmenu events', function() + exec_lua [[ vim.ui_attach(ns, {ext_popupmenu=true}, on_event) ]] + feed('ifo') + screen:expect{grid=[[ + fo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]} + + funcs.complete(1, {'food', 'foobar', 'foo'}) + screen:expect{grid=[[ + food^ | + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]} + expect_events { + { "popupmenu_show", { { "food", "", "", "" }, { "foobar", "", "", "" }, { "foo", "", "", "" } }, 0, 0, 0, 1 }; + } + + feed '<c-n>' + screen:expect{grid=[[ + foobar^ | + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]} + expect_events { + { "popupmenu_select", 1 }; + } + + feed '<c-y>' + screen:expect{grid=[[ + foobar^ | + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], intermediate=true} + expect_events { + { "popupmenu_hide" }; + } + + -- vim.ui_detach() stops events, and reenables builtin pum immediately + exec_lua [[ + vim.ui_detach(ns) + vim.fn.complete(1, {'food', 'foobar', 'foo'}) + ]] + + screen:expect{grid=[[ + food^ | + {3:food }{1: }| + {4:foobar }{1: }| + {4:foo }{1: }| + {2:-- INSERT --} | + ]]} + expect_events { + } + + end) + + it('does not crash on exit', function() + helpers.funcs.system({ + helpers.nvim_prog, + '-u', 'NONE', + '-i', 'NONE', + '--cmd', [[ lua ns = vim.api.nvim_create_namespace 'testspace' ]], + '--cmd', [[ lua vim.ui_attach(ns, {ext_popupmenu=true}, function() end) ]], + '--cmd', 'quitall!', + }) + eq(0, helpers.eval('v:shell_error')) + end) +end) diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua index 4635f17557..2cb0b26c6d 100644 --- a/test/functional/lua/uri_spec.lua +++ b/test/functional/lua/uri_spec.lua @@ -11,7 +11,7 @@ describe('URI methods', function() describe('file path to uri', function() describe('encode Unix file path', function() - it('file path includes only ascii charactors', function() + it('file path includes only ascii characters', function() exec_lua("filepath = '/Foo/Bar/Baz.txt'") eq('file:///Foo/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) @@ -23,7 +23,7 @@ describe('URI methods', function() eq('file:///Foo%20/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) end) - it('file path including Unicode charactors', function() + it('file path including Unicode characters', function() exec_lua("filepath = '/xy/åäö/ɧ/汉语/↥/🤦/🦄/å/بِيَّ.txt'") -- The URI encoding should be case-insensitive @@ -32,7 +32,7 @@ describe('URI methods', function() end) describe('encode Windows filepath', function() - it('file path includes only ascii charactors', function() + it('file path includes only ascii characters', function() exec_lua([[filepath = 'C:\\Foo\\Bar\\Baz.txt']]) eq('file:///C:/Foo/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) @@ -44,7 +44,7 @@ describe('URI methods', function() eq('file:///C:/Foo%20/Bar/Baz.txt', exec_lua("return vim.uri_from_fname(filepath)")) end) - it('file path including Unicode charactors', function() + it('file path including Unicode characters', function() exec_lua([[filepath = 'C:\\xy\\åäö\\ɧ\\汉语\\↥\\🤦\\🦄\\å\\بِيَّ.txt']]) eq('file:///C:/xy/%c3%a5%c3%a4%c3%b6/%c9%a7/%e6%b1%89%e8%af%ad/%e2%86%a5/%f0%9f%a4%a6/%f0%9f%a6%84/a%cc%8a/%d8%a8%d9%90%d9%8a%d9%8e%d9%91.txt', exec_lua("return vim.uri_from_fname(filepath)")) @@ -72,7 +72,7 @@ describe('URI methods', function() eq('/Foo /Bar/Baz.txt', exec_lua("return vim.uri_to_fname(uri)")) end) - it('file path including Unicode charactors', function() + it('file path including Unicode characters', function() local test_case = [[ local uri = 'file:///xy/%C3%A5%C3%A4%C3%B6/%C9%A7/%E6%B1%89%E8%AF%AD/%E2%86%A5/%F0%9F%A4%A6/%F0%9F%A6%84/a%CC%8A/%D8%A8%D9%90%D9%8A%D9%8E%D9%91.txt' return vim.uri_to_fname(uri) @@ -83,7 +83,7 @@ describe('URI methods', function() end) describe('decode Windows filepath', function() - it('file path includes only ascii charactors', function() + it('file path includes only ascii characters', function() local test_case = [[ local uri = 'file:///C:/Foo/Bar/Baz.txt' return vim.uri_to_fname(uri) @@ -119,7 +119,7 @@ describe('URI methods', function() eq('C:\\Foo \\Bar\\Baz.txt', exec_lua(test_case)) end) - it('file path including Unicode charactors', function() + it('file path including Unicode characters', function() local test_case = [[ local uri = 'file:///C:/xy/%C3%A5%C3%A4%C3%B6/%C9%A7/%E6%B1%89%E8%AF%AD/%E2%86%A5/%F0%9F%A4%A6/%F0%9F%A6%84/a%CC%8A/%D8%A8%D9%90%D9%8A%D9%8E%D9%91.txt' return vim.uri_to_fname(uri) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 2b249b7a69..47a0004183 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -24,6 +24,7 @@ local rmdir = helpers.rmdir local write_file = helpers.write_file local expect_exit = helpers.expect_exit local poke_eventloop = helpers.poke_eventloop +local assert_alive = helpers.assert_alive describe('lua stdlib', function() before_each(clear) @@ -158,17 +159,20 @@ describe('lua stdlib', function() end) it("vim.str_utfindex/str_byteindex", function() - exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) - local indicies32 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,29,33,34,35,37,38,40,42,44,46,48} - local indicies16 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,28,29,33,33,34,35,37,38,40,42,44,46,48} + exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ\000ъ"]]) + local indicies32 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,29,33,34,35,37,38,40,42,44,46,48,49,51} + local indicies16 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,28,29,33,33,34,35,37,38,40,42,44,46,48,49,51} for i,k in pairs(indicies32) do eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ...)", i), i) end for i,k in pairs(indicies16) do eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ..., true)", i), i) end + matches(": index out of range$", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ...)", #indicies32 + 1)) + matches(": index out of range$", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ..., true)", #indicies16 + 1)) local i32, i16 = 0, 0 - for k = 0,48 do + local len = 51 + for k = 0,len do if indicies32[i32] < k then i32 = i32 + 1 end @@ -180,6 +184,7 @@ describe('lua stdlib', function() end eq({i32, i16}, exec_lua("return {vim.str_utfindex(_G.test_text, ...)}", k), k) end + matches(": index out of range$", pcall_err(exec_lua, "return vim.str_utfindex(_G.test_text, ...)", len + 1)) end) it("vim.str_utf_start", function() @@ -788,6 +793,11 @@ describe('lua stdlib', function() local x = vim.fn.VarArg(function() return 'foo' end, function() return 'bar' end) return #x == 2 and x[1]() == 'foo' and x[2]() == 'bar' ]])) + + -- Test for #20211 + eq('a (b) c', exec_lua([[ + return vim.fn.substitute('a b c', 'b', function(m) return '(' .. m[1] .. ')' end, 'g') + ]])) end) it('vim.fn should error when calling API function', function() @@ -896,7 +906,7 @@ describe('lua stdlib', function() ]])) -- vim.empty_dict() gives new value each time - -- equality is not overriden (still by ref) + -- equality is not overridden (still by ref) -- non-empty table uses the usual heuristics (ignores the tag) eq({false, {"foo"}, {namey="bar"}}, exec_lua([[ local aa = vim.empty_dict() @@ -1029,6 +1039,7 @@ describe('lua stdlib', function() vim.g.AddCounter = add_counter vim.g.GetCounter = get_counter vim.g.funcs = {add = add_counter, get = get_counter} + vim.g.AddParens = function(s) return '(' .. s .. ')' end ]] eq(0, eval('g:GetCounter()')) @@ -1044,6 +1055,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.g.funcs.get()]])) exec_lua([[vim.api.nvim_get_var('funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_get_var('funcs').get()]])) + eq('((foo))', eval([['foo'->AddParens()->AddParens()]])) exec_lua [[ local counter = 0 @@ -1052,6 +1064,7 @@ describe('lua stdlib', function() vim.api.nvim_set_var('AddCounter', add_counter) vim.api.nvim_set_var('GetCounter', get_counter) vim.api.nvim_set_var('funcs', {add = add_counter, get = get_counter}) + vim.api.nvim_set_var('AddParens', function(s) return '(' .. s .. ')' end) ]] eq(0, eval('g:GetCounter()')) @@ -1067,6 +1080,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.g.funcs.get()]])) exec_lua([[vim.api.nvim_get_var('funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_get_var('funcs').get()]])) + eq('((foo))', eval([['foo'->AddParens()->AddParens()]])) exec([[ function Test() @@ -1133,6 +1147,7 @@ describe('lua stdlib', function() vim.b.AddCounter = add_counter vim.b.GetCounter = get_counter vim.b.funcs = {add = add_counter, get = get_counter} + vim.b.AddParens = function(s) return '(' .. s .. ')' end ]] eq(0, eval('b:GetCounter()')) @@ -1148,6 +1163,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.b.funcs.get()]])) exec_lua([[vim.api.nvim_buf_get_var(0, 'funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'funcs').get()]])) + eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]])) exec_lua [[ local counter = 0 @@ -1156,6 +1172,7 @@ describe('lua stdlib', function() vim.api.nvim_buf_set_var(0, 'AddCounter', add_counter) vim.api.nvim_buf_set_var(0, 'GetCounter', get_counter) vim.api.nvim_buf_set_var(0, 'funcs', {add = add_counter, get = get_counter}) + vim.api.nvim_buf_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end) ]] eq(0, eval('b:GetCounter()')) @@ -1171,6 +1188,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.b.funcs.get()]])) exec_lua([[vim.api.nvim_buf_get_var(0, 'funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_buf_get_var(0, 'funcs').get()]])) + eq('((foo))', eval([['foo'->b:AddParens()->b:AddParens()]])) exec([[ function Test() @@ -1227,6 +1245,7 @@ describe('lua stdlib', function() vim.w.AddCounter = add_counter vim.w.GetCounter = get_counter vim.w.funcs = {add = add_counter, get = get_counter} + vim.w.AddParens = function(s) return '(' .. s .. ')' end ]] eq(0, eval('w:GetCounter()')) @@ -1242,6 +1261,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.w.funcs.get()]])) exec_lua([[vim.api.nvim_win_get_var(0, 'funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'funcs').get()]])) + eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]])) exec_lua [[ local counter = 0 @@ -1250,6 +1270,7 @@ describe('lua stdlib', function() vim.api.nvim_win_set_var(0, 'AddCounter', add_counter) vim.api.nvim_win_set_var(0, 'GetCounter', get_counter) vim.api.nvim_win_set_var(0, 'funcs', {add = add_counter, get = get_counter}) + vim.api.nvim_win_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end) ]] eq(0, eval('w:GetCounter()')) @@ -1265,6 +1286,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.w.funcs.get()]])) exec_lua([[vim.api.nvim_win_get_var(0, 'funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_win_get_var(0, 'funcs').get()]])) + eq('((foo))', eval([['foo'->w:AddParens()->w:AddParens()]])) exec([[ function Test() @@ -1316,6 +1338,7 @@ describe('lua stdlib', function() vim.t.AddCounter = add_counter vim.t.GetCounter = get_counter vim.t.funcs = {add = add_counter, get = get_counter} + vim.t.AddParens = function(s) return '(' .. s .. ')' end ]] eq(0, eval('t:GetCounter()')) @@ -1331,6 +1354,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.t.funcs.get()]])) exec_lua([[vim.api.nvim_tabpage_get_var(0, 'funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'funcs').get()]])) + eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]])) exec_lua [[ local counter = 0 @@ -1339,6 +1363,7 @@ describe('lua stdlib', function() vim.api.nvim_tabpage_set_var(0, 'AddCounter', add_counter) vim.api.nvim_tabpage_set_var(0, 'GetCounter', get_counter) vim.api.nvim_tabpage_set_var(0, 'funcs', {add = add_counter, get = get_counter}) + vim.api.nvim_tabpage_set_var(0, 'AddParens', function(s) return '(' .. s .. ')' end) ]] eq(0, eval('t:GetCounter()')) @@ -1354,6 +1379,7 @@ describe('lua stdlib', function() eq(5, exec_lua([[return vim.t.funcs.get()]])) exec_lua([[vim.api.nvim_tabpage_get_var(0, 'funcs').add()]]) eq(6, exec_lua([[return vim.api.nvim_tabpage_get_var(0, 'funcs').get()]])) + eq('((foo))', eval([['foo'->t:AddParens()->t:AddParens()]])) exec_lua [[ vim.cmd "tabnew" @@ -1365,11 +1391,23 @@ describe('lua stdlib', function() end) it('vim.env', function() - exec_lua [[ - vim.fn.setenv("A", 123) - ]] - eq('123', funcs.luaeval "vim.env.A") - eq(true, funcs.luaeval "vim.env.B == nil") + exec_lua([[vim.fn.setenv('A', 123)]]) + eq('123', funcs.luaeval('vim.env.A')) + exec_lua([[vim.env.A = 456]]) + eq('456', funcs.luaeval('vim.env.A')) + exec_lua([[vim.env.A = nil]]) + eq(NIL, funcs.luaeval('vim.env.A')) + + eq(true, funcs.luaeval('vim.env.B == nil')) + + command([[let $HOME = 'foo']]) + eq('foo', funcs.expand('~')) + eq('foo', funcs.luaeval('vim.env.HOME')) + exec_lua([[vim.env.HOME = nil]]) + eq('foo', funcs.expand('~')) + exec_lua([[vim.env.HOME = 'bar']]) + eq('bar', funcs.expand('~')) + eq('bar', funcs.luaeval('vim.env.HOME')) end) it('vim.v', function() @@ -1396,7 +1434,7 @@ describe('lua stdlib', function() ]] eq('', funcs.luaeval "vim.bo.filetype") eq(true, funcs.luaeval "vim.bo[BUF].modifiable") - matches("unknown option 'nosuchopt'$", + matches("no such option: 'nosuchopt'$", pcall_err(exec_lua, 'return vim.bo.nosuchopt')) matches("Expected lua string$", pcall_err(exec_lua, 'return vim.bo[0][0].autoread')) @@ -1417,7 +1455,7 @@ describe('lua stdlib', function() eq(0, funcs.luaeval "vim.wo.cole") eq(0, funcs.luaeval "vim.wo[0].cole") eq(0, funcs.luaeval "vim.wo[1001].cole") - matches("unknown option 'notanopt'$", + matches("no such option: 'notanopt'$", pcall_err(exec_lua, 'return vim.wo.notanopt')) matches("Expected lua string$", pcall_err(exec_lua, 'return vim.wo[0][0].list')) @@ -2173,6 +2211,10 @@ describe('lua stdlib', function() eq({3,7}, exec_lua[[return {re1:match_line(0, 1, 1, 8)}]]) eq({}, exec_lua[[return {re1:match_line(0, 1, 1, 7)}]]) eq({0,3}, exec_lua[[return {re1:match_line(0, 1, 0, 7)}]]) + + -- vim.regex() error inside :silent! should not crash. #20546 + command([[silent! lua vim.regex('\\z')]]) + assert_alive() end) it('vim.defer_fn', function() @@ -2721,6 +2763,57 @@ describe('lua stdlib', function() ]] end) end) + + describe('vim.iconv', function() + it('can convert strings', function() + eq('hello', exec_lua[[ + return vim.iconv('hello', 'latin1', 'utf-8') + ]]) + end) + + it('can validate arguments', function() + eq({false, 'Expected at least 3 arguments'}, exec_lua[[ + return {pcall(vim.iconv, 'hello')} + ]]) + + eq({false, 'bad argument #3 to \'?\' (expected string)'}, exec_lua[[ + return {pcall(vim.iconv, 'hello', 'utf-8', true)} + ]]) + end) + + it('can handle bad encodings', function() + eq(NIL, exec_lua[[ + return vim.iconv('hello', 'foo', 'bar') + ]]) + end) + + it('can handle strings with NUL bytes', function() + eq(7, exec_lua[[ + local a = string.char(97, 98, 99, 0, 100, 101, 102) -- abc\0def + return string.len(vim.iconv(a, 'latin1', 'utf-8')) + ]]) + end) + + end) + + describe("vim.defaulttable", function() + it("creates nested table by default", function() + eq({ b = {c = 1 } }, exec_lua[[ + local a = vim.defaulttable() + a.b.c = 1 + return a + ]]) + end) + + it("allows to create default objects", function() + eq({ b = 1 }, exec_lua[[ + local a = vim.defaulttable(function() return 0 end) + a.b = a.b + 1 + return a + ]]) + end) + end) + end) describe('lua: builtin modules', function() |