aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-01-21 01:10:44 +0300
committerZyX <kp-pav@yandex.ru>2017-03-27 00:12:22 +0300
commitbca9c2f3c4af9c132439bbfeaed028ac3171db48 (patch)
tree0e32e3aa620a8b8a201b8c8b0c6bfebbde5489b0
parentf8d55266e461a0a85e17e5adfd33e8429e45d9a5 (diff)
downloadrneovim-bca9c2f3c4af9c132439bbfeaed028ac3171db48.tar.gz
rneovim-bca9c2f3c4af9c132439bbfeaed028ac3171db48.tar.bz2
rneovim-bca9c2f3c4af9c132439bbfeaed028ac3171db48.zip
functests: Move existing tests from lua_spec to lua/*, fix them
-rw-r--r--test/functional/lua/api_spec.lua143
-rw-r--r--test/functional/lua/luaeval_spec.lua181
-rw-r--r--test/functional/lua_spec.lua328
3 files changed, 324 insertions, 328 deletions
diff --git a/test/functional/lua/api_spec.lua b/test/functional/lua/api_spec.lua
index 6652c60adb..31c855c2c1 100644
--- a/test/functional/lua/api_spec.lua
+++ b/test/functional/lua/api_spec.lua
@@ -1,8 +1,10 @@
-- Test suite for testing interactions with API bindings
local helpers = require('test.functional.helpers')(after_each)
+local exc_exec = helpers.exc_exec
local funcs = helpers.funcs
local clear = helpers.clear
+local eval = helpers.eval
local NIL = helpers.NIL
local eq = helpers.eq
@@ -33,4 +35,145 @@ describe('luaeval(vim.api.…)', function()
funcs.luaeval('{pcall(vim.api.nvim_buf_set_lines, 1, 1, 2, false, {"b\\na"})}'))
end)
end)
+
+ it('correctly converts from API objects', function()
+ eq(1, funcs.luaeval('vim.api.nvim_eval("1")'))
+ eq('1', funcs.luaeval([[vim.api.nvim_eval('"1"')]]))
+ eq({}, funcs.luaeval('vim.api.nvim_eval("[]")'))
+ eq({}, funcs.luaeval('vim.api.nvim_eval("{}")'))
+ eq(1, funcs.luaeval('vim.api.nvim_eval("1.0")'))
+ eq(true, funcs.luaeval('vim.api.nvim_eval("v:true")'))
+ eq(false, funcs.luaeval('vim.api.nvim_eval("v:false")'))
+ eq(NIL, funcs.luaeval('vim.api.nvim_eval("v:null")'))
+
+ eq(0, eval([[type(luaeval('vim.api.nvim_eval("1")'))]]))
+ eq(1, eval([[type(luaeval('vim.api.nvim_eval("''1''")'))]]))
+ eq(3, eval([[type(luaeval('vim.api.nvim_eval("[]")'))]]))
+ eq(4, eval([[type(luaeval('vim.api.nvim_eval("{}")'))]]))
+ eq(5, eval([[type(luaeval('vim.api.nvim_eval("1.0")'))]]))
+ eq(6, eval([[type(luaeval('vim.api.nvim_eval("v:true")'))]]))
+ eq(6, eval([[type(luaeval('vim.api.nvim_eval("v:false")'))]]))
+ eq(7, eval([[type(luaeval('vim.api.nvim_eval("v:null")'))]]))
+
+ eq({foo=42}, funcs.luaeval([[vim.api.nvim_eval('{"foo": 42}')]]))
+ eq({42}, funcs.luaeval([[vim.api.nvim_eval('[42]')]]))
+
+ eq({foo={bar=42}, baz=50}, funcs.luaeval([[vim.api.nvim_eval('{"foo": {"bar": 42}, "baz": 50}')]]))
+ eq({{42}, {}}, funcs.luaeval([=[vim.api.nvim_eval('[[42], []]')]=]))
+ end)
+
+ it('correctly converts to API objects', function()
+ eq(1, funcs.luaeval('vim.api._vim_id(1)'))
+ eq('1', funcs.luaeval('vim.api._vim_id("1")'))
+ eq({1}, funcs.luaeval('vim.api._vim_id({1})'))
+ eq({foo=1}, funcs.luaeval('vim.api._vim_id({foo=1})'))
+ eq(1.5, funcs.luaeval('vim.api._vim_id(1.5)'))
+ eq(true, funcs.luaeval('vim.api._vim_id(true)'))
+ eq(false, funcs.luaeval('vim.api._vim_id(false)'))
+ eq(NIL, funcs.luaeval('vim.api._vim_id(nil)'))
+
+ eq(0, eval([[type(luaeval('vim.api._vim_id(1)'))]]))
+ eq(1, eval([[type(luaeval('vim.api._vim_id("1")'))]]))
+ eq(3, eval([[type(luaeval('vim.api._vim_id({1})'))]]))
+ eq(4, eval([[type(luaeval('vim.api._vim_id({foo=1})'))]]))
+ eq(5, eval([[type(luaeval('vim.api._vim_id(1.5)'))]]))
+ eq(6, eval([[type(luaeval('vim.api._vim_id(true)'))]]))
+ eq(6, eval([[type(luaeval('vim.api._vim_id(false)'))]]))
+ eq(7, eval([[type(luaeval('vim.api._vim_id(nil)'))]]))
+
+ eq({foo=1, bar={42, {{baz=true}, 5}}}, funcs.luaeval('vim.api._vim_id({foo=1, bar={42, {{baz=true}, 5}}})'))
+ end)
+
+ it('correctly converts container objects with type_idx to API objects', function()
+ eq(5, eval('type(luaeval("vim.api._vim_id({[vim.type_idx]=vim.types.float, [vim.val_idx]=0})"))'))
+ eq(4, eval([[type(luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.dictionary})'))]]))
+ eq(3, eval([[type(luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array})'))]]))
+
+ eq({}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array})'))
+
+ -- Presence of type_idx makes Vim ignore some keys
+ eq({42}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
+ eq({foo=2}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
+ eq(10, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
+ eq({}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})'))
+ end)
+
+ it('correctly converts arrays with type_idx to API objects', function()
+ eq(3, eval([[type(luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array})'))]]))
+
+ eq({}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array})'))
+
+ eq({42}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
+ eq({{foo=2}}, funcs.luaeval('vim.api._vim_id_array({{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
+ eq({10}, funcs.luaeval('vim.api._vim_id_array({{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
+ eq({}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})'))
+
+ eq({}, funcs.luaeval('vim.api._vim_id_array({})'))
+ eq(3, eval([[type(luaeval('vim.api._vim_id_array({})'))]]))
+ end)
+
+ it('correctly converts dictionaries with type_idx to API objects', function()
+ eq(4, eval([[type(luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary})'))]]))
+
+ eq({}, funcs.luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary})'))
+
+ eq({v={42}}, funcs.luaeval('vim.api._vim_id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
+ eq({foo=2}, funcs.luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
+ eq({v=10}, funcs.luaeval('vim.api._vim_id_dictionary({v={[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
+ eq({v={}}, funcs.luaeval('vim.api._vim_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.
+ eq({}, funcs.luaeval('vim.api._vim_id_dictionary({})'))
+ eq(4, eval([[type(luaeval('vim.api._vim_id_dictionary({})'))]]))
+ end)
+
+ it('errors out correctly when working with API', function()
+ -- Conversion errors
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Cannot convert given lua type',
+ exc_exec([[call luaeval("vim.api._vim_id(vim.api._vim_id)")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Cannot convert given lua table',
+ exc_exec([[call luaeval("vim.api._vim_id({1, foo=42})")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Cannot convert given lua type',
+ exc_exec([[call luaeval("vim.api._vim_id({42, vim.api._vim_id})")]]))
+ -- Errors in number of arguments
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected 1 argument',
+ exc_exec([[call luaeval("vim.api._vim_id()")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected 1 argument',
+ exc_exec([[call luaeval("vim.api._vim_id(1, 2)")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected 2 arguments',
+ exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2, 3)")]]))
+ -- Error in argument types
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua string',
+ exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2)")]]))
+
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua number',
+ exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 'test', 1, false)")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Number is not integral',
+ exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 1.5, 1, false)")]]))
+
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua table',
+ exc_exec([[call luaeval("vim.api._vim_id_float('test')")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Unexpected type',
+ exc_exec([[call luaeval("vim.api._vim_id_float({[vim.type_idx]=vim.types.dictionary})")]]))
+
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua table',
+ exc_exec([[call luaeval("vim.api._vim_id_array(1)")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Unexpected type',
+ exc_exec([[call luaeval("vim.api._vim_id_array({[vim.type_idx]=vim.types.dictionary})")]]))
+
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Expected lua table',
+ exc_exec([[call luaeval("vim.api._vim_id_dictionary(1)")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: Unexpected type',
+ exc_exec([[call luaeval("vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.array})")]]))
+ -- TODO: check for errors with Tabpage argument
+ -- TODO: check for errors with Window argument
+ -- TODO: check for errors with Buffer argument
+ end)
+
+ it('accepts any value as API Boolean', function()
+ eq('', funcs.luaeval('vim.api.nvim_replace_termcodes("", vim, false, nil)'))
+ eq('', funcs.luaeval('vim.api.nvim_replace_termcodes("", 0, 1.5, "test")'))
+ eq('', funcs.luaeval('vim.api.nvim_replace_termcodes("", true, {}, {[vim.type_idx]=vim.types.array})'))
+ end)
end)
diff --git a/test/functional/lua/luaeval_spec.lua b/test/functional/lua/luaeval_spec.lua
index 5b7f365ef3..345848cfff 100644
--- a/test/functional/lua/luaeval_spec.lua
+++ b/test/functional/lua/luaeval_spec.lua
@@ -1,16 +1,37 @@
-- Test suite for testing luaeval() function
local helpers = require('test.functional.helpers')(after_each)
+local redir_exec = helpers.redir_exec
+local exc_exec = helpers.exc_exec
local command = helpers.command
local meths = helpers.meths
local funcs = helpers.funcs
local clear = helpers.clear
+local eval = helpers.eval
local NIL = helpers.NIL
local eq = helpers.eq
before_each(clear)
+local function startswith(expected, actual)
+ eq(expected, actual:sub(1, #expected))
+end
+
describe('luaeval()', function()
+ local nested_by_level = {}
+ local nested = {}
+ local nested_s = '{}'
+ for i=1,100 do
+ if i % 2 == 0 then
+ nested = {nested}
+ nested_s = '{' .. nested_s .. '}'
+ else
+ nested = {nested=nested}
+ nested_s = '{nested=' .. nested_s .. '}'
+ end
+ nested_by_level[i] = {o=nested, s=nested_s}
+ end
+
describe('second argument', function()
it('is successfully received', function()
local t = {t=true, f=false, --[[n=NIL,]] d={l={'string', 42, 0.42}}}
@@ -60,4 +81,164 @@ describe('luaeval()', function()
eq(1, funcs.eval('l[2]._TYPE is v:msgpack_types.binary'))
end)
end)
+
+ -- Not checked: funcrefs converted to NIL. To be altered to something more
+ -- meaningful later.
+
+ it('correctly evaluates scalars', function()
+ eq(1, funcs.luaeval('1'))
+ eq(0, eval('type(luaeval("1"))'))
+
+ eq(1.5, funcs.luaeval('1.5'))
+ eq(5, eval('type(luaeval("1.5"))'))
+
+ eq("test", funcs.luaeval('"test"'))
+ eq(1, eval('type(luaeval("\'test\'"))'))
+
+ eq('', funcs.luaeval('""'))
+ eq({_TYPE={}, _VAL={'\n'}}, funcs.luaeval([['\0']]))
+ eq({_TYPE={}, _VAL={'\n', '\n'}}, funcs.luaeval([['\0\n\0']]))
+ eq(1, eval([[luaeval('"\0\n\0"')._TYPE is v:msgpack_types.binary]]))
+
+ eq(true, funcs.luaeval('true'))
+ eq(false, funcs.luaeval('false'))
+ eq(NIL, funcs.luaeval('nil'))
+ end)
+
+ it('correctly evaluates containers', function()
+ eq({}, funcs.luaeval('{}'))
+ eq(3, eval('type(luaeval("{}"))'))
+
+ eq({test=1, foo=2}, funcs.luaeval('{test=1, foo=2}'))
+ eq(4, eval('type(luaeval("{test=1, foo=2}"))'))
+
+ eq({4, 2}, funcs.luaeval('{4, 2}'))
+ eq(3, eval('type(luaeval("{4, 2}"))'))
+
+ local level = 30
+ eq(nested_by_level[level].o, funcs.luaeval(nested_by_level[level].s))
+
+ eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, {_TYPE={}, _VAL={'\n', '\n\n'}}}}},
+ funcs.luaeval([[{['\0\n\0']='\0\n\0\0'}]]))
+ eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._TYPE is v:msgpack_types.map]]))
+ eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0]._TYPE is v:msgpack_types.string]]))
+ eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][1]._TYPE is v:msgpack_types.binary]]))
+ eq({nested={{_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, {_TYPE={}, _VAL={'\n', '\n\n'}}}}}}},
+ funcs.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]]))
+ end)
+
+ it('correctly passes scalars as argument', function()
+ eq(1, funcs.luaeval('_A', 1))
+ eq(1.5, funcs.luaeval('_A', 1.5))
+ eq('', funcs.luaeval('_A', ''))
+ eq('test', funcs.luaeval('_A', 'test'))
+ eq(NIL, funcs.luaeval('_A', NIL))
+ eq(true, funcs.luaeval('_A', true))
+ eq(false, funcs.luaeval('_A', false))
+ end)
+
+ it('correctly passes containers as argument', function()
+ eq({}, funcs.luaeval('_A', {}))
+ eq({test=1}, funcs.luaeval('_A', {test=1}))
+ eq({4, 2}, funcs.luaeval('_A', {4, 2}))
+ local level = 28
+ eq(nested_by_level[level].o, funcs.luaeval('_A', nested_by_level[level].o))
+ end)
+
+ local function sp(typ, val)
+ return ('{"_TYPE": v:msgpack_types.%s, "_VAL": %s}'):format(typ, val)
+ end
+ local function mapsp(...)
+ local val = ''
+ for i=1,(select('#', ...)/2) do
+ val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...),
+ select(i * 2, ...))
+ end
+ return sp('map', '[' .. val .. ']')
+ end
+ local function luaevalarg(argexpr, expr)
+ return eval(([=[
+ [
+ extend(g:, {'_ret': luaeval(%s, %s)})._ret,
+ type(g:_ret)==type({})&&has_key(g:_ret, '_TYPE')
+ ? [
+ get(keys(filter(copy(v:msgpack_types), 'v:val is g:_ret._TYPE')), 0,
+ g:_ret._TYPE),
+ get(g:_ret, '_VAL', g:_ret)
+ ]
+ : [0, g:_ret]][1]
+ ]=]):format(expr or '"_A"', argexpr):gsub('\n', ''))
+ end
+
+ it('correctly passes special dictionaries', function()
+ eq({'binary', {'\n', '\n'}}, luaevalarg(sp('binary', '["\\n", "\\n"]')))
+ eq({'binary', {'\n', '\n'}}, luaevalarg(sp('string', '["\\n", "\\n"]')))
+ eq({0, true}, luaevalarg(sp('boolean', 1)))
+ eq({0, false}, luaevalarg(sp('boolean', 0)))
+ eq({0, NIL}, luaevalarg(sp('nil', 0)))
+ eq({0, {[""]=""}}, luaevalarg(mapsp(sp('binary', '[""]'), '""')))
+ eq({0, {[""]=""}}, luaevalarg(mapsp(sp('string', '[""]'), '""')))
+ end)
+
+ it('issues an error in some cases', function()
+ eq("Vim(call):E5100: Cannot convert given lua table: table should either have a sequence of positive integer keys or contain only string keys",
+ exc_exec('call luaeval("{1, foo=2}")'))
+ eq("Vim(call):E5101: Cannot convert given lua type",
+ exc_exec('call luaeval("vim.api.nvim_buf_get_lines")'))
+ startswith("Vim(call):E5107: Error while creating lua chunk for luaeval(): ",
+ exc_exec('call luaeval("1, 2, 3")'))
+ startswith("Vim(call):E5108: Error while calling lua chunk for luaeval(): ",
+ exc_exec('call luaeval("(nil)()")'))
+ eq("Vim(call):E5101: Cannot convert given lua type",
+ exc_exec('call luaeval("{42, vim.api}")'))
+ eq("Vim(call):E5101: Cannot convert given lua type",
+ exc_exec('call luaeval("{foo=42, baz=vim.api}")'))
+
+ -- The following should not crash: conversion error happens inside
+ eq("Vim(call):E5101: Cannot convert given lua type",
+ exc_exec('call luaeval("vim.api")'))
+ -- The following should not show internal error
+ eq("\nE5101: Cannot convert given lua type\n0",
+ redir_exec('echo luaeval("vim.api")'))
+ end)
+
+ it('correctly converts containers with type_idx', function()
+ eq(5, eval('type(luaeval("{[vim.type_idx]=vim.types.float, [vim.val_idx]=0}"))'))
+ eq(4, eval([[type(luaeval('{[vim.type_idx]=vim.types.dictionary}'))]]))
+ eq(3, eval([[type(luaeval('{[vim.type_idx]=vim.types.array}'))]]))
+
+ eq({}, funcs.luaeval('{[vim.type_idx]=vim.types.array}'))
+
+ -- Presence of type_idx makes Vim ignore some keys
+ eq({42}, funcs.luaeval('{[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}'))
+ eq({foo=2}, funcs.luaeval('{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}'))
+ eq(10, funcs.luaeval('{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}'))
+
+ -- The following should not crash
+ eq({}, funcs.luaeval('{[vim.type_idx]=vim.types.dictionary}'))
+ end)
+
+ it('correctly converts self-containing containers', function()
+ meths.set_var('l', {})
+ eval('add(l, l)')
+ eq(true, eval('luaeval("_A == _A[1]", l)'))
+ eq(true, eval('luaeval("_A[1] == _A[1][1]", [l])'))
+ eq(true, eval('luaeval("_A.d == _A.d[1]", {"d": l})'))
+ eq(true, eval('luaeval("_A ~= _A[1]", [l])'))
+
+ meths.set_var('d', {foo=42})
+ eval('extend(d, {"d": d})')
+ eq(true, eval('luaeval("_A == _A.d", d)'))
+ eq(true, eval('luaeval("_A[1] == _A[1].d", [d])'))
+ eq(true, eval('luaeval("_A.d == _A.d.d", {"d": d})'))
+ eq(true, eval('luaeval("_A ~= _A.d", {"d": d})'))
+ end)
+
+ it('errors out correctly when doing incorrect things in lua', function()
+ -- Conversion errors
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: attempt to call field \'xxx_nonexistent_key_xxx\' (a nil value)',
+ exc_exec([[call luaeval("vim.xxx_nonexistent_key_xxx()")]]))
+ eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): [string "<VimL compiled string>"]:1: ERROR',
+ exc_exec([[call luaeval("error('ERROR')")]]))
+ end)
end)
diff --git a/test/functional/lua_spec.lua b/test/functional/lua_spec.lua
deleted file mode 100644
index 8ca47718aa..0000000000
--- a/test/functional/lua_spec.lua
+++ /dev/null
@@ -1,328 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-
-local eq = helpers.eq
-local neq = helpers.neq
-local NIL = helpers.NIL
-local eval = helpers.eval
-local clear = helpers.clear
-local funcs = helpers.funcs
-local meths = helpers.meths
-local exc_exec = helpers.exc_exec
-local redir_exec = helpers.redir_exec
-
-local function startswith(expected, actual)
- eq(expected, actual:sub(1, #expected))
-end
-
-before_each(clear)
-
-describe('luaeval() function', function()
- local nested_by_level = {}
- local nested = {}
- local nested_s = '{}'
- for i=1,100 do
- if i % 2 == 0 then
- nested = {nested}
- nested_s = '{' .. nested_s .. '}'
- else
- nested = {nested=nested}
- nested_s = '{nested=' .. nested_s .. '}'
- end
- nested_by_level[i] = {o=nested, s=nested_s}
- end
-
- -- Not checked: funcrefs converted to NIL. To be altered to something more
- -- meaningful later.
-
- it('correctly evaluates scalars', function()
- eq(1, funcs.luaeval('1'))
- eq(0, eval('type(luaeval("1"))'))
-
- eq(1.5, funcs.luaeval('1.5'))
- eq(5, eval('type(luaeval("1.5"))'))
-
- eq("test", funcs.luaeval('"test"'))
- eq(1, eval('type(luaeval("\'test\'"))'))
-
- eq('', funcs.luaeval('""'))
- eq({_TYPE={}, _VAL={'\n'}}, funcs.luaeval([['\0']]))
- eq({_TYPE={}, _VAL={'\n', '\n'}}, funcs.luaeval([['\0\n\0']]))
- eq(1, eval([[luaeval('"\0\n\0"')._TYPE is v:msgpack_types.binary]]))
-
- eq(true, funcs.luaeval('true'))
- eq(false, funcs.luaeval('false'))
- eq(NIL, funcs.luaeval('nil'))
- end)
-
- it('correctly evaluates containers', function()
- eq({}, funcs.luaeval('{}'))
- eq(3, eval('type(luaeval("{}"))'))
-
- eq({test=1, foo=2}, funcs.luaeval('{test=1, foo=2}'))
- eq(4, eval('type(luaeval("{test=1, foo=2}"))'))
-
- eq({4, 2}, funcs.luaeval('{4, 2}'))
- eq(3, eval('type(luaeval("{4, 2}"))'))
-
- local level = 30
- eq(nested_by_level[level].o, funcs.luaeval(nested_by_level[level].s))
-
- eq({_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, {_TYPE={}, _VAL={'\n', '\n\n'}}}}},
- funcs.luaeval([[{['\0\n\0']='\0\n\0\0'}]]))
- eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._TYPE is v:msgpack_types.map]]))
- eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0]._TYPE is v:msgpack_types.string]]))
- eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][1]._TYPE is v:msgpack_types.binary]]))
- eq({nested={{_TYPE={}, _VAL={{{_TYPE={}, _VAL={'\n', '\n'}}, {_TYPE={}, _VAL={'\n', '\n\n'}}}}}}},
- funcs.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]]))
- end)
-
- it('correctly passes scalars as argument', function()
- eq(1, funcs.luaeval('_A', 1))
- eq(1.5, funcs.luaeval('_A', 1.5))
- eq('', funcs.luaeval('_A', ''))
- eq('test', funcs.luaeval('_A', 'test'))
- eq(NIL, funcs.luaeval('_A', NIL))
- eq(true, funcs.luaeval('_A', true))
- eq(false, funcs.luaeval('_A', false))
- end)
-
- it('correctly passes containers as argument', function()
- eq({}, funcs.luaeval('_A', {}))
- eq({test=1}, funcs.luaeval('_A', {test=1}))
- eq({4, 2}, funcs.luaeval('_A', {4, 2}))
- local level = 28
- eq(nested_by_level[level].o, funcs.luaeval('_A', nested_by_level[level].o))
- end)
-
- local function sp(typ, val)
- return ('{"_TYPE": v:msgpack_types.%s, "_VAL": %s}'):format(typ, val)
- end
- local function mapsp(...)
- local val = ''
- for i=1,(select('#', ...)/2) do
- val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...),
- select(i * 2, ...))
- end
- return sp('map', '[' .. val .. ']')
- end
- local function luaevalarg(argexpr, expr)
- return eval(([=[
- [
- extend(g:, {'_ret': luaeval(%s, %s)})._ret,
- type(g:_ret)==type({})&&has_key(g:_ret, '_TYPE')
- ? [
- get(keys(filter(copy(v:msgpack_types), 'v:val is g:_ret._TYPE')), 0,
- g:_ret._TYPE),
- get(g:_ret, '_VAL', g:_ret)
- ]
- : [0, g:_ret]][1]
- ]=]):format(expr or '"_A"', argexpr):gsub('\n', ''))
- end
-
- it('correctly passes special dictionaries', function()
- eq({'binary', {'\n', '\n'}}, luaevalarg(sp('binary', '["\\n", "\\n"]')))
- eq({'binary', {'\n', '\n'}}, luaevalarg(sp('string', '["\\n", "\\n"]')))
- eq({0, true}, luaevalarg(sp('boolean', 1)))
- eq({0, false}, luaevalarg(sp('boolean', 0)))
- eq({0, NIL}, luaevalarg(sp('nil', 0)))
- eq({0, {[""]=""}}, luaevalarg(mapsp(sp('binary', '[""]'), '""')))
- eq({0, {[""]=""}}, luaevalarg(mapsp(sp('string', '[""]'), '""')))
- end)
-
- it('issues an error in some cases', function()
- eq("Vim(call):E5100: Cannot convert given lua table: table should either have a sequence of positive integer keys or contain only string keys",
- exc_exec('call luaeval("{1, foo=2}")'))
- eq("Vim(call):E5101: Cannot convert given lua type",
- exc_exec('call luaeval("vim.api.buffer_get_line_slice")'))
- startswith("Vim(call):E5107: Error while creating lua chunk for luaeval(): ",
- exc_exec('call luaeval("1, 2, 3")'))
- startswith("Vim(call):E5108: Error while calling lua chunk for luaeval(): ",
- exc_exec('call luaeval("(nil)()")'))
- eq("Vim(call):E5101: Cannot convert given lua type",
- exc_exec('call luaeval("{42, vim.api}")'))
- eq("Vim(call):E5101: Cannot convert given lua type",
- exc_exec('call luaeval("{foo=42, baz=vim.api}")'))
-
- -- The following should not crash: conversion error happens inside
- eq("Vim(call):E5101: Cannot convert given lua type",
- exc_exec('call luaeval("vim.api")'))
- -- The following should not show internal error
- eq("\nE5101: Cannot convert given lua type\n0",
- redir_exec('echo luaeval("vim.api")'))
- end)
-
- it('correctly converts containers with type_idx', function()
- eq(5, eval('type(luaeval("{[vim.type_idx]=vim.types.float, [vim.val_idx]=0}"))'))
- eq(4, eval([[type(luaeval('{[vim.type_idx]=vim.types.dictionary}'))]]))
- eq(3, eval([[type(luaeval('{[vim.type_idx]=vim.types.array}'))]]))
-
- eq({}, funcs.luaeval('{[vim.type_idx]=vim.types.array}'))
-
- -- Presence of type_idx makes Vim ignore some keys
- eq({42}, funcs.luaeval('{[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}'))
- eq({foo=2}, funcs.luaeval('{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}'))
- eq(10, funcs.luaeval('{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}'))
-
- -- The following should not crash
- eq({}, funcs.luaeval('{[vim.type_idx]=vim.types.dictionary}'))
- end)
-
- it('correctly converts from API objects', function()
- eq(1, funcs.luaeval('vim.api.vim_eval("1")'))
- eq('1', funcs.luaeval([[vim.api.vim_eval('"1"')]]))
- eq({}, funcs.luaeval('vim.api.vim_eval("[]")'))
- eq({}, funcs.luaeval('vim.api.vim_eval("{}")'))
- eq(1, funcs.luaeval('vim.api.vim_eval("1.0")'))
- eq(true, funcs.luaeval('vim.api.vim_eval("v:true")'))
- eq(false, funcs.luaeval('vim.api.vim_eval("v:false")'))
- eq(NIL, funcs.luaeval('vim.api.vim_eval("v:null")'))
-
- eq(0, eval([[type(luaeval('vim.api.vim_eval("1")'))]]))
- eq(1, eval([[type(luaeval('vim.api.vim_eval("''1''")'))]]))
- eq(3, eval([[type(luaeval('vim.api.vim_eval("[]")'))]]))
- eq(4, eval([[type(luaeval('vim.api.vim_eval("{}")'))]]))
- eq(5, eval([[type(luaeval('vim.api.vim_eval("1.0")'))]]))
- eq(6, eval([[type(luaeval('vim.api.vim_eval("v:true")'))]]))
- eq(6, eval([[type(luaeval('vim.api.vim_eval("v:false")'))]]))
- eq(7, eval([[type(luaeval('vim.api.vim_eval("v:null")'))]]))
-
- eq({foo=42}, funcs.luaeval([[vim.api.vim_eval('{"foo": 42}')]]))
- eq({42}, funcs.luaeval([[vim.api.vim_eval('[42]')]]))
-
- eq({foo={bar=42}, baz=50}, funcs.luaeval([[vim.api.vim_eval('{"foo": {"bar": 42}, "baz": 50}')]]))
- eq({{42}, {}}, funcs.luaeval([=[vim.api.vim_eval('[[42], []]')]=]))
- end)
-
- it('correctly converts to API objects', function()
- eq(1, funcs.luaeval('vim.api._vim_id(1)'))
- eq('1', funcs.luaeval('vim.api._vim_id("1")'))
- eq({1}, funcs.luaeval('vim.api._vim_id({1})'))
- eq({foo=1}, funcs.luaeval('vim.api._vim_id({foo=1})'))
- eq(1.5, funcs.luaeval('vim.api._vim_id(1.5)'))
- eq(true, funcs.luaeval('vim.api._vim_id(true)'))
- eq(false, funcs.luaeval('vim.api._vim_id(false)'))
- eq(NIL, funcs.luaeval('vim.api._vim_id(nil)'))
-
- eq(0, eval([[type(luaeval('vim.api._vim_id(1)'))]]))
- eq(1, eval([[type(luaeval('vim.api._vim_id("1")'))]]))
- eq(3, eval([[type(luaeval('vim.api._vim_id({1})'))]]))
- eq(4, eval([[type(luaeval('vim.api._vim_id({foo=1})'))]]))
- eq(5, eval([[type(luaeval('vim.api._vim_id(1.5)'))]]))
- eq(6, eval([[type(luaeval('vim.api._vim_id(true)'))]]))
- eq(6, eval([[type(luaeval('vim.api._vim_id(false)'))]]))
- eq(7, eval([[type(luaeval('vim.api._vim_id(nil)'))]]))
-
- eq({foo=1, bar={42, {{baz=true}, 5}}}, funcs.luaeval('vim.api._vim_id({foo=1, bar={42, {{baz=true}, 5}}})'))
- end)
-
- it('correctly converts container objects with type_idx to API objects', function()
- eq(5, eval('type(luaeval("vim.api._vim_id({[vim.type_idx]=vim.types.float, [vim.val_idx]=0})"))'))
- eq(4, eval([[type(luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.dictionary})'))]]))
- eq(3, eval([[type(luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array})'))]]))
-
- eq({}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array})'))
-
- -- Presence of type_idx makes Vim ignore some keys
- eq({42}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
- eq({foo=2}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
- eq(10, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
- eq({}, funcs.luaeval('vim.api._vim_id({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})'))
- end)
-
- it('correctly converts arrays with type_idx to API objects', function()
- eq(3, eval([[type(luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array})'))]]))
-
- eq({}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array})'))
-
- eq({42}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
- eq({{foo=2}}, funcs.luaeval('vim.api._vim_id_array({{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
- eq({10}, funcs.luaeval('vim.api._vim_id_array({{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
- eq({}, funcs.luaeval('vim.api._vim_id_array({[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2})'))
-
- eq({}, funcs.luaeval('vim.api._vim_id_array({})'))
- eq(3, eval([[type(luaeval('vim.api._vim_id_array({})'))]]))
- end)
-
- it('correctly converts dictionaries with type_idx to API objects', function()
- eq(4, eval([[type(luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary})'))]]))
-
- eq({}, funcs.luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary})'))
-
- eq({v={42}}, funcs.luaeval('vim.api._vim_id_dictionary({v={[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
- eq({foo=2}, funcs.luaeval('vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42})'))
- eq({v=10}, funcs.luaeval('vim.api._vim_id_dictionary({v={[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}})'))
- eq({v={}}, funcs.luaeval('vim.api._vim_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.
- eq({}, funcs.luaeval('vim.api._vim_id_dictionary({})'))
- eq(4, eval([[type(luaeval('vim.api._vim_id_dictionary({})'))]]))
- end)
-
- it('correctly converts self-containing containers', function()
- meths.set_var('l', {})
- eval('add(l, l)')
- eq(true, eval('luaeval("_A == _A[1]", l)'))
- eq(true, eval('luaeval("_A[1] == _A[1][1]", [l])'))
- eq(true, eval('luaeval("_A.d == _A.d[1]", {"d": l})'))
- eq(true, eval('luaeval("_A ~= _A[1]", [l])'))
-
- meths.set_var('d', {foo=42})
- eval('extend(d, {"d": d})')
- eq(true, eval('luaeval("_A == _A.d", d)'))
- eq(true, eval('luaeval("_A[1] == _A[1].d", [d])'))
- eq(true, eval('luaeval("_A.d == _A.d.d", {"d": d})'))
- eq(true, eval('luaeval("_A ~= _A.d", {"d": d})'))
- end)
-
- it('errors out correctly when working with API', function()
- -- Conversion errors
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Cannot convert given lua type',
- exc_exec([[call luaeval("vim.api._vim_id(vim.api._vim_id)")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Cannot convert given lua table',
- exc_exec([[call luaeval("vim.api._vim_id({1, foo=42})")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Cannot convert given lua type',
- exc_exec([[call luaeval("vim.api._vim_id({42, vim.api._vim_id})")]]))
- -- Errors in number of arguments
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected 1 argument',
- exc_exec([[call luaeval("vim.api._vim_id()")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected 1 argument',
- exc_exec([[call luaeval("vim.api._vim_id(1, 2)")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected 2 arguments',
- exc_exec([[call luaeval("vim.api.vim_set_var(1, 2, 3)")]]))
- -- Error in argument types
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected lua string',
- exc_exec([[call luaeval("vim.api.vim_set_var(1, 2)")]]))
-
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected lua number',
- exc_exec([[call luaeval("vim.api.buffer_get_line(0, 'test')")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Number is not integral',
- exc_exec([[call luaeval("vim.api.buffer_get_line(0, 1.5)")]]))
-
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected lua table',
- exc_exec([[call luaeval("vim.api._vim_id_float('test')")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Unexpected type',
- exc_exec([[call luaeval("vim.api._vim_id_float({[vim.type_idx]=vim.types.dictionary})")]]))
-
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected lua table',
- exc_exec([[call luaeval("vim.api._vim_id_array(1)")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Unexpected type',
- exc_exec([[call luaeval("vim.api._vim_id_array({[vim.type_idx]=vim.types.dictionary})")]]))
-
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Expected lua table',
- exc_exec([[call luaeval("vim.api._vim_id_dictionary(1)")]]))
- eq('Vim(call):E5108: Error while calling lua chunk for luaeval(): Unexpected type',
- exc_exec([[call luaeval("vim.api._vim_id_dictionary({[vim.type_idx]=vim.types.array})")]]))
- -- TODO: check for errors with Tabpage argument
- -- TODO: check for errors with Window argument
- -- TODO: check for errors with Buffer argument
- end)
-
- it('accepts any value as API Boolean', function()
- eq('', funcs.luaeval('vim.api.vim_replace_termcodes("", vim, false, nil)'))
- eq('', funcs.luaeval('vim.api.vim_replace_termcodes("", 0, 1.5, "test")'))
- eq('', funcs.luaeval('vim.api.vim_replace_termcodes("", true, {}, {[vim.type_idx]=vim.types.array})'))
- end)
-
- -- TODO: check buffer/window/etc.
-end)