aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/plugin/helpers.lua41
-rw-r--r--test/functional/plugin/msgpack_spec.lua699
-rw-r--r--test/functional/plugin/shada_spec.lua2833
3 files changed, 3573 insertions, 0 deletions
diff --git a/test/functional/plugin/helpers.lua b/test/functional/plugin/helpers.lua
new file mode 100644
index 0000000000..9762ca314e
--- /dev/null
+++ b/test/functional/plugin/helpers.lua
@@ -0,0 +1,41 @@
+local paths = require('test.config.paths')
+
+local helpers = require('test.functional.helpers')
+local spawn, set_session, nvim_prog, merge_args =
+ helpers.spawn, helpers.set_session, helpers.nvim_prog, helpers.merge_args
+
+local additional_cmd = ''
+
+local function nvim_argv(shada_file)
+ local rtp_value = ('\'%s/runtime\''):format(
+ paths.test_source_path:gsub('\'', '\'\''))
+ local nvim_argv = {nvim_prog, '-u', 'NORC', '-i', shada_file or 'NONE', '-N',
+ '--cmd', 'set shortmess+=I background=light noswapfile',
+ '--cmd', 'let &runtimepath=' .. rtp_value,
+ '--cmd', additional_cmd,
+ '--embed'}
+ if helpers.prepend_argv then
+ return merge_args(helpers.prepend_argv, nvim_argv)
+ else
+ return nvim_argv
+ end
+end
+
+local session = nil
+
+local reset = function(...)
+ if session then
+ session:exit(0)
+ end
+ session = spawn(nvim_argv(...))
+ set_session(session)
+end
+
+local set_additional_cmd = function(s)
+ additional_cmd = s
+end
+
+return {
+ reset=reset,
+ set_additional_cmd=set_additional_cmd,
+}
diff --git a/test/functional/plugin/msgpack_spec.lua b/test/functional/plugin/msgpack_spec.lua
new file mode 100644
index 0000000000..18ff0f5156
--- /dev/null
+++ b/test/functional/plugin/msgpack_spec.lua
@@ -0,0 +1,699 @@
+local helpers = require('test.functional.helpers')
+local eq, nvim_eval, nvim_command, exc_exec =
+ helpers.eq, helpers.eval, helpers.command, helpers.exc_exec
+
+local plugin_helpers = require('test.functional.plugin.helpers')
+local reset = plugin_helpers.reset
+
+describe('In autoload/msgpack.vim', function()
+ before_each(reset)
+
+ 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 minus_nan = 1.0/0.0-1.0/0.0
+ local inf = 1.0/0.0
+ local minus_inf = -(1.0/0.0)
+ local has_minus_nan = tostring(nan) ~= tostring(minus_nan)
+
+ 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 binary specials correctly', function()
+ msgpack_eq(1, sp('binary', '["abc\\n", "def"]'),
+ sp('binary', '["abc\\n", "def"]'))
+ msgpack_eq(0, sp('binary', '["abc", "def"]'),
+ sp('binary', '["abc\\n", "def"]'))
+ end)
+ it('compares binary specials with raw binaries correctly', function()
+ msgpack_eq(1, sp('binary', '["abc", "def"]'), '"abc\\ndef"')
+ msgpack_eq(0, sp('binary', '["abc", "def"]'), '"abcdef"')
+ 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"]'))
+ end)
+ it('compares string specials with binary correctly', function()
+ msgpack_eq(0, sp('string', '["abc\\n", "def"]'),
+ sp('binary', '["abc\\n", "def"]'))
+ msgpack_eq(0, sp('string', '["abc", "def"]'), '"abc\\ndef"')
+ msgpack_eq(0, sp('binary', '["abc\\n", "def"]'),
+ sp('string', '["abc\\n", "def"]'))
+ msgpack_eq(0, '"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(sp('binary', '[""]'), '""'),
+ mapsp(sp('binary', '[""]'), '""'))
+ 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(sp('binary', '["a"]'), '""'),
+ mapsp(sp('binary', '[""]'), '""'))
+ msgpack_eq(0, mapsp(sp('binary', '[""]'), '"a"'),
+ mapsp(sp('binary', '[""]'), '""'))
+ msgpack_eq(0, mapsp(sp('binary', '["a"]'), '"a"'),
+ mapsp(sp('binary', '[""]'), '""'))
+ msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(sp('binary', '[""]'), 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(0, 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)')
+ if has_minus_nan then
+ msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '-(1.0/0.0-1.0/0.0)')
+ end
+ 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)')
+ if has_minus_nan then
+ msgpack_eq(0, sp('float', '(1.0/0.0-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-1.0/0.0)')
+ end
+ 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)'))
+ if has_minus_nan then
+ msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'),
+ sp('float', '-(1.0/0.0-1.0/0.0)'))
+ end
+ 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('binary', sp('binary', '[""]'))
+ 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('binary', '""')
+ 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('binary', sp('binary', '[""]'))
+ 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('""', sp('binary', '[""]'))
+ string_eq('"\\n"', sp('binary', '["", ""]'))
+ string_eq('"ab\\0c\\nde"', sp('binary', '["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)'))
+ if has_minus_nan then
+ string_eq('-nan', sp('float', '(1.0/0.0-1.0/0.0)'))
+ end
+ 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)')
+ if has_minus_nan then
+ string_eq('-nan', '(1.0/0.0-1.0/0.0)')
+ end
+ string_eq('nan', '-(1.0/0.0-1.0/0.0)')
+ 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 spbin = ' .. sp('binary', '["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 spbin2 = msgpack#deepcopy(spbin)')
+ 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('binary', nvim_eval('msgpack#type(spbin2)'))
+ 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 spbin._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={'abc', 'def'}}, nvim_eval('spbin2'))
+ 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 spbin._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('binary', nvim_eval('msgpack#special_type(spbin2)'))
+ 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('binary', 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)
+ 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
+ eq(tostring(expected_val_full), tostring(nvim_eval('g:__val')))
+ end
+ nvim_command('unlet g:__val')
+ end
+
+ it('correctly loads binary strings', function()
+ eval_eq('binary', {'abcdef'}, '"abcdef"')
+ eval_eq('binary', {'abc', 'def'}, '"abc\\ndef"')
+ eval_eq('binary', {'abc\ndef'}, '"abc\\0def"')
+ eval_eq('binary', {'\nabc\ndef\n'}, '"\\0abc\\0def\\0"')
+ eval_eq('binary', {'abc\n\n\ndef'}, '"abc\\0\\0\\0def"')
+ eval_eq('binary', {'abc\n', '\ndef'}, '"abc\\0\\n\\0def"')
+ eval_eq('binary', {'abc', '', '', 'def'}, '"abc\\n\\n\\ndef"')
+ eval_eq('binary', {'abc', '', '', 'def', ''}, '"abc\\n\\n\\ndef\\n"')
+ eval_eq('binary', {'', 'abc', '', '', 'def'}, '"\\nabc\\n\\n\\ndef"')
+ eval_eq('binary', {''}, '""')
+ eval_eq('binary', {'"'}, '"\\""')
+ 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', {'"'}, '="\\""')
+ 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)"\\""')
+ 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', minus_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, '\'«\'')
+ 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}')
+ 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}]')
+ 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", {})'))
+ end)
+ end)
+end)
diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua
new file mode 100644
index 0000000000..407f13a55b
--- /dev/null
+++ b/test/functional/plugin/shada_spec.lua
@@ -0,0 +1,2833 @@
+local helpers = require('test.functional.helpers')
+local eq, nvim_eval, nvim_command, nvim, exc_exec, funcs, nvim_feed, curbuf =
+ helpers.eq, helpers.eval, helpers.command, helpers.nvim, helpers.exc_exec,
+ helpers.funcs, helpers.feed, helpers.curbuf
+local neq = helpers.neq
+
+local msgpack = require('MessagePack')
+
+local plugin_helpers = require('test.functional.plugin.helpers')
+local reset = plugin_helpers.reset
+
+local shada_helpers = require('test.functional.shada.helpers')
+local get_shada_rw = shada_helpers.get_shada_rw
+local read_shada_file = shada_helpers.read_shada_file
+
+local mpack_eq = function(expected, mpack_result)
+ local mpack_keys = {'type', 'timestamp', 'length', 'value'}
+
+ local unpacker = msgpack.unpacker(mpack_result)
+ local actual = {}
+ local cur
+ local i = 0
+ while true do
+ local off, val = unpacker()
+ if not off then break end
+ if i % 4 == 0 then
+ cur = {}
+ actual[#actual + 1] = cur
+ end
+ local key = mpack_keys[(i % 4) + 1]
+ if key ~= 'length' then
+ if key == 'timestamp' and math.abs(val - os.time()) < 2 then
+ val = 'current'
+ end
+ cur[key] = val
+ end
+ i = i + 1
+ end
+ eq(expected, actual)
+end
+
+local wshada, _, fname = get_shada_rw('Xtest-functional-plugin-shada.shada')
+
+local wshada_tmp, _, fname_tmp =
+ get_shada_rw('Xtest-functional-plugin-shada.shada.tmp.f')
+
+describe('In autoload/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(function()
+ reset()
+ nvim_command([[
+ function ModifyVal(val)
+ if type(a:val) == type([])
+ if len(a:val) == 2 && type(a:val[0]) == type('') && a:val[0][0] is# '!' && has_key(v:msgpack_types, a:val[0][1:])
+ return {'_TYPE': v:msgpack_types[ a:val[0][1:] ], '_VAL': a:val[1]}
+ else
+ return map(copy(a:val), 'ModifyVal(v:val)')
+ endif
+ elseif type(a:val) == type({})
+ let keys = sort(keys(a:val))
+ let ret = {'_TYPE': v:msgpack_types.map, '_VAL': []}
+ for key in keys
+ let k = {'_TYPE': v:msgpack_types.string, '_VAL': split(key, "\n", 1)}
+ let v = ModifyVal(a:val[key])
+ call add(ret._VAL, [k, v])
+ unlet v
+ endfor
+ return ret
+ elseif type(a:val) == type('')
+ return {'_TYPE': v:msgpack_types.binary, '_VAL': split(a:val, "\n", 1)}
+ else
+ return a:val
+ endif
+ endfunction
+ ]])
+ end)
+
+ local sp = function(typ, val)
+ return ('{"_TYPE": v:msgpack_types.%s, "_VAL": %s}'):format(typ, val)
+ end
+
+ local st_meta = {
+ __pairs=function(table)
+ local ret = {}
+ local next_key = nil
+ local num_keys = 0
+ while true do
+ next_key = next(table, next_key)
+ if next_key == nil then
+ break
+ end
+ num_keys = num_keys + 1
+ ret[num_keys] = {next_key, table[next_key]}
+ end
+ table.sort(ret, function(a, b)
+ return a[1] < b[1]
+ end)
+ local state = {i=0}
+ return (function(state, var)
+ state.i = state.i + 1
+ if ret[state.i] then
+ return table.unpack(ret[state.i])
+ end
+ end), state
+ end
+ }
+
+ local st = function(table)
+ return setmetatable(table, st_meta)
+ end
+
+ describe('function shada#mpack_to_sd', function()
+ local mpack2sd = function(arg)
+ return ('shada#mpack_to_sd(%s)'):format(arg)
+ end
+
+ it('works', function()
+ eq({}, nvim_eval(mpack2sd('[]')))
+ eq({{type=1, timestamp=5, length=1, data=7}},
+ nvim_eval(mpack2sd('[1, 5, 1, 7]')))
+ eq({{type=1, timestamp=5, length=1, data=7},
+ {type=1, timestamp=10, length=1, data=5}},
+ nvim_eval(mpack2sd('[1, 5, 1, 7, 1, 10, 1, 5]')))
+ eq('zero-uint:Entry 1 has type element which is zero',
+ exc_exec('call ' .. mpack2sd('[0, 5, 1, 7]')))
+ eq('zero-uint:Entry 1 has type element which is zero',
+ exc_exec('call ' .. mpack2sd(('[%s, 5, 1, 7]'):format(
+ sp('integer', '[1, 0, 0, 0]')))))
+ eq('not-uint:Entry 1 has timestamp element which is not an unsigned integer',
+ exc_exec('call ' .. mpack2sd('[1, -1, 1, 7]')))
+ eq('not-uint:Entry 1 has length element which is not an unsigned integer',
+ exc_exec('call ' .. mpack2sd('[1, 1, -1, 7]')))
+ eq('not-uint:Entry 1 has type element which is not an unsigned integer',
+ exc_exec('call ' .. mpack2sd('["", 1, -1, 7]')))
+ end)
+ end)
+
+ describe('function shada#sd_to_strings', function()
+ local sd2strings_eq = function(expected, arg)
+ if type(arg) == 'table' then
+ eq(expected, funcs['shada#sd_to_strings'](arg))
+ else
+ eq(expected, nvim_eval(('shada#sd_to_strings(%s)'):format(arg)))
+ end
+ end
+
+ it('works with empty input', function()
+ sd2strings_eq({}, '[]')
+ end)
+
+ it('works with unknown items', function()
+ sd2strings_eq({
+ 'Unknown (0x64) with timestamp ' .. epoch .. ':',
+ ' = 100'
+ }, {{type=100, timestamp=0, length=1, data=100}})
+
+ sd2strings_eq({
+ 'Unknown (0x4000001180000006) with timestamp ' .. epoch .. ':',
+ ' = 100'
+ }, ('[{"type": %s, "timestamp": 0, "length": 1, "data": 100}]'):format(
+ sp('integer', '[1, 1, 35, 6]')
+ ))
+ end)
+
+ it('works with multiple unknown items', function()
+ sd2strings_eq({
+ 'Unknown (0x64) with timestamp ' .. epoch .. ':',
+ ' = 100',
+ 'Unknown (0x65) with timestamp ' .. epoch .. ':',
+ ' = 500',
+ }, {{type=100, timestamp=0, length=1, data=100},
+ {type=101, timestamp=0, length=1, data=500}})
+ end)
+
+ it('works with header items', function()
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ }, {{type=1, timestamp=0, data={generator='test'}}})
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + a 1',
+ ' + b 2',
+ ' + c column 3',
+ ' + d 4',
+ }, {{type=1, timestamp=0, data=st({a=1, b=2, c=3, d=4})}})
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Value',
+ ' + t "test"',
+ }, {{type=1, timestamp=0, data={t='test'}}})
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=1, timestamp=0, data={1, 2, 3}}})
+ end)
+
+ it('processes standard keys correctly, even in header', function()
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + c column 0',
+ ' + f file name "/tmp/foo"',
+ ' + l line number 10',
+ ' + n name \'@\'',
+ ' + rc contents ["abc", "def"]',
+ ' + rt type CHARACTERWISE',
+ ' + rw block width 10',
+ ' + sc smartcase value FALSE',
+ ' + se place cursor at end TRUE',
+ ' + sh v:hlsearch value TRUE',
+ ' + sl has line offset FALSE',
+ ' + sm magic value TRUE',
+ ' + so offset value 10',
+ ' + sp pattern "100"',
+ ' + ss is :s pattern TRUE',
+ ' + su is last used FALSE',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'so': 10,
+ 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sp': '100',
+ 'rt': 0,
+ 'rw': 10,
+ 'rc': ['abc', 'def'],
+ 'n': 0x40,
+ 'l': 10,
+ 'c': 0,
+ 'f': '/tmp/foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description____ Value',
+ ' # Expected integer',
+ ' + c column "abc"',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + n name -64',
+ ' # Expected array value',
+ ' + rc contents "10"',
+ ' # Unexpected enum value: expected one of '
+ .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ ' # Expected boolean',
+ ' + sc smartcase value NIL',
+ ' # Expected boolean',
+ ' + sm magic value "TRUE"',
+ ' # Expected integer',
+ ' + so offset value "TRUE"',
+ ' # Expected binary string',
+ ' + sp pattern ="abc"',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'sm': 'TRUE',
+ 'sc': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ 'so': 'TRUE',
+ 'sp': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]},
+ 'rt': 10,
+ 'rc': '10',
+ 'n': -0x40,
+ 'l': -10,
+ 'c': 'abc',
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Expected array of binary strings',
+ ' + rc contents ["abc", ="abc"]',
+ ' # Expected integer',
+ ' + rt type "ABC"',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'rt': 'ABC',
+ 'rc': ["abc", {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]}],
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + rc contents ["abc", "a\\nd\\0"]',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'rc': ["abc", {'_TYPE': v:msgpack_types.binary, '_VAL': ["a", "d\n"]}],
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with search pattern items', function()
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=2, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 'abc',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ ' + sX NIL',
+ ' + sY NIL',
+ ' + sZ NIL',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 'abc',
+ 'sZ': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ 'sY': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ 'sX': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 'abc',
+ 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'so': 0,
+ 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Required key missing: sp',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern ""',
+ ' + sh v:hlsearch value TRUE',
+ ' + ss is :s pattern TRUE',
+ ' + sm magic value FALSE',
+ ' + sc smartcase value TRUE',
+ ' + sl has line offset TRUE',
+ ' + se place cursor at end TRUE',
+ ' + so offset value -10',
+ ' + su is last used FALSE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': '',
+ 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'so': -10,
+ 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Expected binary string',
+ ' + sp pattern 0',
+ ' # Expected boolean',
+ ' + sh v:hlsearch value 0',
+ ' # Expected boolean',
+ ' + ss is :s pattern 0',
+ ' # Expected boolean',
+ ' + sm magic value 0',
+ ' # Expected boolean',
+ ' + sc smartcase value 0',
+ ' # Expected boolean',
+ ' + sl has line offset 0',
+ ' # Expected boolean',
+ ' + se place cursor at end 0',
+ ' # Expected integer',
+ ' + so offset value ""',
+ ' # Expected boolean',
+ ' + su is last used 0',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 0,
+ 'sh': 0,
+ 'ss': 0,
+ 'sm': 0,
+ 'sc': 0,
+ 'sl': 0,
+ 'se': 0,
+ 'so': '',
+ 'su': 0,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with replacement string items', function()
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=3, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected binary string',
+ ' - :s replacement string 0',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ 0,
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected no NUL bytes',
+ ' - :s replacement string "abc\\0def"',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ ' - 0',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
+ 0,
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with history entry items', function()
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=4, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected integer',
+ ' - history type ""',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 5,
+ ''
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ ' - 32',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 5,
+ '',
+ 0x20
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents ""',
+ ' - 32',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 0,
+ '',
+ 0x20
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' - separator \' \'',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ '',
+ 0x20
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type EXPR',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 2,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type INPUT',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 3,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 4,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' # Expected binary string',
+ ' - contents 10',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 4,
+ 10,
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' # Expected no NUL bytes',
+ ' - contents "abc\\0def"',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 4,
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents "abc"',
+ ' # Expected integer',
+ ' - separator ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ 'abc',
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents "abc"',
+ ' # Value is negative',
+ ' - separator -1',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ 'abc',
+ -1,
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with register items', function()
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=5, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents ["abc", "def"]',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ["abc", "def"],
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ 'rw': 0,
+ 'rt': 0,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 5',
+ ' + rt type LINEWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ 'rw': 5,
+ 'rt': 1,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' # Expected integer',
+ ' + rw block width ""',
+ ' + rt type BLOCKWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ 'rw': "",
+ 'rt': 2,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Expected array value',
+ ' + rc contents 0',
+ ' # Value is negative',
+ ' + rw block width -1',
+ ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), '
+ .. '1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': 0,
+ 'rw': -1,
+ 'rt': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with variable items', function()
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=6, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected binary string',
+ ' - name 1',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ 1
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected no NUL bytes',
+ ' - name "\\0"',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
+ {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ ' - NIL',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
+ {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
+ {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with global mark items', function()
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=7, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected integer',
+ ' + n name "foo"',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' + f file name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Value is negative',
+ ' + n name -10',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name 20',
+ ' + f file name "foo"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name 20',
+ ' + f file name "foo"',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': char2nr('A'),
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with jump items', function()
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=8, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Expected integer',
+ ' + n name "foo"',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Value is negative',
+ ' + n name -10',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ ' + n name \' \'',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with buffer list items', function()
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=9, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [[], []]',
+ }, {{type=9, timestamp=0, data={{}, {}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": 10}, []]',
+ }, {{type=9, timestamp=0, data={{a=10}, {}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' + a 10',
+ }, {{type=9, timestamp=0, data={{a=10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Expected integer',
+ ' + l line number "10"',
+ ' # Expected integer',
+ ' + c column "10"',
+ ' + a 10',
+ }, {{type=9, timestamp=0, data={{l='10', c='10', a=10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 10',
+ ' + c column 10',
+ ' + a 10',
+ }, {{type=9, timestamp=0, data={{l=10, c=10, a=10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, {{type=9, timestamp=0, data={{l=-10, c=-10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "abc"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, {{type=9, timestamp=0, data={{f='abc'}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ ' + l line number 1',
+ ' + c column 0',
+ }, {{type=9, timestamp=0, data={{f=10}, {f=20}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 9, 'timestamp': 0, 'data': [
+ {'f': 10},
+ {'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}},
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with local mark items', function()
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=10, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + n name \'"\'',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Expected integer',
+ ' + n name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + n name \'"\'',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' # Value is negative',
+ ' + n name -10',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + n name 20',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + n name 20',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + n name \'a\'',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': char2nr('a'),
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with change items', function()
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=11, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Expected integer',
+ ' + n name "foo"',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Value is negative',
+ ' + n name -10',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ ' + n name \' \'',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+ end)
+
+ describe('function shada#get_strings', function()
+ it('works', function()
+ eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Value',
+ }, nvim_eval('shada#get_strings(msgpackdump([1, 0, 0, {}]))'))
+ end)
+ end)
+
+ describe('function shada#strings_to_sd', function()
+
+ local strings2sd_eq = function(expected, input)
+ nvim('set_var', '__input', input)
+ nvim_command('let g:__actual = map(shada#strings_to_sd(g:__input), '
+ .. '"filter(v:val, \\"v:key[0] isnot# \'_\' '
+ .. '&& v:key isnot# \'length\'\\")")')
+ -- print()
+ if type(expected) == 'table' then
+ nvim('set_var', '__expected', expected)
+ nvim_command('let g:__expected = ModifyVal(g:__expected)')
+ expected = 'g:__expected'
+ -- print(nvim_eval('msgpack#string(g:__expected)'))
+ end
+ -- print(nvim_eval('msgpack#string(g:__actual)'))
+ eq(1, nvim_eval(('msgpack#equal(%s, g:__actual)'):format(expected)))
+ if type(expected) == 'table' then
+ nvim_command('unlet g:__expected')
+ end
+ nvim_command('unlet g:__input')
+ nvim_command('unlet g:__actual')
+ end
+
+ assert:set_parameter('TableFormatLevel', 100)
+
+ it('works with multiple items', function()
+ strings2sd_eq({{
+ type=11, timestamp=0, data={
+ f='foo',
+ l=2,
+ c=200,
+ mX=10,
+ mYYYYYYYYYY=10,
+ n=(' '):byte(),
+ }
+ }, {
+ type=1, timestamp=0, data={
+ c='abc',
+ f={'!binary', {'abc\ndef'}},
+ l=-10,
+ n=-64,
+ rc='10',
+ rt=10,
+ sc={'!nil', 0},
+ sm='TRUE',
+ so='TRUE',
+ sp={'!string', {'abc'}},
+ }
+ }}, {
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ ' + n name \' \'',
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description____ Value',
+ ' # Expected integer',
+ ' + c column "abc"',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + n name -64',
+ ' # Expected array value',
+ ' + rc contents "10"',
+ ' # Unexpected enum value: expected one of '
+ .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ ' # Expected boolean',
+ ' + sc smartcase value NIL',
+ ' # Expected boolean',
+ ' + sm magic value "TRUE"',
+ ' # Expected integer',
+ ' + so offset value "TRUE"',
+ ' # Expected binary string',
+ ' + sp pattern ="abc"',
+ })
+ end)
+
+ it('works with empty list', function()
+ strings2sd_eq({}, {})
+ end)
+
+ it('works with header items', function()
+ strings2sd_eq({{type=1, timestamp=0, data={
+ generator='test',
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ strings2sd_eq({{type=1, timestamp=0, data={
+ 1, 2, 3,
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=1, timestamp=0, data={
+ a=1, b=2, c=3, d=4,
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + a 1',
+ ' + b 2',
+ ' + c column 3',
+ ' + d 4',
+ })
+ strings2sd_eq({{type=1, timestamp=0, data={
+ c='abc',
+ f={'!binary', {'abc\ndef'}},
+ l=-10,
+ n=-64,
+ rc='10',
+ rt=10,
+ sc={'!nil', 0},
+ sm='TRUE',
+ so='TRUE',
+ sp={'!string', {'abc'}},
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description____ Value',
+ ' # Expected integer',
+ ' + c column "abc"',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + n name -64',
+ ' # Expected array value',
+ ' + rc contents "10"',
+ ' # Unexpected enum value: expected one of '
+ .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ ' # Expected boolean',
+ ' + sc smartcase value NIL',
+ ' # Expected boolean',
+ ' + sm magic value "TRUE"',
+ ' # Expected integer',
+ ' + so offset value "TRUE"',
+ ' # Expected binary string',
+ ' + sp pattern ="abc"',
+ })
+ end)
+
+ it('works with search pattern items', function()
+ strings2sd_eq({{type=2, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp='abc',
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp='abc',
+ sX={'!nil', 0},
+ sY={'!nil', 0},
+ sZ={'!nil', 0},
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ ' + sX NIL',
+ ' + sY NIL',
+ ' + sZ NIL',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={'!map', {
+ }}}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Required key missing: sp',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp='',
+ sh={'!boolean', 1},
+ ss={'!boolean', 1},
+ sc={'!boolean', 1},
+ sl={'!boolean', 1},
+ se={'!boolean', 1},
+ sm={'!boolean', 0},
+ su={'!boolean', 0},
+ so=-10,
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern ""',
+ ' + sh v:hlsearch value TRUE',
+ ' + ss is :s pattern TRUE',
+ ' + sm magic value FALSE',
+ ' + sc smartcase value TRUE',
+ ' + sl has line offset TRUE',
+ ' + se place cursor at end TRUE',
+ ' + so offset value -10',
+ ' + su is last used FALSE',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp=0,
+ sh=0,
+ ss=0,
+ sc=0,
+ sl=0,
+ se=0,
+ sm=0,
+ su=0,
+ so='',
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Expected binary string',
+ ' + sp pattern 0',
+ ' # Expected boolean',
+ ' + sh v:hlsearch value 0',
+ ' # Expected boolean',
+ ' + ss is :s pattern 0',
+ ' # Expected boolean',
+ ' + sm magic value 0',
+ ' # Expected boolean',
+ ' + sc smartcase value 0',
+ ' # Expected boolean',
+ ' + sl has line offset 0',
+ ' # Expected boolean',
+ ' + se place cursor at end 0',
+ ' # Expected integer',
+ ' + so offset value ""',
+ ' # Expected boolean',
+ ' + su is last used 0',
+ })
+ end)
+
+ it('works with replacement string items', function()
+ strings2sd_eq({{type=3, timestamp=0, data={
+ a={10}
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ 0
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected binary string',
+ ' - :s replacement string 0',
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ 'abc\ndef', 0,
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ ' - 0',
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ 'abc\ndef',
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ })
+ end)
+
+ it('works with history entry items', function()
+ strings2sd_eq({{type=4, timestamp=0, data={
+ a={10},
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected integer',
+ ' - history type ""',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 5, '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 5, '', 32,
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ ' - 32',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 0, '', 32,
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents ""',
+ ' - 32',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 1, '', 32,
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' - separator \' \'',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 1, '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' # Expected more elements in list',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 2, '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type EXPR',
+ ' - contents ""',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 3, ''
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type INPUT',
+ ' - contents ""',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 4, ''
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' - contents ""',
+ })
+ end)
+
+ it('works with register items', function()
+ strings2sd_eq({{type=5, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={'!map', {
+ }}}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte()
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(), rc={'abc', 'def'}
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents ["abc", "def"]',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'},
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'},
+ rw=5,
+ rt=1,
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 5',
+ ' + rt type LINEWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'},
+ rw=5,
+ rt=2,
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 5',
+ ' + rt type BLOCKWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc=0,
+ rw=-1,
+ rt=10,
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Expected array value',
+ ' + rc contents 0',
+ ' # Value is negative',
+ ' + rw block width -1',
+ ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), '
+ .. '1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ })
+ end)
+
+ it('works with variable items', function()
+ strings2sd_eq({{type=6, timestamp=0, data={
+ a={10}
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ 'foo',
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' # Expected more elements in list',
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ 'foo', {'!nil', 0},
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ 'foo', {'!nil', 0}, {'!nil', 0}
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ ' - NIL',
+ })
+ end)
+
+ it('works with global mark items', function()
+ strings2sd_eq({{type=7, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=7, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+
+ it('works with jump items', function()
+ strings2sd_eq({{type=8, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=8, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+
+ it('works with buffer list items', function()
+ strings2sd_eq({{type=9, timestamp=0, data={
+ a={10}
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {a=10}, {}
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": 10}, []]',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {a=10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' + a 10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {l='10', c='10', a=10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Expected integer',
+ ' + l line number "10"',
+ ' # Expected integer',
+ ' + c column "10"',
+ ' + a 10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {l=10, c=10, a=10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 10',
+ ' + c column 10',
+ ' + a 10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {l=-10, c=-10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {f='abc'},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "abc"',
+ ' + l line number 1',
+ ' + c column 0',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {f=10}, {f=20},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ ' + l line number 1',
+ ' + c column 0',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {f=10}, {f={'!binary', {'\n'}}},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ })
+ end)
+
+ it('works with local mark items', function()
+ strings2sd_eq({{type=10, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=10, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+
+ it('works with change items', function()
+ strings2sd_eq({{type=11, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Change with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=11, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+ end)
+
+ describe('function shada#get_binstrings', function()
+ local getbstrings_eq = function(expected, input)
+ local result = funcs['shada#get_binstrings'](input)
+ for i, s in ipairs(result) do
+ result[i] = s:gsub('\n', '\0')
+ end
+ local mpack_result = table.concat(result, '\n')
+ return mpack_eq(expected, mpack_result)
+ end
+
+ it('works', function()
+ getbstrings_eq({{timestamp='current', type=1, value={
+ generator='shada.vim',
+ version=704,
+ }}}, {})
+ getbstrings_eq({
+ {timestamp='current', type=1, value={
+ generator='shada.vim', version=704
+ }},
+ {timestamp=0, type=1, value={generator='test'}}
+ }, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ nvim('set_var', 'shada#add_own_header', 1)
+ getbstrings_eq({{timestamp='current', type=1, value={
+ generator='shada.vim',
+ version=704,
+ }}}, {})
+ getbstrings_eq({
+ {timestamp='current', type=1, value={
+ generator='shada.vim', version=704
+ }},
+ {timestamp=0, type=1, value={generator='test'}}
+ }, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ nvim('set_var', 'shada#add_own_header', 0)
+ getbstrings_eq({}, {})
+ getbstrings_eq({{timestamp=0, type=1, value={generator='test'}}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ nvim('set_var', 'shada#keep_old_header', 0)
+ getbstrings_eq({}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ getbstrings_eq({
+ {type=3, timestamp=0, value={'abc\ndef'}},
+ {type=3, timestamp=0, value={'abc\ndef'}},
+ {type=3, timestamp=0, value={'abc\ndef'}},
+ }, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ })
+ end)
+ end)
+end)
+
+describe('In plugin/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(function()
+ reset()
+ os.remove(fname)
+ os.remove(fname .. '.tst')
+ os.remove(fname_tmp)
+ end)
+
+ local shada_eq = function(expected, fname)
+ local fd = io.open(fname)
+ local mpack_result = fd:read('*a')
+ fd:close()
+ mpack_eq(expected, mpack_result)
+ end
+
+ describe('event BufReadCmd', function()
+ it('works', function()
+ wshada('\004\000\009\147\000\196\002ab\196\001a')
+ wshada_tmp('\004\000\009\147\000\196\002ab\196\001b')
+ nvim_command('edit ' .. fname)
+ eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(false, curbuf('get_option', 'modified'))
+ eq('shada', curbuf('get_option', 'filetype'))
+ nvim_command('edit ' .. fname_tmp)
+ eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "b"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(false, curbuf('get_option', 'modified'))
+ eq('shada', curbuf('get_option', 'filetype'))
+ eq('++opt not supported', exc_exec('edit ++enc=latin1 ' .. fname))
+ neq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ }, nvim_eval('getline(1, "$")'))
+ neq(true, curbuf('get_option', 'modified'))
+ end)
+ end)
+
+ describe('event FileReadCmd', function()
+ it('works', function()
+ wshada('\004\000\009\147\000\196\002ab\196\001a')
+ wshada_tmp('\004\000\009\147\000\196\002ab\196\001b')
+ nvim_command('$read ' .. fname)
+ eq({
+ '',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(true, curbuf('get_option', 'modified'))
+ neq('shada', curbuf('get_option', 'filetype'))
+ nvim_command('1,$read ' .. fname_tmp)
+ eq({
+ '',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "b"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(true, curbuf('get_option', 'modified'))
+ neq('shada', curbuf('get_option', 'filetype'))
+ curbuf('set_option', 'modified', false)
+ eq('++opt not supported', exc_exec('$read ++enc=latin1 ' .. fname))
+ eq({
+ '',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "b"',
+ }, nvim_eval('getline(1, "$")'))
+ neq(true, curbuf('get_option', 'modified'))
+ end)
+ end)
+
+ describe('event BufWriteCmd', function()
+ it('works', function()
+ nvim('set_var', 'shada#add_own_header', 0)
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ })
+ nvim_command('w ' .. fname .. '.tst')
+ nvim_command('w ' .. fname)
+ nvim_command('w ' .. fname_tmp)
+ eq('++opt not supported', exc_exec('w! ++enc=latin1 ' .. fname))
+ eq(table.concat({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ }, '\n') .. '\n', io.open(fname .. '.tst'):read('*a'))
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname)
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname_tmp)
+ end)
+ end)
+
+ describe('event FileWriteCmd', function()
+ it('works', function()
+ nvim('set_var', 'shada#add_own_header', 0)
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ })
+ nvim_command('1,3w ' .. fname .. '.tst')
+ nvim_command('1,3w ' .. fname)
+ nvim_command('1,3w ' .. fname_tmp)
+ eq('++opt not supported', exc_exec('1,3w! ++enc=latin1 ' .. fname))
+ eq(table.concat({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ }, '\n') .. '\n', io.open(fname .. '.tst'):read('*a'))
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }}, fname)
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }}, fname_tmp)
+ end)
+ end)
+
+ describe('event FileAppendCmd', function()
+ it('works', function()
+ nvim('set_var', 'shada#add_own_header', 0)
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ })
+ funcs.writefile({''}, fname .. '.tst', 'b')
+ funcs.writefile({''}, fname, 'b')
+ funcs.writefile({''}, fname_tmp, 'b')
+ nvim_command('1,3w >> ' .. fname .. '.tst')
+ nvim_command('1,3w >> ' .. fname)
+ nvim_command('1,3w >> ' .. fname_tmp)
+ nvim_command('w >> ' .. fname .. '.tst')
+ nvim_command('w >> ' .. fname)
+ nvim_command('w >> ' .. fname_tmp)
+ eq('++opt not supported', exc_exec('1,3w! ++enc=latin1 >> ' .. fname))
+ eq(table.concat({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ }, '\n') .. '\n', io.open(fname .. '.tst'):read('*a'))
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname)
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname_tmp)
+ end)
+ end)
+
+ describe('event SourceCmd', function()
+ before_each(function()
+ reset(fname)
+ end)
+ it('works', function()
+ wshada('\004\000\006\146\000\196\002ab')
+ wshada_tmp('\004\001\006\146\000\196\002bc')
+ eq(0, exc_exec('source ' .. fname))
+ eq(0, exc_exec('source ' .. fname_tmp))
+ eq('bc', funcs.histget(':', -1))
+ eq('ab', funcs.histget(':', -2))
+ end)
+ end)
+end)
+
+describe('ftplugin/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(reset)
+
+ it('sets indentexpr correctly', function()
+ nvim_command('filetype plugin indent on')
+ nvim_command('setlocal filetype=shada')
+ funcs.setline(1, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ '% Key________ Description Value',
+ '+ n name \'A\'',
+ '+ f file name "foo"',
+ '+ l line number 2',
+ '+ c column 200',
+ '+ mX 10',
+ '+ mYYYYYYYYYY 10',
+ 'Register with timestamp ' .. epoch .. ':',
+ '% Key Description Value',
+ '+ n name \' \'',
+ '+ rc contents @',
+ '| - "abcdefghijklmnopqrstuvwxyz"',
+ '| - "abcdefghijklmnopqrstuvwxyz"',
+ '+ rw block width 0',
+ '+ rt type CHARACTERWISE',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ ' Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ '= [{="a": 10}, []]',
+ ' Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ '+ f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ '+ l line number 1',
+ ' + c column 0',
+ })
+ nvim_command('normal! gg=G')
+ eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": 10}, []]',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ ' + l line number 1',
+ ' + c column 0',
+ }, funcs.getline(1, funcs.line('$')))
+ end)
+
+ it('sets options correctly', function()
+ nvim_command('filetype plugin indent on')
+ nvim_command('setlocal filetype=shada')
+ eq(true, curbuf('get_option', 'expandtab'))
+ eq(2, curbuf('get_option', 'tabstop'))
+ eq(2, curbuf('get_option', 'softtabstop'))
+ eq(2, curbuf('get_option', 'shiftwidth'))
+ end)
+
+ it('sets indentkeys correctly', function()
+ nvim_command('filetype plugin indent on')
+ nvim_command('setlocal filetype=shada')
+ funcs.setline(1, ' Replacement with timestamp ' .. epoch)
+ nvim_feed('ggA:\027')
+ eq('Replacement with timestamp ' .. epoch .. ':', curbuf('get_line', 0))
+ nvim_feed('o-\027')
+ eq(' -', curbuf('get_line', 1))
+ nvim_feed('ggO+\027')
+ eq('+', curbuf('get_line', 0))
+ nvim_feed('GO*\027')
+ eq(' *', curbuf('get_line', 2))
+ nvim_feed('ggO /\027')
+ eq(' /', curbuf('get_line', 0))
+ nvim_feed('ggOx\027')
+ eq('x', curbuf('get_line', 0))
+ end)
+end)
+
+describe('syntax/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(reset)
+
+ it('works', function()
+ nvim_command('syntax on')
+ nvim_command('setlocal syntax=shada')
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Value',
+ ' + t "test"',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + rc contents @',
+ ' | - {"abcdefghijklmnopqrstuvwxyz": 1.0}',
+ ' + rt type CHARACTERWISE',
+ ' + rt type LINEWISE',
+ ' + rt type BLOCKWISE',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string CMD',
+ ' - :s replacement string SEARCH',
+ ' - :s replacement string EXPR',
+ ' - :s replacement string INPUT',
+ ' - :s replacement string DEBUG',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": +(10)"ac\\0df\\ngi\\"tt\\.", TRUE: FALSE}, [NIL, +(-10)""]]',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ '',
+ ' % Key Description Value',
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + se place cursor at end TRUE',
+ })
+ nvim_command([[
+ function GetSyntax()
+ let lines = []
+ for l in range(1, line('$'))
+ let columns = []
+ let line = getline(l)
+ for c in range(1, col([l, '$']) - 1)
+ let synstack = map(synstack(l, c), 'synIDattr(v:val, "name")')
+ if !empty(columns) && columns[-1][0] ==# synstack
+ let columns[-1][1] .= line[c - 1]
+ else
+ call add(columns, [ synstack, line[c - 1] ])
+ endif
+ endfor
+ call add(lines, columns)
+ endfor
+ return lines
+ endfunction
+ ]])
+ local hname = function(s) return {{'ShaDaEntryHeader', 'ShaDaEntryName'},
+ s} end
+ local h = function(s) return {{'ShaDaEntryHeader'}, s} end
+ local htsnum = function(s) return {
+ {'ShaDaEntryHeader', 'ShaDaEntryTimestamp', 'ShaDaEntryTimestampNumber'},
+ s
+ } end
+ local synhtssep = function(s)
+ return {{'ShaDaEntryHeader', 'ShaDaEntryTimestamp'}, s}
+ end
+ local synepoch = {
+ year = htsnum(os.date('%Y', 0)),
+ month = htsnum(os.date('%m', 0)),
+ day = htsnum(os.date('%d', 0)),
+ hour = htsnum(os.date('%H', 0)),
+ minute = htsnum(os.date('%M', 0)),
+ second = htsnum(os.date('%S', 0)),
+ }
+ local msh = function(s) return {{'ShaDaEntryMapShort',
+ 'ShaDaEntryMapHeader'}, s} end
+ local mlh = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapHeader'}, s} end
+ local ah = function(s) return {{'ShaDaEntryArray',
+ 'ShaDaEntryArrayHeader'}, s} end
+ local mses = function(s) return {{'ShaDaEntryMapShort',
+ 'ShaDaEntryMapShortEntryStart'}, s} end
+ local mles = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapLongEntryStart'}, s} end
+ local act = funcs.GetSyntax()
+ local ms = function(syn)
+ return {
+ {'ShaDaEntryMap' .. syn, 'ShaDaEntryMap' .. syn .. 'EntryStart'}, ' + '
+ }
+ end
+ local as = function()
+ return {{'ShaDaEntryArray', 'ShaDaEntryArrayEntryStart'}, ' - '}
+ end
+ local ad = function(s) return {{'ShaDaEntryArray',
+ 'ShaDaEntryArrayDescription'}, s} end
+ local mbas = function(syn)
+ return {
+ {'ShaDaEntryMap' .. syn, 'ShaDaEntryMapBinArrayStart'},
+ ' | - '
+ }
+ end
+ local msk = function(s) return {{'ShaDaEntryMapShort',
+ 'ShaDaEntryMapShortKey'}, s} end
+ local mlk = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapLongKey'}, s} end
+ local mld = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapLongDescription'}, s} end
+ local c = function(s) return {{'ShaDaComment'}, s} end
+ local exp = {
+ {
+ hname('Header'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ msh(' % Key Value'),
+ },
+ {
+ ms('Short'), msk('t '),
+ {{'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString'}, 'test'},
+ {{'ShaDaEntryMapShort', 'ShaDaMsgpackStringQuotes'}, '"'},
+ },
+ {
+ hname('Jump'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key________ Description Value'),
+ },
+ {
+ ms('Long'), mlk('n '), mld('name '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackCharacter'}, '\'A\''},
+ },
+ {
+ ms('Long'), mlk('f '), mld('file name '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray',
+ 'ShaDaMsgpackArrayBraces'}, '['},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString'},
+ 'foo'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArrayBraces'}, ']'},
+ },
+ {
+ ms('Long'), mlk('l '), mld('line number '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackInteger'}, '2'},
+ },
+ {
+ ms('Long'), mlk('c '), mld('column '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackInteger'}, '-200'},
+ },
+ {
+ hname('Register'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key Description Value'),
+ },
+ {
+ ms('Long'), mlk('rc '), mld('contents '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMultilineArray'}, '@'},
+ },
+ {
+ mbas('Long'),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces'},
+ '{'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'abcdefghijklmnopqrstuvwxyz'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackFloat'}, '1.0'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMapBraces'}, '}'},
+ },
+ {
+ ms('Long'), mlk('rt '), mld('type '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'CHARACTERWISE'},
+ },
+ {
+ ms('Long'), mlk('rt '), mld('type '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'LINEWISE'},
+ },
+ {
+ ms('Long'), mlk('rt '), mld('type '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'BLOCKWISE'},
+ },
+ {
+ hname('Replacement string'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ ah(' @ Description__________ Value'),
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'CMD'},
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'SEARCH'},
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'EXPR'},
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'INPUT'},
+ },
+ {
+ {{'ShaDaEntryArrayEntryStart'}, ' - '},
+ {{'ShaDaEntryArrayDescription'}, ':s replacement string '},
+ {{'ShaDaMsgpackShaDaKeyword'}, 'DEBUG'},
+ },
+ {
+ hname('Buffer list'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ c(' # Expected array of maps'),
+ },
+ {
+ {{'ShaDaEntryRawMsgpack'}, ' = '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'}, '['},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces'},
+ '{'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackString'}, '='},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'a'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt'}, '+('},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt',
+ 'ShaDaMsgpackExtType'}, '10'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt'}, ')'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'ac'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackBinaryStringEscape'},
+ '\\0'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'df'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackBinaryStringEscape'},
+ '\\n'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'gi'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackBinaryStringEscape'},
+ '\\"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'tt\\.'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackComma'}, ','},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword'},
+ 'TRUE'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword'},
+ 'FALSE'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMapBraces'}, '}'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackComma'}, ','},
+ {{'ShaDaMsgpackArray'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'},
+ '['},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackKeyword'},
+ 'NIL'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackComma'}, ','},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt'}, '+('},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt',
+ 'ShaDaMsgpackExtType'}, '-10'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt'}, ')'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'}, ']'},
+ {{'ShaDaMsgpackArrayBraces'}, ']'},
+ },
+ {
+ hname('Buffer list'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key Description Value'),
+ },
+ {
+ },
+ {
+ mlh(' % Key Description Value'),
+ },
+ {
+ hname('Header'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key Description________ Value'),
+ },
+ {
+ {{'ShaDaEntryMapLongEntryStart'}, ' + '},
+ {{'ShaDaEntryMapLongKey'}, 'se '},
+ {{'ShaDaEntryMapLongDescription'}, 'place cursor at end '},
+ {{'ShaDaMsgpackKeyword'}, 'TRUE'},
+ },
+ }
+ eq(exp, act)
+ end)
+end)