aboutsummaryrefslogtreecommitdiff
path: root/test/functional/lua/vim_spec.lua
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /test/functional/lua/vim_spec.lua
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.gz
rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.bz2
rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.zip
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'test/functional/lua/vim_spec.lua')
-rw-r--r--test/functional/lua/vim_spec.lua264
1 files changed, 224 insertions, 40 deletions
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 2b249b7a69..867f366d06 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -2,6 +2,7 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
+local nvim_prog = helpers.nvim_prog
local funcs = helpers.funcs
local meths = helpers.meths
local command = helpers.command
@@ -22,8 +23,8 @@ local remove_trace = helpers.remove_trace
local mkdir_p = helpers.mkdir_p
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,28 +159,32 @@ 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}
- for i,k in pairs(indicies32) do
+ exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ\000ъ"]])
+ local indices32 = {[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 indices16 = {[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(indices32) do
eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ...)", i), i)
end
- for i,k in pairs(indicies16) do
+ for i,k in pairs(indices16) do
eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ..., true)", i), i)
end
+ eq("index out of range", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ...)", #indices32 + 1))
+ eq("index out of range", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ..., true)", #indices16 + 1))
local i32, i16 = 0, 0
- for k = 0,48 do
- if indicies32[i32] < k then
+ local len = 51
+ for k = 0,len do
+ if indices32[i32] < k then
i32 = i32 + 1
end
- if indicies16[i16] < k then
+ if indices16[i16] < k then
i16 = i16 + 1
- if indicies16[i16+1] == indicies16[i16] then
+ if indices16[i16+1] == indices16[i16] then
i16 = i16 + 1
end
end
eq({i32, i16}, exec_lua("return {vim.str_utfindex(_G.test_text, ...)}", k), k)
end
+ eq("index out of range", pcall_err(exec_lua, "return vim.str_utfindex(_G.test_text, ...)", len + 1))
end)
it("vim.str_utf_start", function()
@@ -414,6 +419,12 @@ describe('lua stdlib', function()
return getmetatable(t2) == mt
]]))
+ ok(exec_lua([[
+ local t1 = {a = vim.NIL}
+ local t2 = vim.deepcopy(t1)
+ return t2.a == vim.NIL
+ ]]))
+
matches('Cannot deepcopy object of type thread',
pcall_err(exec_lua, [[
local thread = coroutine.create(function () return 0 end)
@@ -425,6 +436,8 @@ describe('lua stdlib', function()
it('vim.pesc', function()
eq('foo%-bar', exec_lua([[return vim.pesc('foo-bar')]]))
eq('foo%%%-bar', exec_lua([[return vim.pesc(vim.pesc('foo-bar'))]]))
+ -- pesc() returns one result. #20751
+ eq({'x'}, exec_lua([[return {vim.pesc('x')}]]))
-- Validates args.
matches('s: expected string, got number',
@@ -499,6 +512,8 @@ describe('lua stdlib', function()
eq(NIL, exec_lua("return vim.tbl_get({ unindexable = function () end }, 'unindexable', 'missing_key')"))
eq(NIL, exec_lua("return vim.tbl_get({}, 'missing_key')"))
eq(NIL, exec_lua("return vim.tbl_get({})"))
+ eq(1, exec_lua("return select('#', vim.tbl_get({}))"))
+ eq(1, exec_lua("return select('#', vim.tbl_get({ nested = {} }, 'nested', 'missing_key'))"))
end)
it('vim.tbl_extend', function()
@@ -748,6 +763,20 @@ describe('lua stdlib', function()
pcall_err(exec_lua, code))
end)
+ it('vim.spairs', function()
+ local res = ''
+ local table = {
+ ccc=1,
+ bbb=2,
+ ddd=3,
+ aaa=4
+ }
+ for key, _ in vim.spairs(table) do
+ res = res .. key
+ end
+ matches('aaabbbcccddd', res)
+ end)
+
it('vim.call, vim.fn', function()
eq(true, exec_lua([[return vim.call('sin', 0.0) == 0.0 ]]))
eq(true, exec_lua([[return vim.fn.sin(0.0) == 0.0 ]]))
@@ -788,6 +817,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 +930,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()
@@ -1006,11 +1040,11 @@ describe('lua stdlib', function()
eq('hi', funcs.luaeval "vim.g.testing")
eq(123, funcs.luaeval "vim.g.other")
eq(5120.1, funcs.luaeval "vim.g.floaty")
- eq(NIL, funcs.luaeval "vim.g.nonexistant")
+ eq(NIL, funcs.luaeval "vim.g.nonexistent")
eq(NIL, funcs.luaeval "vim.g.nullvar")
-- lost over RPC, so test locally:
eq({false, true}, exec_lua [[
- return {vim.g.nonexistant == vim.NIL, vim.g.nullvar == vim.NIL}
+ return {vim.g.nonexistent == vim.NIL, vim.g.nullvar == vim.NIL}
]])
eq({hello="world"}, funcs.luaeval "vim.g.to_delete")
@@ -1029,6 +1063,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 +1079,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 +1088,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 +1104,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()
@@ -1109,12 +1147,12 @@ describe('lua stdlib', function()
eq('bye', funcs.luaeval "vim.b[BUF].testing")
eq(123, funcs.luaeval "vim.b.other")
eq(5120.1, funcs.luaeval "vim.b.floaty")
- eq(NIL, funcs.luaeval "vim.b.nonexistant")
- eq(NIL, funcs.luaeval "vim.b[BUF].nonexistant")
+ eq(NIL, funcs.luaeval "vim.b.nonexistent")
+ eq(NIL, funcs.luaeval "vim.b[BUF].nonexistent")
eq(NIL, funcs.luaeval "vim.b.nullvar")
-- lost over RPC, so test locally:
eq({false, true}, exec_lua [[
- return {vim.b.nonexistant == vim.NIL, vim.b.nullvar == vim.NIL}
+ return {vim.b.nonexistent == vim.NIL, vim.b.nullvar == vim.NIL}
]])
matches([[attempt to index .* nil value]],
@@ -1133,6 +1171,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 +1187,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 +1196,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 +1212,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()
@@ -1189,7 +1231,7 @@ describe('lua stdlib', function()
eq(NIL, funcs.luaeval "vim.b.testing")
eq(NIL, funcs.luaeval "vim.b.other")
- eq(NIL, funcs.luaeval "vim.b.nonexistant")
+ eq(NIL, funcs.luaeval "vim.b.nonexistent")
end)
it('vim.w', function()
@@ -1208,8 +1250,8 @@ describe('lua stdlib', function()
eq('hi', funcs.luaeval "vim.w.testing")
eq('bye', funcs.luaeval "vim.w[WIN].testing")
eq(123, funcs.luaeval "vim.w.other")
- eq(NIL, funcs.luaeval "vim.w.nonexistant")
- eq(NIL, funcs.luaeval "vim.w[WIN].nonexistant")
+ eq(NIL, funcs.luaeval "vim.w.nonexistent")
+ eq(NIL, funcs.luaeval "vim.w[WIN].nonexistent")
matches([[attempt to index .* nil value]],
pcall_err(exec_lua, 'return vim.w[WIN][0].testing'))
@@ -1227,6 +1269,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 +1285,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 +1294,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 +1310,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()
@@ -1283,7 +1329,7 @@ describe('lua stdlib', function()
eq(NIL, funcs.luaeval "vim.w.testing")
eq(NIL, funcs.luaeval "vim.w.other")
- eq(NIL, funcs.luaeval "vim.w.nonexistant")
+ eq(NIL, funcs.luaeval "vim.w.nonexistent")
end)
it('vim.t', function()
@@ -1295,10 +1341,10 @@ describe('lua stdlib', function()
eq('hi', funcs.luaeval "vim.t.testing")
eq(123, funcs.luaeval "vim.t.other")
- eq(NIL, funcs.luaeval "vim.t.nonexistant")
+ eq(NIL, funcs.luaeval "vim.t.nonexistent")
eq('hi', funcs.luaeval "vim.t[0].testing")
eq(123, funcs.luaeval "vim.t[0].other")
- eq(NIL, funcs.luaeval "vim.t[0].nonexistant")
+ eq(NIL, funcs.luaeval "vim.t[0].nonexistent")
matches([[attempt to index .* nil value]],
pcall_err(exec_lua, 'return vim.t[0][0].testing'))
@@ -1316,6 +1362,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 +1378,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 +1387,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 +1403,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"
@@ -1361,15 +1411,27 @@ describe('lua stdlib', function()
eq(NIL, funcs.luaeval "vim.t.testing")
eq(NIL, funcs.luaeval "vim.t.other")
- eq(NIL, funcs.luaeval "vim.t.nonexistant")
+ eq(NIL, funcs.luaeval "vim.t.nonexistent")
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 +1458,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 +1479,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'))
@@ -2141,6 +2203,22 @@ describe('lua stdlib', function()
end)
end) -- vim.opt
+ describe('opt_local', function()
+ it('should be able to append to an array list type option', function()
+ eq({ "foo,bar,baz,qux" }, exec_lua [[
+ local result = {}
+
+ vim.opt.tags = "foo,bar"
+ vim.opt_local.tags:append("baz")
+ vim.opt_local.tags:append("qux")
+
+ table.insert(result, vim.bo.tags)
+
+ return result
+ ]])
+ end)
+ end)
+
it('vim.cmd', function()
exec_lua [[
vim.cmd "autocmd BufNew * ++once lua BUF = vim.fn.expand('<abuf>')"
@@ -2173,6 +2251,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()
@@ -2185,13 +2267,19 @@ describe('lua stdlib', function()
eq(true, exec_lua[[return vim.g.test]])
end)
- it('vim.region', function()
- insert(helpers.dedent( [[
- text tααt tααt text
- text tαxt txtα tex
- text tαxt tαxt
- ]]))
- eq({5,15}, exec_lua[[ return vim.region(0,{1,5},{1,14},'v',true)[1] ]])
+ describe('vim.region', function()
+ it('charwise', function()
+ insert(helpers.dedent( [[
+ text tααt tααt text
+ text tαxt txtα tex
+ text tαxt tαxt
+ ]]))
+ eq({5,15}, exec_lua[[ return vim.region(0,{1,5},{1,14},'v',true)[1] ]])
+ end)
+ it('blockwise', function()
+ insert([[αα]])
+ eq({0,5}, exec_lua[[ return vim.region(0,{0,0},{0,4},'3',true)[0] ]])
+ end)
end)
describe('vim.on_key', function()
@@ -2623,6 +2711,46 @@ describe('lua stdlib', function()
a.nvim_buf_call(a.nvim_create_buf(false, true), function() vim.cmd "redraw" end)
]]
end)
+
+ it('can be nested crazily with hidden buffers', function()
+ eq(true, exec_lua([[
+ local function scratch_buf_call(fn)
+ local buf = vim.api.nvim_create_buf(false, true)
+ vim.api.nvim_buf_set_option(buf, 'cindent', true)
+ return vim.api.nvim_buf_call(buf, function()
+ return vim.api.nvim_get_current_buf() == buf
+ and vim.api.nvim_buf_get_option(buf, 'cindent')
+ and fn()
+ end) and vim.api.nvim_buf_delete(buf, {}) == nil
+ end
+
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return scratch_buf_call(function()
+ return true
+ end)
+ end)
+ end)
+ end)
+ end)
+ end)
+ end)
+ end)
+ end)
+ end)
+ end)
+ end)
+ ]]))
+ end)
end)
describe('vim.api.nvim_win_call', function()
@@ -2721,6 +2849,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()
@@ -2745,9 +2924,14 @@ describe('lua: builtin modules', function()
end)
- it('does not work when disabled without runtime', function()
- clear{args={'--luamod-dev'}, env={VIMRUNTIME='fixtures/a'}}
- expect_exit(exec_lua, [[return vim.tbl_count {x=1,y=2}]])
+ it('fails when disabled without runtime', function()
+ clear()
+ command("let $VIMRUNTIME='fixtures/a'")
+ -- Use system([nvim,…]) instead of clear() to avoid stderr noise. #21844
+ local out = funcs.system({nvim_prog, '--clean', '--luamod-dev',
+ [[+call nvim_exec_lua('return vim.tbl_count {x=1,y=2}')]], '+qa!'}):gsub('\r\n', '\n')
+ eq(1, eval('v:shell_error'))
+ matches("'vim%.shared' not found", out)
end)
end)