mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 13:15:09 -07:00
bda63d5b97
This is a breaking change which will make refactor of typval and shada code a lot easier. In particular, code that would use or check for v:msgpack_types.binary in the wild would be broken. This appears to be rarely used in existing plugins. Also some cases where v:msgpack_type.string would be used to represent a binary string of "string" type, we use a BLOB instead, which is vimscripts native type for binary blobs, and already was used for BIN formats when necessary. msgpackdump(msgpackparse(data)) no longer preserves the distinction of BIN and STR strings. This is very common behavior for language-specific msgpack bindings. Nvim uses msgpack as a tool to serialize its data. Nvim is not a tool to bit-perfectly manipulate arbitrary msgpack data out in the wild. The changed tests should indicate how behavior changes in various edge cases.
713 lines
29 KiB
Lua
713 lines
29 KiB
Lua
local t = require('test.testutil')
|
|
local n = require('test.functional.testnvim')()
|
|
|
|
local clear = n.clear
|
|
local api = n.api
|
|
local eq = t.eq
|
|
local nvim_eval = n.eval
|
|
local nvim_command = n.command
|
|
local exc_exec = n.exc_exec
|
|
local ok = t.ok
|
|
local NIL = vim.NIL
|
|
|
|
describe('autoload/msgpack.vim', function()
|
|
before_each(function()
|
|
clear { args = { '-u', 'NORC' } }
|
|
end)
|
|
|
|
local sp = function(typ, val)
|
|
return ('{"_TYPE": v:msgpack_types.%s, "_VAL": %s}'):format(typ, val)
|
|
end
|
|
local mapsp = function(...)
|
|
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 nan = -(1.0 / 0.0 - 1.0 / 0.0)
|
|
local inf = 1.0 / 0.0
|
|
local minus_inf = -(1.0 / 0.0)
|
|
|
|
describe('function msgpack#equal', function()
|
|
local msgpack_eq = function(expected, a, b)
|
|
eq(expected, nvim_eval(('msgpack#equal(%s, %s)'):format(a, b)))
|
|
if a ~= b then
|
|
eq(expected, nvim_eval(('msgpack#equal(%s, %s)'):format(b, a)))
|
|
end
|
|
end
|
|
it('compares raw integers correctly', function()
|
|
msgpack_eq(1, '1', '1')
|
|
msgpack_eq(0, '1', '0')
|
|
end)
|
|
it('compares integer specials correctly', function()
|
|
msgpack_eq(1, sp('integer', '[-1, 1, 0, 0]'), sp('integer', '[-1, 1, 0, 0]'))
|
|
msgpack_eq(0, sp('integer', '[-1, 1, 0, 0]'), sp('integer', '[ 1, 1, 0, 0]'))
|
|
end)
|
|
it('compares integer specials with raw integer correctly', function()
|
|
msgpack_eq(1, sp('integer', '[-1, 0, 0, 1]'), '-1')
|
|
msgpack_eq(0, sp('integer', '[-1, 0, 0, 1]'), '1')
|
|
msgpack_eq(0, sp('integer', '[ 1, 0, 0, 1]'), '-1')
|
|
msgpack_eq(1, sp('integer', '[ 1, 0, 0, 1]'), '1')
|
|
end)
|
|
it('compares integer with float correctly', function()
|
|
msgpack_eq(0, '0', '0.0')
|
|
end)
|
|
it('compares raw binaries correctly', function()
|
|
msgpack_eq(1, '"abc\\ndef"', '"abc\\ndef"')
|
|
msgpack_eq(0, '"abc\\ndef"', '"abc\\nghi"')
|
|
end)
|
|
it('compares string specials correctly', function()
|
|
msgpack_eq(1, sp('string', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]'))
|
|
msgpack_eq(0, sp('string', '["abc", "def"]'), sp('string', '["abc\\n", "def"]'))
|
|
msgpack_eq(1, sp('string', '["abc", "def"]'), '"abc\\ndef"')
|
|
msgpack_eq(1, '"abc\\ndef"', sp('string', '["abc", "def"]'))
|
|
end)
|
|
it('compares ext specials correctly', function()
|
|
msgpack_eq(1, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
|
|
msgpack_eq(0, sp('ext', '[2, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
|
|
msgpack_eq(0, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "abc"]]'))
|
|
end)
|
|
it('compares raw maps correctly', function()
|
|
msgpack_eq(1, '{"a": 1, "b": 2}', '{"b": 2, "a": 1}')
|
|
msgpack_eq(1, '{}', '{}')
|
|
msgpack_eq(0, '{}', '{"a": 1}')
|
|
msgpack_eq(0, '{"a": 2}', '{"a": 1}')
|
|
msgpack_eq(0, '{"a": 1}', '{"b": 1}')
|
|
msgpack_eq(0, '{"a": 1}', '{"a": 1, "b": 1}')
|
|
msgpack_eq(0, '{"a": 1, "b": 1}', '{"b": 1}')
|
|
end)
|
|
it('compares map specials correctly', function()
|
|
msgpack_eq(1, mapsp(), mapsp())
|
|
msgpack_eq(
|
|
1,
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1'))
|
|
)
|
|
msgpack_eq(0, mapsp(), mapsp('1', '1'))
|
|
msgpack_eq(
|
|
0,
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
|
mapsp(sp('string', '[""]'), mapsp('1', '1'))
|
|
)
|
|
msgpack_eq(
|
|
0,
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
|
mapsp(mapsp('2', '1'), mapsp('1', '1'))
|
|
)
|
|
msgpack_eq(
|
|
0,
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
|
mapsp(mapsp('1', '2'), mapsp('1', '1'))
|
|
)
|
|
msgpack_eq(
|
|
0,
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
|
mapsp(mapsp('1', '1'), mapsp('2', '1'))
|
|
)
|
|
msgpack_eq(
|
|
0,
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1')),
|
|
mapsp(mapsp('1', '1'), mapsp('1', '2'))
|
|
)
|
|
msgpack_eq(
|
|
1,
|
|
mapsp(mapsp('2', '1'), mapsp('1', '1'), mapsp('1', '1'), mapsp('1', '1')),
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1'), mapsp('2', '1'), mapsp('1', '1'))
|
|
)
|
|
end)
|
|
it('compares map specials with raw maps correctly', function()
|
|
msgpack_eq(1, mapsp(), '{}')
|
|
msgpack_eq(1, mapsp(sp('string', '["1"]'), '1'), '{"1": 1}')
|
|
msgpack_eq(1, mapsp(sp('string', '["1"]'), sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
|
|
msgpack_eq(0, mapsp(sp('integer', '[1, 0, 0, 1]'), sp('string', '["1"]')), '{1: "1"}')
|
|
msgpack_eq(1, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
|
|
msgpack_eq(0, mapsp(sp('string', '["1"]'), '1', sp('string', '["2"]'), '2'), '{"1": 1}')
|
|
msgpack_eq(0, mapsp(sp('string', '["1"]'), '1'), '{"1": 1, "2": 2}')
|
|
end)
|
|
it('compares raw arrays correctly', function()
|
|
msgpack_eq(1, '[]', '[]')
|
|
msgpack_eq(0, '[]', '[1]')
|
|
msgpack_eq(1, '[1]', '[1]')
|
|
msgpack_eq(1, '[[[1]]]', '[[[1]]]')
|
|
msgpack_eq(0, '[[[2]]]', '[[[1]]]')
|
|
end)
|
|
it('compares array specials correctly', function()
|
|
msgpack_eq(1, sp('array', '[]'), sp('array', '[]'))
|
|
msgpack_eq(0, sp('array', '[]'), sp('array', '[1]'))
|
|
msgpack_eq(1, sp('array', '[1]'), sp('array', '[1]'))
|
|
msgpack_eq(1, sp('array', '[[[1]]]'), sp('array', '[[[1]]]'))
|
|
msgpack_eq(0, sp('array', '[[[1]]]'), sp('array', '[[[2]]]'))
|
|
end)
|
|
it('compares array specials with raw arrays correctly', function()
|
|
msgpack_eq(1, sp('array', '[]'), '[]')
|
|
msgpack_eq(0, sp('array', '[]'), '[1]')
|
|
msgpack_eq(1, sp('array', '[1]'), '[1]')
|
|
msgpack_eq(1, sp('array', '[[[1]]]'), '[[[1]]]')
|
|
msgpack_eq(0, sp('array', '[[[1]]]'), '[[[2]]]')
|
|
end)
|
|
it('compares raw floats correctly', function()
|
|
msgpack_eq(1, '0.0', '0.0')
|
|
msgpack_eq(1, '(1.0/0.0-1.0/0.0)', '(1.0/0.0-1.0/0.0)')
|
|
-- both (1.0/0.0-1.0/0.0) and -(1.0/0.0-1.0/0.0) now return
|
|
-- str2float('nan'). ref: @18d1ba3422d
|
|
msgpack_eq(1, '(1.0/0.0-1.0/0.0)', '-(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(1, '-(1.0/0.0-1.0/0.0)', '-(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(1, '1.0/0.0', '1.0/0.0')
|
|
msgpack_eq(1, '-(1.0/0.0)', '-(1.0/0.0)')
|
|
msgpack_eq(1, '0.0', '0.0')
|
|
msgpack_eq(0, '0.0', '1.0')
|
|
msgpack_eq(0, '0.0', '(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(0, '0.0', '1.0/0.0')
|
|
msgpack_eq(0, '0.0', '-(1.0/0.0)')
|
|
msgpack_eq(0, '1.0/0.0', '-(1.0/0.0)')
|
|
msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '-(1.0/0.0)')
|
|
msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '1.0/0.0')
|
|
end)
|
|
it('compares float specials with raw floats correctly', function()
|
|
msgpack_eq(1, sp('float', '0.0'), '0.0')
|
|
msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), '(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), '-(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), '(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), '-(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(1, sp('float', '1.0/0.0'), '1.0/0.0')
|
|
msgpack_eq(1, sp('float', '-(1.0/0.0)'), '-(1.0/0.0)')
|
|
msgpack_eq(1, sp('float', '0.0'), '0.0')
|
|
msgpack_eq(0, sp('float', '0.0'), '1.0')
|
|
msgpack_eq(0, sp('float', '0.0'), '(1.0/0.0-1.0/0.0)')
|
|
msgpack_eq(0, sp('float', '0.0'), '1.0/0.0')
|
|
msgpack_eq(0, sp('float', '0.0'), '-(1.0/0.0)')
|
|
msgpack_eq(0, sp('float', '1.0/0.0'), '-(1.0/0.0)')
|
|
msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), '-(1.0/0.0)')
|
|
msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), '1.0/0.0')
|
|
end)
|
|
it('compares float specials correctly', function()
|
|
msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0'))
|
|
msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '(1.0/0.0-1.0/0.0)'))
|
|
msgpack_eq(1, sp('float', '1.0/0.0'), sp('float', '1.0/0.0'))
|
|
msgpack_eq(1, sp('float', '-(1.0/0.0)'), sp('float', '-(1.0/0.0)'))
|
|
msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0'))
|
|
msgpack_eq(0, sp('float', '0.0'), sp('float', '1.0'))
|
|
msgpack_eq(0, sp('float', '0.0'), sp('float', '(1.0/0.0-1.0/0.0)'))
|
|
msgpack_eq(0, sp('float', '0.0'), sp('float', '1.0/0.0'))
|
|
msgpack_eq(0, sp('float', '0.0'), sp('float', '-(1.0/0.0)'))
|
|
msgpack_eq(0, sp('float', '1.0/0.0'), sp('float', '-(1.0/0.0)'))
|
|
msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0)'))
|
|
msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0-1.0/0.0)'))
|
|
msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0-1.0/0.0)'))
|
|
msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '1.0/0.0'))
|
|
end)
|
|
it('compares boolean specials correctly', function()
|
|
msgpack_eq(1, sp('boolean', '1'), sp('boolean', '1'))
|
|
msgpack_eq(0, sp('boolean', '1'), sp('boolean', '0'))
|
|
end)
|
|
it('compares nil specials correctly', function()
|
|
msgpack_eq(1, sp('nil', '1'), sp('nil', '0'))
|
|
end)
|
|
it('compares nil, boolean and integer values with each other correctly', function()
|
|
msgpack_eq(0, sp('boolean', '1'), '1')
|
|
msgpack_eq(0, sp('boolean', '1'), sp('nil', '0'))
|
|
msgpack_eq(0, sp('boolean', '1'), sp('nil', '1'))
|
|
msgpack_eq(0, sp('boolean', '0'), sp('nil', '0'))
|
|
msgpack_eq(0, sp('boolean', '0'), '0')
|
|
msgpack_eq(0, sp('boolean', '0'), sp('integer', '[1, 0, 0, 0]'))
|
|
msgpack_eq(0, sp('boolean', '0'), sp('integer', '[1, 0, 0, 1]'))
|
|
msgpack_eq(0, sp('boolean', '1'), sp('integer', '[1, 0, 0, 1]'))
|
|
msgpack_eq(0, sp('nil', '0'), sp('integer', '[1, 0, 0, 0]'))
|
|
msgpack_eq(0, sp('nil', '0'), '0')
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#is_int', function()
|
|
it('works', function()
|
|
eq(1, nvim_eval('msgpack#is_int(1)'))
|
|
eq(1, nvim_eval('msgpack#is_int(-1)'))
|
|
eq(1, nvim_eval(('msgpack#is_int(%s)'):format(sp('integer', '[1, 0, 0, 1]'))))
|
|
eq(1, nvim_eval(('msgpack#is_int(%s)'):format(sp('integer', '[-1, 0, 0, 1]'))))
|
|
eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('float', '0.0'))))
|
|
eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('boolean', '0'))))
|
|
eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('nil', '0'))))
|
|
eq(0, nvim_eval('msgpack#is_int("")'))
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#is_uint', function()
|
|
it('works', function()
|
|
eq(1, nvim_eval('msgpack#is_uint(1)'))
|
|
eq(0, nvim_eval('msgpack#is_uint(-1)'))
|
|
eq(1, nvim_eval(('msgpack#is_uint(%s)'):format(sp('integer', '[1, 0, 0, 1]'))))
|
|
eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('integer', '[-1, 0, 0, 1]'))))
|
|
eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('float', '0.0'))))
|
|
eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('boolean', '0'))))
|
|
eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('nil', '0'))))
|
|
eq(0, nvim_eval('msgpack#is_uint("")'))
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#strftime', function()
|
|
it('works', function()
|
|
local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
|
|
eq(epoch, nvim_eval('msgpack#strftime("%Y-%m-%dT%H:%M:%S", 0)'))
|
|
eq(
|
|
epoch,
|
|
nvim_eval(
|
|
('msgpack#strftime("%%Y-%%m-%%dT%%H:%%M:%%S", %s)'):format(sp('integer', '[1, 0, 0, 0]'))
|
|
)
|
|
)
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#strptime', function()
|
|
it('works', function()
|
|
for _, v in ipairs({ 0, 10, 100000, 204, 1000000000 }) do
|
|
local time = os.date('%Y-%m-%dT%H:%M:%S', v)
|
|
eq(v, nvim_eval('msgpack#strptime("%Y-%m-%dT%H:%M:%S", ' .. '"' .. time .. '")'))
|
|
end
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#type', function()
|
|
local type_eq = function(expected, val)
|
|
eq(expected, nvim_eval(('msgpack#type(%s)'):format(val)))
|
|
end
|
|
|
|
it('works for special dictionaries', function()
|
|
type_eq('string', sp('string', '[""]'))
|
|
type_eq('ext', sp('ext', '[1, [""]]'))
|
|
type_eq('array', sp('array', '[]'))
|
|
type_eq('map', sp('map', '[]'))
|
|
type_eq('integer', sp('integer', '[1, 0, 0, 0]'))
|
|
type_eq('float', sp('float', '0.0'))
|
|
type_eq('boolean', sp('boolean', '0'))
|
|
type_eq('nil', sp('nil', '0'))
|
|
end)
|
|
|
|
it('works for regular values', function()
|
|
type_eq('string', '""')
|
|
type_eq('array', '[]')
|
|
type_eq('map', '{}')
|
|
type_eq('integer', '1')
|
|
type_eq('float', '0.0')
|
|
type_eq('float', '(1.0/0.0)')
|
|
type_eq('float', '-(1.0/0.0)')
|
|
type_eq('float', '(1.0/0.0-1.0/0.0)')
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#special_type', function()
|
|
local sp_type_eq = function(expected, val)
|
|
eq(expected, nvim_eval(('msgpack#special_type(%s)'):format(val)))
|
|
end
|
|
|
|
it('works for special dictionaries', function()
|
|
sp_type_eq('string', sp('string', '[""]'))
|
|
sp_type_eq('ext', sp('ext', '[1, [""]]'))
|
|
sp_type_eq('array', sp('array', '[]'))
|
|
sp_type_eq('map', sp('map', '[]'))
|
|
sp_type_eq('integer', sp('integer', '[1, 0, 0, 0]'))
|
|
sp_type_eq('float', sp('float', '0.0'))
|
|
sp_type_eq('boolean', sp('boolean', '0'))
|
|
sp_type_eq('nil', sp('nil', '0'))
|
|
end)
|
|
|
|
it('works for regular values', function()
|
|
sp_type_eq(0, '""')
|
|
sp_type_eq(0, '[]')
|
|
sp_type_eq(0, '{}')
|
|
sp_type_eq(0, '1')
|
|
sp_type_eq(0, '0.0')
|
|
sp_type_eq(0, '(1.0/0.0)')
|
|
sp_type_eq(0, '-(1.0/0.0)')
|
|
sp_type_eq(0, '(1.0/0.0-1.0/0.0)')
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#string', function()
|
|
local string_eq = function(expected, val)
|
|
eq(expected, nvim_eval(('msgpack#string(%s)'):format(val)))
|
|
end
|
|
|
|
it('works for special dictionaries', function()
|
|
string_eq('""', sp('string', '[""]'))
|
|
string_eq('"\\n"', sp('string', '["", ""]'))
|
|
string_eq('"ab\\0c\\nde"', sp('string', '["ab\\nc", "de"]'))
|
|
string_eq('+(2)""', sp('ext', '[2, [""]]'))
|
|
string_eq('+(2)"\\n"', sp('ext', '[2, ["", ""]]'))
|
|
string_eq('+(2)"ab\\0c\\nde"', sp('ext', '[2, ["ab\\nc", "de"]]'))
|
|
string_eq('[]', sp('array', '[]'))
|
|
string_eq('[[[[{}]]]]', sp('array', '[[[[{}]]]]'))
|
|
string_eq('{}', sp('map', '[]'))
|
|
string_eq('{2: 10}', sp('map', '[[2, 10]]'))
|
|
string_eq(
|
|
'{{1: 1}: {1: 1}, {2: 1}: {1: 1}}',
|
|
mapsp(mapsp('2', '1'), mapsp('1', '1'), mapsp('1', '1'), mapsp('1', '1'))
|
|
)
|
|
string_eq(
|
|
'{{1: 1}: {1: 1}, {2: 1}: {1: 1}}',
|
|
mapsp(mapsp('1', '1'), mapsp('1', '1'), mapsp('2', '1'), mapsp('1', '1'))
|
|
)
|
|
string_eq(
|
|
'{[1, 2, {{1: 2}: 1}]: [1, 2, {{1: 2}: 1}]}',
|
|
mapsp(
|
|
('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1')),
|
|
('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1'))
|
|
)
|
|
)
|
|
string_eq('0x0000000000000000', sp('integer', '[1, 0, 0, 0]'))
|
|
string_eq('-0x0000000100000000', sp('integer', '[-1, 0, 2, 0]'))
|
|
string_eq('0x123456789abcdef0', sp('integer', '[ 1, 0, 610839793, 448585456]'))
|
|
string_eq('-0x123456789abcdef0', sp('integer', '[-1, 0, 610839793, 448585456]'))
|
|
string_eq('0xf23456789abcdef0', sp('integer', '[ 1, 3, 1684581617, 448585456]'))
|
|
string_eq('-0x723456789abcdef0', sp('integer', '[-1, 1, 1684581617, 448585456]'))
|
|
string_eq('0.0', sp('float', '0.0'))
|
|
string_eq('inf', sp('float', '(1.0/0.0)'))
|
|
string_eq('-inf', sp('float', '-(1.0/0.0)'))
|
|
string_eq('nan', sp('float', '(1.0/0.0-1.0/0.0)'))
|
|
string_eq('nan', sp('float', '-(1.0/0.0-1.0/0.0)'))
|
|
string_eq('FALSE', sp('boolean', '0'))
|
|
string_eq('TRUE', sp('boolean', '1'))
|
|
string_eq('NIL', sp('nil', '0'))
|
|
end)
|
|
|
|
it('works for regular values', function()
|
|
string_eq('""', '""')
|
|
string_eq('"\\n"', '"\\n"')
|
|
string_eq('[]', '[]')
|
|
string_eq('[[[{}]]]', '[[[{}]]]')
|
|
string_eq('{}', '{}')
|
|
string_eq('{"2": 10}', '{2: 10}')
|
|
string_eq('{"2": [{}]}', '{2: [{}]}')
|
|
string_eq('1', '1')
|
|
string_eq('0.0', '0.0')
|
|
string_eq('inf', '(1.0/0.0)')
|
|
string_eq('-inf', '-(1.0/0.0)')
|
|
string_eq('nan', '(1.0/0.0-1.0/0.0)')
|
|
string_eq('nan', '-(1.0/0.0-1.0/0.0)')
|
|
end)
|
|
|
|
it('works for special v: values like v:true', function()
|
|
string_eq('TRUE', 'v:true')
|
|
string_eq('FALSE', 'v:false')
|
|
string_eq('NIL', 'v:null')
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#deepcopy', function()
|
|
it('works for special dictionaries', function()
|
|
nvim_command('let sparr = ' .. sp('array', '[[[]]]'))
|
|
nvim_command('let spmap = ' .. mapsp('"abc"', '[[]]'))
|
|
nvim_command('let spint = ' .. sp('integer', '[1, 0, 0, 0]'))
|
|
nvim_command('let spflt = ' .. sp('float', '1.0'))
|
|
nvim_command('let spext = ' .. sp('ext', '[2, ["abc", "def"]]'))
|
|
nvim_command('let spstr = ' .. sp('string', '["abc", "def"]'))
|
|
nvim_command('let spbln = ' .. sp('boolean', '0'))
|
|
nvim_command('let spnil = ' .. sp('nil', '0'))
|
|
|
|
nvim_command('let sparr2 = msgpack#deepcopy(sparr)')
|
|
nvim_command('let spmap2 = msgpack#deepcopy(spmap)')
|
|
nvim_command('let spint2 = msgpack#deepcopy(spint)')
|
|
nvim_command('let spflt2 = msgpack#deepcopy(spflt)')
|
|
nvim_command('let spext2 = msgpack#deepcopy(spext)')
|
|
nvim_command('let spstr2 = msgpack#deepcopy(spstr)')
|
|
nvim_command('let spbln2 = msgpack#deepcopy(spbln)')
|
|
nvim_command('let spnil2 = msgpack#deepcopy(spnil)')
|
|
|
|
eq('array', nvim_eval('msgpack#type(sparr2)'))
|
|
eq('map', nvim_eval('msgpack#type(spmap2)'))
|
|
eq('integer', nvim_eval('msgpack#type(spint2)'))
|
|
eq('float', nvim_eval('msgpack#type(spflt2)'))
|
|
eq('ext', nvim_eval('msgpack#type(spext2)'))
|
|
eq('string', nvim_eval('msgpack#type(spstr2)'))
|
|
eq('boolean', nvim_eval('msgpack#type(spbln2)'))
|
|
eq('nil', nvim_eval('msgpack#type(spnil2)'))
|
|
|
|
nvim_command('call add(sparr._VAL, 0)')
|
|
nvim_command('call add(sparr._VAL[0], 0)')
|
|
nvim_command('call add(sparr._VAL[0][0], 0)')
|
|
nvim_command('call add(spmap._VAL, [0, 0])')
|
|
nvim_command('call add(spmap._VAL[0][1], 0)')
|
|
nvim_command('call add(spmap._VAL[0][1][0], 0)')
|
|
nvim_command('let spint._VAL[1] = 1')
|
|
nvim_command('let spflt._VAL = 0.0')
|
|
nvim_command('let spext._VAL[0] = 3')
|
|
nvim_command('let spext._VAL[1][0] = "gh"')
|
|
nvim_command('let spstr._VAL[0] = "gh"')
|
|
nvim_command('let spbln._VAL = 1')
|
|
nvim_command('let spnil._VAL = 1')
|
|
|
|
eq({ _TYPE = {}, _VAL = { { {} } } }, nvim_eval('sparr2'))
|
|
eq({ _TYPE = {}, _VAL = { { 'abc', { {} } } } }, nvim_eval('spmap2'))
|
|
eq({ _TYPE = {}, _VAL = { 1, 0, 0, 0 } }, nvim_eval('spint2'))
|
|
eq({ _TYPE = {}, _VAL = 1.0 }, nvim_eval('spflt2'))
|
|
eq({ _TYPE = {}, _VAL = { 2, { 'abc', 'def' } } }, nvim_eval('spext2'))
|
|
eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spstr2'))
|
|
eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spbln2'))
|
|
eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spnil2'))
|
|
|
|
nvim_command('let sparr._TYPE = []')
|
|
nvim_command('let spmap._TYPE = []')
|
|
nvim_command('let spint._TYPE = []')
|
|
nvim_command('let spflt._TYPE = []')
|
|
nvim_command('let spext._TYPE = []')
|
|
nvim_command('let spstr._TYPE = []')
|
|
nvim_command('let spbln._TYPE = []')
|
|
nvim_command('let spnil._TYPE = []')
|
|
|
|
eq('array', nvim_eval('msgpack#special_type(sparr2)'))
|
|
eq('map', nvim_eval('msgpack#special_type(spmap2)'))
|
|
eq('integer', nvim_eval('msgpack#special_type(spint2)'))
|
|
eq('float', nvim_eval('msgpack#special_type(spflt2)'))
|
|
eq('ext', nvim_eval('msgpack#special_type(spext2)'))
|
|
eq('string', nvim_eval('msgpack#special_type(spstr2)'))
|
|
eq('boolean', nvim_eval('msgpack#special_type(spbln2)'))
|
|
eq('nil', nvim_eval('msgpack#special_type(spnil2)'))
|
|
end)
|
|
|
|
it('works for regular values', function()
|
|
nvim_command('let arr = [[[]]]')
|
|
nvim_command('let map = {1: {}}')
|
|
nvim_command('let int = 1')
|
|
nvim_command('let flt = 2.0')
|
|
nvim_command('let bin = "abc"')
|
|
|
|
nvim_command('let arr2 = msgpack#deepcopy(arr)')
|
|
nvim_command('let map2 = msgpack#deepcopy(map)')
|
|
nvim_command('let int2 = msgpack#deepcopy(int)')
|
|
nvim_command('let flt2 = msgpack#deepcopy(flt)')
|
|
nvim_command('let bin2 = msgpack#deepcopy(bin)')
|
|
|
|
eq('array', nvim_eval('msgpack#type(arr2)'))
|
|
eq('map', nvim_eval('msgpack#type(map2)'))
|
|
eq('integer', nvim_eval('msgpack#type(int2)'))
|
|
eq('float', nvim_eval('msgpack#type(flt2)'))
|
|
eq('string', nvim_eval('msgpack#type(bin2)'))
|
|
|
|
nvim_command('call add(arr, 0)')
|
|
nvim_command('call add(arr[0], 0)')
|
|
nvim_command('call add(arr[0][0], 0)')
|
|
nvim_command('let map.a = 1')
|
|
nvim_command('let map.1.a = 1')
|
|
nvim_command('let int = 2')
|
|
nvim_command('let flt = 3.0')
|
|
nvim_command('let bin = ""')
|
|
|
|
eq({ { {} } }, nvim_eval('arr2'))
|
|
eq({ ['1'] = {} }, nvim_eval('map2'))
|
|
eq(1, nvim_eval('int2'))
|
|
eq(2.0, nvim_eval('flt2'))
|
|
eq('abc', nvim_eval('bin2'))
|
|
end)
|
|
|
|
it('works for special v: values like v:true', function()
|
|
api.nvim_set_var('true', true)
|
|
api.nvim_set_var('false', false)
|
|
api.nvim_set_var('nil', NIL)
|
|
|
|
nvim_command('let true2 = msgpack#deepcopy(true)')
|
|
nvim_command('let false2 = msgpack#deepcopy(false)')
|
|
nvim_command('let nil2 = msgpack#deepcopy(nil)')
|
|
|
|
eq(true, api.nvim_get_var('true'))
|
|
eq(false, api.nvim_get_var('false'))
|
|
eq(NIL, api.nvim_get_var('nil'))
|
|
end)
|
|
end)
|
|
|
|
describe('function msgpack#eval', function()
|
|
local eval_eq = function(expected_type, expected_val, str, ...)
|
|
nvim_command(
|
|
("let g:__val = msgpack#eval('%s', %s)"):format(str:gsub("'", "''"), select(1, ...) or '{}')
|
|
)
|
|
eq(expected_type, nvim_eval('msgpack#type(g:__val)'))
|
|
local expected_val_full = expected_val
|
|
if
|
|
not (({ float = true, integer = true })[expected_type] and type(expected_val) ~= 'table')
|
|
and expected_type ~= 'array'
|
|
then
|
|
expected_val_full = { _TYPE = {}, _VAL = expected_val_full }
|
|
end
|
|
if expected_val_full == expected_val_full then
|
|
eq(expected_val_full, nvim_eval('g:__val'))
|
|
else -- NaN
|
|
local nvim_nan = tostring(nvim_eval('g:__val'))
|
|
-- -NaN is a hardware-specific detail, there's no need to test for it.
|
|
-- Accept ether 'nan' or '-nan' as the response.
|
|
ok(nvim_nan == 'nan' or nvim_nan == '-nan')
|
|
end
|
|
nvim_command('unlet g:__val')
|
|
end
|
|
|
|
it('correctly loads strings', function()
|
|
eval_eq('string', { 'abcdef' }, '="abcdef"')
|
|
eval_eq('string', { 'abc', 'def' }, '="abc\\ndef"')
|
|
eval_eq('string', { 'abc\ndef' }, '="abc\\0def"')
|
|
eval_eq('string', { '\nabc\ndef\n' }, '="\\0abc\\0def\\0"')
|
|
eval_eq('string', { 'abc\n\n\ndef' }, '="abc\\0\\0\\0def"')
|
|
eval_eq('string', { 'abc\n', '\ndef' }, '="abc\\0\\n\\0def"')
|
|
eval_eq('string', { 'abc', '', '', 'def' }, '="abc\\n\\n\\ndef"')
|
|
eval_eq('string', { 'abc', '', '', 'def', '' }, '="abc\\n\\n\\ndef\\n"')
|
|
eval_eq('string', { '', 'abc', '', '', 'def' }, '="\\nabc\\n\\n\\ndef"')
|
|
eval_eq('string', { '' }, '=""')
|
|
eval_eq('string', { '"' }, '="\\""')
|
|
eval_eq('string', { 'py3 print(sys.version_info)' }, '="py3 print(sys.version_info)"')
|
|
end)
|
|
|
|
it('correctly loads ext values', function()
|
|
eval_eq('ext', { 0, { 'abcdef' } }, '+(0)"abcdef"')
|
|
eval_eq('ext', { 0, { 'abc', 'def' } }, '+(0)"abc\\ndef"')
|
|
eval_eq('ext', { 0, { 'abc\ndef' } }, '+(0)"abc\\0def"')
|
|
eval_eq('ext', { 0, { '\nabc\ndef\n' } }, '+(0)"\\0abc\\0def\\0"')
|
|
eval_eq('ext', { 0, { 'abc\n\n\ndef' } }, '+(0)"abc\\0\\0\\0def"')
|
|
eval_eq('ext', { 0, { 'abc\n', '\ndef' } }, '+(0)"abc\\0\\n\\0def"')
|
|
eval_eq('ext', { 0, { 'abc', '', '', 'def' } }, '+(0)"abc\\n\\n\\ndef"')
|
|
eval_eq('ext', { 0, { 'abc', '', '', 'def', '' } }, '+(0)"abc\\n\\n\\ndef\\n"')
|
|
eval_eq('ext', { 0, { '', 'abc', '', '', 'def' } }, '+(0)"\\nabc\\n\\n\\ndef"')
|
|
eval_eq('ext', { 0, { '' } }, '+(0)""')
|
|
eval_eq('ext', { 0, { '"' } }, '+(0)"\\""')
|
|
|
|
eval_eq('ext', { -1, { 'abcdef' } }, '+(-1)"abcdef"')
|
|
eval_eq('ext', { -1, { 'abc', 'def' } }, '+(-1)"abc\\ndef"')
|
|
eval_eq('ext', { -1, { 'abc\ndef' } }, '+(-1)"abc\\0def"')
|
|
eval_eq('ext', { -1, { '\nabc\ndef\n' } }, '+(-1)"\\0abc\\0def\\0"')
|
|
eval_eq('ext', { -1, { 'abc\n\n\ndef' } }, '+(-1)"abc\\0\\0\\0def"')
|
|
eval_eq('ext', { -1, { 'abc\n', '\ndef' } }, '+(-1)"abc\\0\\n\\0def"')
|
|
eval_eq('ext', { -1, { 'abc', '', '', 'def' } }, '+(-1)"abc\\n\\n\\ndef"')
|
|
eval_eq('ext', { -1, { 'abc', '', '', 'def', '' } }, '+(-1)"abc\\n\\n\\ndef\\n"')
|
|
eval_eq('ext', { -1, { '', 'abc', '', '', 'def' } }, '+(-1)"\\nabc\\n\\n\\ndef"')
|
|
eval_eq('ext', { -1, { '' } }, '+(-1)""')
|
|
eval_eq('ext', { -1, { '"' } }, '+(-1)"\\""')
|
|
|
|
eval_eq(
|
|
'ext',
|
|
{ 42, { 'py3 print(sys.version_info)' } },
|
|
'+(42)"py3 print(sys.version_info)"'
|
|
)
|
|
end)
|
|
|
|
it('correctly loads floats', function()
|
|
eval_eq('float', inf, 'inf')
|
|
eval_eq('float', minus_inf, '-inf')
|
|
eval_eq('float', nan, 'nan')
|
|
eval_eq('float', 1.0e10, '1.0e10')
|
|
eval_eq('float', 1.0e10, '1.0e+10')
|
|
eval_eq('float', -1.0e10, '-1.0e+10')
|
|
eval_eq('float', 1.0, '1.0')
|
|
eval_eq('float', -1.0, '-1.0')
|
|
eval_eq('float', 1.0e-10, '1.0e-10')
|
|
eval_eq('float', -1.0e-10, '-1.0e-10')
|
|
end)
|
|
|
|
it('correctly loads integers', function()
|
|
eval_eq('integer', 10, '10')
|
|
eval_eq('integer', -10, '-10')
|
|
eval_eq('integer', { 1, 0, 610839793, 448585456 }, ' 0x123456789ABCDEF0')
|
|
eval_eq('integer', { -1, 0, 610839793, 448585456 }, '-0x123456789ABCDEF0')
|
|
eval_eq('integer', { 1, 3, 1684581617, 448585456 }, ' 0xF23456789ABCDEF0')
|
|
eval_eq('integer', { -1, 1, 1684581617, 448585456 }, '-0x723456789ABCDEF0')
|
|
eval_eq('integer', { 1, 0, 0, 0x100 }, '0x100')
|
|
eval_eq('integer', { -1, 0, 0, 0x100 }, '-0x100')
|
|
|
|
eval_eq('integer', ('a'):byte(), "'a'")
|
|
eval_eq('integer', 0xAB, "'«'")
|
|
eval_eq('integer', 0, "'\\0'")
|
|
eval_eq('integer', 10246567, "'\\10246567'")
|
|
end)
|
|
|
|
it('correctly loads constants', function()
|
|
eval_eq('boolean', 1, 'TRUE')
|
|
eval_eq('boolean', 0, 'FALSE')
|
|
eval_eq('nil', 0, 'NIL')
|
|
eval_eq('nil', 0, 'NIL', '{"NIL": 1, "nan": 2, "T": 3}')
|
|
eval_eq('float', nan, 'nan', '{"NIL": "1", "nan": "2", "T": "3"}')
|
|
eval_eq('integer', 3, 'T', '{"NIL": "1", "nan": "2", "T": "3"}')
|
|
eval_eq(
|
|
'integer',
|
|
{ 1, 0, 0, 0 },
|
|
'T',
|
|
('{"NIL": "1", "nan": "2", "T": \'%s\'}'):format(sp('integer', '[1, 0, 0, 0]'))
|
|
)
|
|
end)
|
|
|
|
it('correctly loads maps', function()
|
|
eval_eq('map', {}, '{}')
|
|
eval_eq(
|
|
'map',
|
|
{ { { _TYPE = {}, _VAL = { { 1, 2 } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } } },
|
|
'{{1: 2}: {3: 4}}'
|
|
)
|
|
eval_eq(
|
|
'map',
|
|
{ { { _TYPE = {}, _VAL = { { 1, 2 } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } }, { 1, 2 } },
|
|
'{{1: 2}: {3: 4}, 1: 2}'
|
|
)
|
|
|
|
eval_eq('map', {
|
|
{
|
|
{
|
|
_TYPE = {},
|
|
_VAL = {
|
|
{ { _TYPE = {}, _VAL = { 'py3 print(sys.version_info)' } }, 2 },
|
|
},
|
|
},
|
|
{ _TYPE = {}, _VAL = { { 3, 4 } } },
|
|
},
|
|
{ 1, 2 },
|
|
}, '{{"py3 print(sys.version_info)": 2}: {3: 4}, 1: 2}')
|
|
end)
|
|
|
|
it('correctly loads arrays', function()
|
|
eval_eq('array', {}, '[]')
|
|
eval_eq('array', { 1 }, '[1]')
|
|
eval_eq('array', { { _TYPE = {}, _VAL = 1 } }, '[TRUE]')
|
|
eval_eq(
|
|
'array',
|
|
{ { { _TYPE = {}, _VAL = { { 1, 2 } } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } },
|
|
'[[{1: 2}], {3: 4}]'
|
|
)
|
|
|
|
eval_eq(
|
|
'array',
|
|
{ { _TYPE = {}, _VAL = { 'py3 print(sys.version_info)' } } },
|
|
'["py3 print(sys.version_info)"]'
|
|
)
|
|
end)
|
|
|
|
it('errors out when needed', function()
|
|
eq('empty:Parsed string is empty', exc_exec('call msgpack#eval("", {})'))
|
|
eq('unknown:Invalid non-space character: ^', exc_exec('call msgpack#eval("^", {})'))
|
|
eq(
|
|
"char-invalid:Invalid integer character literal format: ''",
|
|
exc_exec('call msgpack#eval("\'\'", {})')
|
|
)
|
|
eq(
|
|
"char-invalid:Invalid integer character literal format: 'ab'",
|
|
exc_exec('call msgpack#eval("\'ab\'", {})')
|
|
)
|
|
eq(
|
|
"char-invalid:Invalid integer character literal format: '",
|
|
exc_exec('call msgpack#eval("\'", {})')
|
|
)
|
|
eq('"-invalid:Invalid string: "', exc_exec('call msgpack#eval("\\"", {})'))
|
|
eq('"-invalid:Invalid string: ="', exc_exec('call msgpack#eval("=\\"", {})'))
|
|
eq('"-invalid:Invalid string: +(0)"', exc_exec('call msgpack#eval("+(0)\\"", {})'))
|
|
eq(
|
|
'0.-nodigits:Decimal dot must be followed by digit(s): .e1',
|
|
exc_exec('call msgpack#eval("0.e1", {})')
|
|
)
|
|
eq(
|
|
'0x-long:Must have at most 16 hex digits: FEDCBA98765432100',
|
|
exc_exec('call msgpack#eval("0xFEDCBA98765432100", {})')
|
|
)
|
|
eq('0x-empty:Must have number after 0x: ', exc_exec('call msgpack#eval("0x", {})'))
|
|
eq('name-unknown:Unknown name FOO: FOO', exc_exec('call msgpack#eval("FOO", {})'))
|
|
|
|
eq(
|
|
'name-unknown:Unknown name py3: py3 print(sys.version_info)',
|
|
exc_exec('call msgpack#eval("py3 print(sys.version_info)", {})')
|
|
)
|
|
eq('name-unknown:Unknown name o: o', exc_exec('call msgpack#eval("-info", {})'))
|
|
end)
|
|
end)
|
|
end)
|