diff options
Diffstat (limited to 'test/functional')
99 files changed, 4247 insertions, 265 deletions
diff --git a/test/functional/api/menu_spec.lua b/test/functional/api/menu_spec.lua index 34d23ca098..5b414fb559 100644 --- a/test/functional/api/menu_spec.lua +++ b/test/functional/api/menu_spec.lua @@ -19,7 +19,7 @@ describe("update_menu notification", function() screen:detach() end) - function expect_sent(expected) + local function expect_sent(expected) screen:wait(function() if screen.update_menu ~= expected then if expected then diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 4c7122a549..a3ac864f79 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -95,13 +95,13 @@ describe('server -> client', function() eq('notified!', eval('rpcrequest('..cid..', "notify")')) end - local function on_request(method, args) + local function on_request(method) eq('notify', method) eq(1, eval('rpcnotify('..cid..', "notification")')) return 'notified!' end - local function on_notification(method, args) + local function on_notification(method) eq('notification', method) if notified == expected then stop() diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index eb4804f141..cba0b7533b 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -180,6 +180,8 @@ describe('vim_* functions', function() end) describe('err_write', function() + local screen + before_each(function() clear() screen = Screen.new(40, 8) diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index 456252522d..17aacafe9b 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -1,9 +1,9 @@ -- Sanity checks for window_* API calls via msgpack-rpc local helpers = require('test.functional.helpers') -local clear, nvim, buffer, curbuf, curbuf_contents, window, curwin, eq, neq, - ok, feed, rawfeed, insert, eval = helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, +local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq, + ok, feed, insert, eval = helpers.clear, helpers.nvim, helpers.curbuf, helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq, - helpers.neq, helpers.ok, helpers.feed, helpers.rawfeed, helpers.insert, helpers.eval + helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval local wait = helpers.wait -- check if str is visible at the beginning of some line @@ -54,7 +54,7 @@ describe('window_* functions', function() insert("prologue") feed('100o<esc>') insert("epilogue") - win = curwin() + local win = curwin() feed('gg') wait() -- let nvim process the 'gg' command diff --git a/test/functional/autocmd/tabclose_spec.lua b/test/functional/autocmd/tabclose_spec.lua index 847362e3de..bf609d1846 100644 --- a/test/functional/autocmd/tabclose_spec.lua +++ b/test/functional/autocmd/tabclose_spec.lua @@ -1,7 +1,5 @@ local helpers = require('test.functional.helpers') -local clear, nvim, buffer, curbuf, curwin, eq, neq, ok = - helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin, - helpers.eq, helpers.neq, helpers.ok +local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq describe('TabClosed', function() describe('au TabClosed', function() @@ -20,7 +18,6 @@ describe('TabClosed', function() end) describe('with NR as <afile>', function() it('matches when closing a tab whose index is NR', function() - tmp_path = nvim('eval', 'tempname()') nvim('command', 'au! TabClosed 2 echom "tabclosed:match"') repeat nvim('command', 'tabnew') diff --git a/test/functional/autocmd/tabnew_spec.lua b/test/functional/autocmd/tabnew_spec.lua index d80644cd92..5ab504889b 100644 --- a/test/functional/autocmd/tabnew_spec.lua +++ b/test/functional/autocmd/tabnew_spec.lua @@ -1,7 +1,5 @@ local helpers = require('test.functional.helpers') -local clear, nvim, buffer, curbuf, curwin, eq, neq, ok = - helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin, - helpers.eq, helpers.neq, helpers.ok +local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq describe('TabNew', function() setup(clear) @@ -15,7 +13,7 @@ describe('TabNew', function() end) describe('with FILE as <afile>', function() it('matches when opening a new tab for FILE', function() - tmp_path = nvim('eval', 'tempname()') + local tmp_path = nvim('eval', 'tempname()') nvim('command', 'au! TabNew '..tmp_path..' echom "tabnew:match"') eq("\ntabnew:4:3\ntabnew:match\n\""..tmp_path.."\" [New File]", nvim('command_output', 'tabnew '..tmp_path)) end) diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua index f220c15ef7..64b9a22f41 100644 --- a/test/functional/autocmd/tabnewentered_spec.lua +++ b/test/functional/autocmd/tabnewentered_spec.lua @@ -1,7 +1,5 @@ local helpers = require('test.functional.helpers') -local clear, nvim, buffer, curbuf, curwin, eq, neq, ok = - helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin, - helpers.eq, helpers.neq, helpers.ok +local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq describe('TabNewEntered', function() describe('au TabNewEntered', function() @@ -15,7 +13,7 @@ describe('TabNewEntered', function() end) describe('with FILE as <afile>', function() it('matches when opening a new tab for FILE', function() - tmp_path = nvim('eval', 'tempname()') + local tmp_path = nvim('eval', 'tempname()') nvim('command', 'au! TabNewEntered '..tmp_path..' echom "tabnewentered:match"') eq("\n\""..tmp_path.."\" [New File]\ntabnewentered:4:4\ntabnewentered:match", nvim('command_output', 'tabnew '..tmp_path)) end) diff --git a/test/functional/autocmd/termclose_spec.lua b/test/functional/autocmd/termclose_spec.lua index 265d857a42..0961340e61 100644 --- a/test/functional/autocmd/termclose_spec.lua +++ b/test/functional/autocmd/termclose_spec.lua @@ -1,11 +1,11 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') -local clear, eval, execute, feed, nvim, nvim_dir = helpers.clear, helpers.eval, +local clear, execute, feed, nvim, nvim_dir = helpers.clear, helpers.execute, helpers.feed, helpers.nvim, helpers.nvim_dir -local wait = helpers.wait describe('TermClose event', function() + local screen before_each(function() clear() nvim('set_option', 'shell', nvim_dir .. '/shell-test') diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua index 98b8d2dd45..898ec556a2 100644 --- a/test/functional/clipboard/clipboard_provider_spec.lua +++ b/test/functional/clipboard/clipboard_provider_spec.lua @@ -4,7 +4,6 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert local execute, expect, eq, eval = helpers.execute, helpers.expect, helpers.eq, helpers.eval -local nvim, run, stop, restart = helpers.nvim, helpers.run, helpers.stop, helpers.restart local function basic_register_test(noblock) insert("some words") diff --git a/test/functional/eval/glob_spec.lua b/test/functional/eval/glob_spec.lua index f99a9e7d0e..c6bba46424 100644 --- a/test/functional/eval/glob_spec.lua +++ b/test/functional/eval/glob_spec.lua @@ -1,3 +1,4 @@ +local lfs = require('lfs') local helpers = require('test.functional.helpers') local clear, execute, eval, eq = helpers.clear, helpers.execute, helpers.eval, helpers.eq diff --git a/test/functional/eval/msgpack_functions_spec.lua b/test/functional/eval/msgpack_functions_spec.lua index 9a7b630f64..da42fc9d26 100644 --- a/test/functional/eval/msgpack_functions_spec.lua +++ b/test/functional/eval/msgpack_functions_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers') -local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute -local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq -local execute, source = helpers.execute, helpers.source +local clear = helpers.clear +local eval, eq = helpers.eval, helpers.eq +local execute = helpers.execute local nvim = helpers.nvim local exc_exec = helpers.exc_exec @@ -454,9 +454,9 @@ describe('msgpackparse() function', function() it('msgpackparse(systemlist(...)) does not segfault. #3135', function() local cmd = "sort(keys(msgpackparse(systemlist('" ..helpers.nvim_prog.." --api-info'))[0]))" - local api_info = eval(cmd) - api_info = eval(cmd) -- do it again (try to force segfault) - api_info = eval(cmd) -- do it again + eval(cmd) + eval(cmd) -- do it again (try to force segfault) + local api_info = eval(cmd) -- do it again eq({'error_types', 'functions', 'types'}, api_info) end) diff --git a/test/functional/ex_cmds/grep_spec.lua b/test/functional/ex_cmds/grep_spec.lua index 9c792099c1..f3ff0a3817 100644 --- a/test/functional/ex_cmds/grep_spec.lua +++ b/test/functional/ex_cmds/grep_spec.lua @@ -1,7 +1,6 @@ local helpers = require('test.functional.helpers') -local clear, execute, nvim, feed, eq, ok, eval = - helpers.clear, helpers.execute, helpers.nvim, helpers.feed, - helpers.eq, helpers.ok, helpers.eval +local clear, execute, feed, ok, eval = + helpers.clear, helpers.execute, helpers.feed, helpers.ok, helpers.eval describe(':grep', function() before_each(clear) diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua index e02f42cd12..dac6757a97 100644 --- a/test/functional/ex_cmds/oldfiles_spec.lua +++ b/test/functional/ex_cmds/oldfiles_spec.lua @@ -2,7 +2,7 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers') local buf, eq, execute = helpers.curbufmeths, helpers.eq, helpers.execute -local feed, nvim, nvim_prog = helpers.feed, helpers.nvim, helpers.nvim_prog +local feed, nvim_prog = helpers.feed, helpers.nvim_prog local ok, set_session, spawn = helpers.ok, helpers.set_session, helpers.spawn local shada_file = 'test.shada' @@ -11,9 +11,6 @@ local shada_file = 'test.shada' -- helpers.clear() uses "-i NONE", which is not useful for this test. -- local function _clear() - if session then - session:exit(0) - end set_session(spawn({nvim_prog, '-u', 'NONE', '--cmd', 'set noswapfile undodir=. directory=. viewdir=. backupdir=.', @@ -32,7 +29,7 @@ describe(':oldfiles', function() end it('shows most recently used files', function() - screen = Screen.new(100, 5) + local screen = Screen.new(100, 5) screen:attach() execute('edit testfile1') execute('edit testfile2') diff --git a/test/functional/ex_cmds/profile_spec.lua b/test/functional/ex_cmds/profile_spec.lua index 721669e73b..744b22621f 100644 --- a/test/functional/ex_cmds/profile_spec.lua +++ b/test/functional/ex_cmds/profile_spec.lua @@ -1,5 +1,5 @@ require('os') -require('lfs') +local lfs = require('lfs') local helpers = require('test.functional.helpers') local eval = helpers.eval diff --git a/test/functional/ex_cmds/quit_spec.lua b/test/functional/ex_cmds/quit_spec.lua index 3cd8e19617..a8156228d3 100644 --- a/test/functional/ex_cmds/quit_spec.lua +++ b/test/functional/ex_cmds/quit_spec.lua @@ -1,5 +1,5 @@ local helpers = require('test.functional.helpers') -local execute, eq, clear = helpers.execute, helpers.eq, helpers.clear +local clear = helpers.clear describe(':qa', function() before_each(function() diff --git a/test/functional/ex_cmds/recover_spec.lua b/test/functional/ex_cmds/recover_spec.lua index 6749cfaf40..e1d01f6896 100644 --- a/test/functional/ex_cmds/recover_spec.lua +++ b/test/functional/ex_cmds/recover_spec.lua @@ -1,6 +1,7 @@ -- Tests for :recover local helpers = require('test.functional.helpers') +local lfs = require('lfs') local execute, eq, clear, eval, feed, expect, source = helpers.execute, helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.expect, helpers.source diff --git a/test/functional/ex_cmds/sign_spec.lua b/test/functional/ex_cmds/sign_spec.lua index be213cd0d9..c50704504d 100644 --- a/test/functional/ex_cmds/sign_spec.lua +++ b/test/functional/ex_cmds/sign_spec.lua @@ -1,7 +1,5 @@ local helpers = require('test.functional.helpers') -local clear, nvim, buffer, curbuf, curwin, eq, ok = - helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin, - helpers.eq, helpers.ok +local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq describe('sign', function() before_each(clear) diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua index b6b9185cf2..207d94124f 100644 --- a/test/functional/ex_cmds/wviminfo_spec.lua +++ b/test/functional/ex_cmds/wviminfo_spec.lua @@ -1,6 +1,6 @@ local helpers, lfs = require('test.functional.helpers'), require('lfs') -local clear, execute, eq, neq, spawn, nvim_prog, set_session, wait, write_file - = helpers.clear, helpers.execute, helpers.eq, helpers.neq, helpers.spawn, +local execute, eq, neq, spawn, nvim_prog, set_session, wait, write_file + = helpers.execute, helpers.eq, helpers.neq, helpers.spawn, helpers.nvim_prog, helpers.set_session, helpers.wait, helpers.write_file describe(':wshada', function() @@ -13,7 +13,7 @@ describe(':wshada', function() end -- Override the default session because we need 'swapfile' for these tests. - local session = spawn({nvim_prog, '-u', 'NONE', '-i', '/dev/null', '--embed', + session = spawn({nvim_prog, '-u', 'NONE', '-i', '/dev/null', '--embed', '--cmd', 'set swapfile'}) set_session(session) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 8a85f187cf..9562457c8e 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -1,4 +1,5 @@ require('coxpcall') +local lfs = require('lfs') local assert = require('luassert') local Loop = require('nvim.loop') local MsgpackStream = require('nvim.msgpack_stream') @@ -55,7 +56,7 @@ if prepend_argv then nvim_argv = new_nvim_argv end -local session, loop_running, loop_stopped, last_error +local session, loop_running, last_error local function set_session(s) session = s @@ -79,7 +80,7 @@ local function next_message() end local function call_and_stop_on_error(...) - local status, result = copcall(...) + local status, result = copcall(...) -- luacheck: ignore if not status then session:stop() last_error = result @@ -109,7 +110,6 @@ local function run(request_cb, notification_cb, setup_cb, timeout) end end - loop_stopped = false loop_running = true session:run(on_request, on_notification, on_setup, timeout) loop_running = false @@ -121,7 +121,6 @@ local function run(request_cb, notification_cb, setup_cb, timeout) end local function stop() - loop_stopped = true session:stop() end @@ -197,9 +196,9 @@ local function spawn(argv, merge) local loop = Loop.new() local msgpack_stream = MsgpackStream.new(loop) local async_session = AsyncSession.new(msgpack_stream) - local session = Session.new(async_session) + local sess = Session.new(async_session) loop:spawn(merge and merge_args(prepend_argv, argv) or argv) - return session + return sess end local function clear(extra_cmd) @@ -332,14 +331,14 @@ local function rmdir(path) if file == '.' or file == '..' then goto continue end - ret, err = os.remove(path..'/'..file) + local ret, err = os.remove(path..'/'..file) if not ret then error('os.remove: '..err) return nil end ::continue:: end - ret, err = os.remove(path) + local ret, err = os.remove(path) if not ret then error('os.remove: '..err) end @@ -371,15 +370,15 @@ local function redir_exec(cmd) end local function create_callindex(func) - local tbl = {} - setmetatable(tbl, { + local table = {} + setmetatable(table, { __index = function(tbl, arg1) - ret = function(...) return func(arg1, ...) end + local ret = function(...) return func(arg1, ...) end tbl[arg1] = ret return ret end, }) - return tbl + return table end local funcs = create_callindex(nvim_call) diff --git a/test/functional/job/job_spec.lua b/test/functional/job/job_spec.lua index bdaf2a7ec6..0915ab0955 100644 --- a/test/functional/job/job_spec.lua +++ b/test/functional/job/job_spec.lua @@ -1,11 +1,11 @@ local helpers = require('test.functional.helpers') -local clear, eq, eval, execute, expect, feed, insert, neq, next_msg, nvim, - nvim_dir, ok, run, session, source, stop, wait, write_file = helpers.clear, - helpers.eq, helpers.eval, helpers.execute, helpers.expect, helpers.feed, +local clear, eq, eval, execute, feed, insert, neq, next_msg, nvim, + nvim_dir, ok, source, write_file = helpers.clear, + helpers.eq, helpers.eval, helpers.execute, helpers.feed, helpers.insert, helpers.neq, helpers.next_message, helpers.nvim, - helpers.nvim_dir, helpers.ok, helpers.run, helpers.session, helpers.source, - helpers.stop, helpers.wait, helpers.write_file + helpers.nvim_dir, helpers.ok, helpers.source, + helpers.write_file local Screen = require('test.functional.ui.screen') @@ -370,7 +370,7 @@ describe('jobs', function() describe('running tty-test program', function() local function next_chunk() - local rv = '' + local rv while true do local msg = next_msg() local data = msg[3][2] diff --git a/test/functional/legacy/003_cindent_spec.lua b/test/functional/legacy/003_cindent_spec.lua index 1857721563..39de3e8280 100644 --- a/test/functional/legacy/003_cindent_spec.lua +++ b/test/functional/legacy/003_cindent_spec.lua @@ -4,7 +4,7 @@ -- in the original test. These have been converted to "it" test cases here. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect -- Inserts text as usual, and additionally positions the cursor on line 1 and diff --git a/test/functional/legacy/009_bufleave_autocommand_spec.lua b/test/functional/legacy/009_bufleave_autocommand_spec.lua index 0fc1b5b657..8c18639c8f 100644 --- a/test/functional/legacy/009_bufleave_autocommand_spec.lua +++ b/test/functional/legacy/009_bufleave_autocommand_spec.lua @@ -1,7 +1,7 @@ -- Test for Bufleave autocommand that deletes the buffer we are about to edit. local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear, insert = helpers.clear, helpers.insert local execute, expect = helpers.execute, helpers.expect describe('BufLeave autocommand', function() diff --git a/test/functional/legacy/015_alignment_spec.lua b/test/functional/legacy/015_alignment_spec.lua index e71f9d1c90..3b19f4ff42 100644 --- a/test/functional/legacy/015_alignment_spec.lua +++ b/test/functional/legacy/015_alignment_spec.lua @@ -3,7 +3,7 @@ -- Also test undo after ":%s" and formatting. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('alignment', function() diff --git a/test/functional/legacy/022_line_ending_spec.lua b/test/functional/legacy/022_line_ending_spec.lua index 4b897a7c95..a841378a82 100644 --- a/test/functional/legacy/022_line_ending_spec.lua +++ b/test/functional/legacy/022_line_ending_spec.lua @@ -1,7 +1,7 @@ -- Tests for file with some lines ending in CTRL-M, some not local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear, feed = helpers.clear, helpers.feed local execute, expect = helpers.execute, helpers.expect describe('line ending', function() diff --git a/test/functional/legacy/023_edit_arguments_spec.lua b/test/functional/legacy/023_edit_arguments_spec.lua index e68af9758d..15b30bfa3a 100644 --- a/test/functional/legacy/023_edit_arguments_spec.lua +++ b/test/functional/legacy/023_edit_arguments_spec.lua @@ -1,7 +1,7 @@ -- Tests for complicated + argument to :edit command local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear, insert = helpers.clear, helpers.insert local execute, expect = helpers.execute, helpers.expect describe(':edit', function() diff --git a/test/functional/legacy/026_execute_while_if_spec.lua b/test/functional/legacy/026_execute_while_if_spec.lua index ffe37819de..f17bb79702 100644 --- a/test/functional/legacy/026_execute_while_if_spec.lua +++ b/test/functional/legacy/026_execute_while_if_spec.lua @@ -1,7 +1,7 @@ -- Test for :execute, :while and :if local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear = helpers.clear local execute, expect = helpers.execute, helpers.expect local source = helpers.source diff --git a/test/functional/legacy/027_expand_file_names_spec.lua b/test/functional/legacy/027_expand_file_names_spec.lua index d31f29d38a..4778d16d43 100644 --- a/test/functional/legacy/027_expand_file_names_spec.lua +++ b/test/functional/legacy/027_expand_file_names_spec.lua @@ -1,10 +1,10 @@ -- Test for expanding file names local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert -local execute, expect = helpers.execute, helpers.expect +local clear, feed = helpers.clear, helpers.feed +local execute = helpers.execute local curbuf_contents = helpers.curbuf_contents -local eq, eval = helpers.eq, helpers.eval +local eq = helpers.eq describe('expand file name', function() setup(clear) diff --git a/test/functional/legacy/029_join_spec.lua b/test/functional/legacy/029_join_spec.lua index eafa50d88c..25a072ad6e 100644 --- a/test/functional/legacy/029_join_spec.lua +++ b/test/functional/legacy/029_join_spec.lua @@ -1,7 +1,7 @@ -- Test for joining lines with marks in them (and with 'joinspaces' set/reset) local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('joining lines', function() diff --git a/test/functional/legacy/031_close_commands_spec.lua b/test/functional/legacy/031_close_commands_spec.lua index 78e71b5fb1..3597cba12a 100644 --- a/test/functional/legacy/031_close_commands_spec.lua +++ b/test/functional/legacy/031_close_commands_spec.lua @@ -10,7 +10,7 @@ -- :edit local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('Commands that close windows and/or buffers', function() diff --git a/test/functional/legacy/038_virtual_replace_spec.lua b/test/functional/legacy/038_virtual_replace_spec.lua index 94503bd42a..10d42f0cea 100644 --- a/test/functional/legacy/038_virtual_replace_spec.lua +++ b/test/functional/legacy/038_virtual_replace_spec.lua @@ -1,7 +1,7 @@ -- Test Virtual replace mode. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed = helpers.feed local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('Virtual replace mode', function() diff --git a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua index efe61aa354..1359b45228 100644 --- a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua +++ b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua @@ -4,7 +4,7 @@ -- This test contains both "test44" and "test99" from the old test suite. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect -- Runs the test protocol with the given 'regexpengine' setting. In the old test diff --git a/test/functional/legacy/046_multi_line_regexps_spec.lua b/test/functional/legacy/046_multi_line_regexps_spec.lua index f8a6143b18..b17ab42fe3 100644 --- a/test/functional/legacy/046_multi_line_regexps_spec.lua +++ b/test/functional/legacy/046_multi_line_regexps_spec.lua @@ -3,7 +3,7 @@ local helpers = require('test.functional.helpers') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert -local execute, expect = helpers.execute, helpers.expect +local expect = helpers.expect describe('multi-line regexp', function() setup(clear) diff --git a/test/functional/legacy/051_highlight_spec.lua b/test/functional/legacy/051_highlight_spec.lua index 620df97aac..94c42b73e5 100644 --- a/test/functional/legacy/051_highlight_spec.lua +++ b/test/functional/legacy/051_highlight_spec.lua @@ -3,7 +3,7 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear, feed = helpers.clear, helpers.feed local execute, expect = helpers.execute, helpers.expect local wait = helpers.wait diff --git a/test/functional/legacy/056_script_local_function_spec.lua b/test/functional/legacy/056_script_local_function_spec.lua index 147391ceb1..dec88e8001 100644 --- a/test/functional/legacy/056_script_local_function_spec.lua +++ b/test/functional/legacy/056_script_local_function_spec.lua @@ -3,7 +3,7 @@ local helpers = require('test.functional.helpers') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert -local execute, expect = helpers.execute, helpers.expect +local expect = helpers.expect describe('source function', function() setup(clear) diff --git a/test/functional/legacy/060_exists_and_has_functions_spec.lua b/test/functional/legacy/060_exists_and_has_functions_spec.lua index e9b79b490d..7f44b35a4e 100644 --- a/test/functional/legacy/060_exists_and_has_functions_spec.lua +++ b/test/functional/legacy/060_exists_and_has_functions_spec.lua @@ -1,8 +1,8 @@ -- Tests for the exists() and has() functions. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local source = helpers.source +local clear, expect = helpers.clear, helpers.expect local write_file = helpers.write_file describe('exists() and has() functions', function() diff --git a/test/functional/legacy/061_undo_tree_spec.lua b/test/functional/legacy/061_undo_tree_spec.lua index 8cc2a371bb..ceb114b2a7 100644 --- a/test/functional/legacy/061_undo_tree_spec.lua +++ b/test/functional/legacy/061_undo_tree_spec.lua @@ -1,8 +1,8 @@ -- Tests for undo tree and :earlier and :later. local helpers = require('test.functional.helpers') -local feed, insert, source, eq, eval, clear, execute, expect, wait, write_file - = helpers.feed, helpers.insert, helpers.source, helpers.eq, helpers.eval, +local feed, source, eq, eval, clear, execute, expect, wait, write_file = + helpers.feed, helpers.source, helpers.eq, helpers.eval, helpers.clear, helpers.execute, helpers.expect, helpers.wait, helpers.write_file @@ -97,9 +97,8 @@ describe('undo tree:', function() -- Retry up to 3 times. pcall() is _not_ used for the final attempt, so -- that failure messages can bubble up. - local success, result = false, '' - for i = 1, 2 do - success, result = pcall(test_earlier_later) + for _ = 1, 2 do + local success = pcall(test_earlier_later) if success then return end diff --git a/test/functional/legacy/063_match_and_matchadd_spec.lua b/test/functional/legacy/063_match_and_matchadd_spec.lua index d819db7812..a354d4d328 100644 --- a/test/functional/legacy/063_match_and_matchadd_spec.lua +++ b/test/functional/legacy/063_match_and_matchadd_spec.lua @@ -2,10 +2,9 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local eval, clear, execute, expect = helpers.eval, helpers.clear, helpers.execute -local expect, eq, neq = helpers.expect, helpers.eq, helpers.neq -local command = helpers.command +local feed, insert = helpers.feed, helpers.insert +local eval, clear, execute = helpers.eval, helpers.clear, helpers.execute +local eq, neq = helpers.eq, helpers.neq describe('063: Test for ":match", "matchadd()" and related functions', function() setup(clear) @@ -86,7 +85,7 @@ describe('063: Test for ":match", "matchadd()" and related functions', function( execute("2match MyGroup2 /HUMPPA/") execute("3match MyGroup3 /VIM/") execute("let ml = getmatches()") - ml = eval("ml") + local ml = eval("ml") execute("call clearmatches()") execute("call setmatches(ml)") eq(ml, eval('getmatches()')) diff --git a/test/functional/legacy/065_float_and_logic_operators_spec.lua b/test/functional/legacy/065_float_and_logic_operators_spec.lua index 5cdb0b7f58..e78b230956 100644 --- a/test/functional/legacy/065_float_and_logic_operators_spec.lua +++ b/test/functional/legacy/065_float_and_logic_operators_spec.lua @@ -1,7 +1,7 @@ -- Test for floating point and logical operators. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local insert, source = helpers.insert, helpers.source local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('floating point and logical operators', function() diff --git a/test/functional/legacy/067_augroup_exists_spec.lua b/test/functional/legacy/067_augroup_exists_spec.lua index 6d89ad6d55..dc4c9c7eeb 100644 --- a/test/functional/legacy/067_augroup_exists_spec.lua +++ b/test/functional/legacy/067_augroup_exists_spec.lua @@ -2,7 +2,7 @@ -- autocommands. local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear = helpers.clear local execute, expect = helpers.execute, helpers.expect describe('augroup when calling exists()', function() diff --git a/test/functional/legacy/072_undo_file_spec.lua b/test/functional/legacy/072_undo_file_spec.lua index ce9129ff43..efcc2f2cc3 100644 --- a/test/functional/legacy/072_undo_file_spec.lua +++ b/test/functional/legacy/072_undo_file_spec.lua @@ -3,7 +3,7 @@ -- undo-able pieces. Do that by setting 'undolevels'. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('72', function() diff --git a/test/functional/legacy/074_global_var_in_viminfo_spec.lua b/test/functional/legacy/074_global_var_in_viminfo_spec.lua index 2428b7f74d..49c4827613 100644 --- a/test/functional/legacy/074_global_var_in_viminfo_spec.lua +++ b/test/functional/legacy/074_global_var_in_viminfo_spec.lua @@ -13,7 +13,7 @@ describe('storing global variables in ShaDa files', function() end) it('is working', function() - local nvim2 = helpers.spawn({helpers.nvim_prog, '-u', 'NONE', + local nvim2 = spawn({helpers.nvim_prog, '-u', 'NONE', '-i', 'Xviminfo', '--embed'}) helpers.set_session(nvim2) diff --git a/test/functional/legacy/075_maparg_spec.lua b/test/functional/legacy/075_maparg_spec.lua index 418abb14d4..82965f5cb2 100644 --- a/test/functional/legacy/075_maparg_spec.lua +++ b/test/functional/legacy/075_maparg_spec.lua @@ -2,7 +2,7 @@ -- Also test utf8 map with a 0x80 byte. local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear, feed = helpers.clear, helpers.feed local execute, expect = helpers.execute, helpers.expect describe('maparg()', function() diff --git a/test/functional/legacy/077_mf_hash_grow_spec.lua b/test/functional/legacy/077_mf_hash_grow_spec.lua index 825f08e968..029fe98fe9 100644 --- a/test/functional/legacy/077_mf_hash_grow_spec.lua +++ b/test/functional/legacy/077_mf_hash_grow_spec.lua @@ -7,7 +7,7 @@ -- If it isn't available then the test will be skipped. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed = helpers.feed local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('mf_hash_grow()', function() diff --git a/test/functional/legacy/078_swapfile_recover_spec.lua b/test/functional/legacy/078_swapfile_recover_spec.lua index 33115c1317..e48fddaac1 100644 --- a/test/functional/legacy/078_swapfile_recover_spec.lua +++ b/test/functional/legacy/078_swapfile_recover_spec.lua @@ -4,9 +4,7 @@ -- pointer blocks. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect, source = helpers.clear, helpers.execute, helpers.expect, helpers.source -local eval = helpers.eval +local clear, expect, source = helpers.clear, helpers.expect, helpers.source describe('78', function() setup(clear) diff --git a/test/functional/legacy/080_substitute_spec.lua b/test/functional/legacy/080_substitute_spec.lua index 89ef7a713c..96082364e0 100644 --- a/test/functional/legacy/080_substitute_spec.lua +++ b/test/functional/legacy/080_substitute_spec.lua @@ -3,7 +3,7 @@ -- Test for *:s%* on :substitute. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect local eq, eval = helpers.eq, helpers.eval diff --git a/test/functional/legacy/082_string_comparison_spec.lua b/test/functional/legacy/082_string_comparison_spec.lua index 1615828ca0..933c6c8fa3 100644 --- a/test/functional/legacy/082_string_comparison_spec.lua +++ b/test/functional/legacy/082_string_comparison_spec.lua @@ -2,7 +2,7 @@ -- Also test "g~ap". local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, source = helpers.feed, helpers.source local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('case-insensitive string comparison in UTF-8', function() diff --git a/test/functional/legacy/084_curswant_spec.lua b/test/functional/legacy/084_curswant_spec.lua index 55df5d3e73..946dd5e501 100644 --- a/test/functional/legacy/084_curswant_spec.lua +++ b/test/functional/legacy/084_curswant_spec.lua @@ -1,8 +1,8 @@ -- Tests for curswant not changing when setting an option. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local insert, source = helpers.insert, helpers.source +local clear, expect = helpers.clear, helpers.expect describe('curswant', function() setup(clear) diff --git a/test/functional/legacy/089_number_relnumber_findfile_spec.lua b/test/functional/legacy/089_number_relnumber_findfile_spec.lua index 1f8e49cc81..f72ebf3f72 100644 --- a/test/functional/legacy/089_number_relnumber_findfile_spec.lua +++ b/test/functional/legacy/089_number_relnumber_findfile_spec.lua @@ -4,7 +4,7 @@ local helpers = require('test.functional.helpers') local feed = helpers.feed -local clear, execute, expect, source = helpers.clear, helpers.execute, helpers.expect, helpers.source +local clear, expect, source = helpers.clear, helpers.expect, helpers.source describe("setting 'number' and 'relativenumber'", function() setup(clear) diff --git a/test/functional/legacy/090_sha256_spec.lua b/test/functional/legacy/090_sha256_spec.lua index 35fbd5752e..95e50063a1 100644 --- a/test/functional/legacy/090_sha256_spec.lua +++ b/test/functional/legacy/090_sha256_spec.lua @@ -1,8 +1,8 @@ -- Tests for sha256() function. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local insert, source = helpers.insert, helpers.source +local clear, expect = helpers.clear, helpers.expect describe('sha256()', function() setup(clear) diff --git a/test/functional/legacy/091_context_variables_spec.lua b/test/functional/legacy/091_context_variables_spec.lua index bb9c32b84f..ffeb0c657e 100644 --- a/test/functional/legacy/091_context_variables_spec.lua +++ b/test/functional/legacy/091_context_variables_spec.lua @@ -1,8 +1,8 @@ -- Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar(). local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local insert, source = helpers.insert, helpers.source +local clear, expect = helpers.clear, helpers.expect describe('context variables', function() setup(clear) diff --git a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua index e0cc39dc40..f76ba25d7a 100644 --- a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua +++ b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua @@ -4,7 +4,7 @@ -- Same as legacy test 93 but using UTF-8 file encoding. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('store cursor position in session file in UTF-8', function() diff --git a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua index 659e716721..bf3af1a827 100644 --- a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua +++ b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua @@ -4,7 +4,7 @@ -- Same as legacy test 92 but using Latin-1 file encoding. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local feed, insert = helpers.feed, helpers.insert local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('store cursor position in session file in Latin-1', function() diff --git a/test/functional/legacy/095_regexp_multibyte_spec.lua b/test/functional/legacy/095_regexp_multibyte_spec.lua index 559222e2ff..a80a247612 100644 --- a/test/functional/legacy/095_regexp_multibyte_spec.lua +++ b/test/functional/legacy/095_regexp_multibyte_spec.lua @@ -4,8 +4,8 @@ -- actually tried. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local insert, source = helpers.insert, helpers.source +local clear, expect = helpers.clear, helpers.expect describe('regex with multi-byte', function() setup(clear) diff --git a/test/functional/legacy/096_location_list_spec.lua b/test/functional/legacy/096_location_list_spec.lua index 2ccfd3530d..6e2f22ea33 100644 --- a/test/functional/legacy/096_location_list_spec.lua +++ b/test/functional/legacy/096_location_list_spec.lua @@ -7,7 +7,7 @@ -- it belongs to. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source +local source = helpers.source local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('location list', function() diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua index 84f26478ac..5c467fbb20 100644 --- a/test/functional/legacy/097_glob_path_spec.lua +++ b/test/functional/legacy/097_glob_path_spec.lua @@ -3,7 +3,7 @@ -- characters. local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear = helpers.clear local execute, expect = helpers.execute, helpers.expect describe('glob() and globpath()', function() diff --git a/test/functional/legacy/098_scrollbind_spec.lua b/test/functional/legacy/098_scrollbind_spec.lua index 7b2059e38b..6850e373ab 100644 --- a/test/functional/legacy/098_scrollbind_spec.lua +++ b/test/functional/legacy/098_scrollbind_spec.lua @@ -1,8 +1,8 @@ -- Test for 'scrollbind' causing an unexpected scroll of one of the windows. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local source = helpers.source +local clear, expect = helpers.clear, helpers.expect describe('scrollbind', function() setup(clear) diff --git a/test/functional/legacy/100_undo_level_spec.lua b/test/functional/legacy/100_undo_level_spec.lua index 9143d9e540..3bf72341d6 100644 --- a/test/functional/legacy/100_undo_level_spec.lua +++ b/test/functional/legacy/100_undo_level_spec.lua @@ -1,8 +1,8 @@ -- Tests for 'undolevel' setting being global-local local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local source = helpers.source +local clear, expect = helpers.clear, helpers.expect describe('undolevel', function() setup(clear) diff --git a/test/functional/legacy/101_hlsearch_spec.lua b/test/functional/legacy/101_hlsearch_spec.lua index 4b8b1cef50..335d275c2a 100644 --- a/test/functional/legacy/101_hlsearch_spec.lua +++ b/test/functional/legacy/101_hlsearch_spec.lua @@ -1,9 +1,8 @@ -- Test for v:hlsearch local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear, feed = helpers.clear, helpers.feed local execute, expect = helpers.execute, helpers.expect -local eval = helpers.eval describe('v:hlsearch', function() setup(clear) diff --git a/test/functional/legacy/102_fnameescape_spec.lua b/test/functional/legacy/102_fnameescape_spec.lua index 251ce68430..a3b0313d7a 100644 --- a/test/functional/legacy/102_fnameescape_spec.lua +++ b/test/functional/legacy/102_fnameescape_spec.lua @@ -1,7 +1,7 @@ -- Test if fnameescape is correct for special chars like! local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear = helpers.clear local execute, expect = helpers.execute, helpers.expect describe('fnameescape', function() diff --git a/test/functional/legacy/103_visual_mode_reset_spec.lua b/test/functional/legacy/103_visual_mode_reset_spec.lua index 6b2f3bc1b6..c1407ef10a 100644 --- a/test/functional/legacy/103_visual_mode_reset_spec.lua +++ b/test/functional/legacy/103_visual_mode_reset_spec.lua @@ -1,8 +1,8 @@ -- Test for visual mode not being reset causing E315 error. local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local feed, source = helpers.feed, helpers.source +local clear, expect = helpers.clear, helpers.expect describe('E315 error', function() setup(clear) diff --git a/test/functional/legacy/105_filename_modifiers_spec.lua b/test/functional/legacy/105_filename_modifiers_spec.lua index 3b417a88eb..3413667022 100644 --- a/test/functional/legacy/105_filename_modifiers_spec.lua +++ b/test/functional/legacy/105_filename_modifiers_spec.lua @@ -1,7 +1,7 @@ -- Test filename modifiers. local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear = helpers.clear local execute, expect = helpers.execute, helpers.expect describe('filename modifiers', function() diff --git a/test/functional/legacy/106_errorformat_spec.lua b/test/functional/legacy/106_errorformat_spec.lua index 5b6037f928..5958f1aa7b 100644 --- a/test/functional/legacy/106_errorformat_spec.lua +++ b/test/functional/legacy/106_errorformat_spec.lua @@ -1,7 +1,7 @@ -- Tests for errorformat. local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear = helpers.clear local execute, expect = helpers.execute, helpers.expect describe('errorformat', function() diff --git a/test/functional/legacy/107_adjust_window_and_contents_spec.lua b/test/functional/legacy/107_adjust_window_and_contents_spec.lua index f6ea7e5a6c..7a6de3d748 100644 --- a/test/functional/legacy/107_adjust_window_and_contents_spec.lua +++ b/test/functional/legacy/107_adjust_window_and_contents_spec.lua @@ -2,8 +2,8 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local insert = helpers.insert +local clear, execute = helpers.clear, helpers.execute describe('107', function() setup(clear) diff --git a/test/functional/legacy/autocmd_option_spec.lua b/test/functional/legacy/autocmd_option_spec.lua new file mode 100644 index 0000000000..855e9c6271 --- /dev/null +++ b/test/functional/legacy/autocmd_option_spec.lua @@ -0,0 +1,277 @@ +local helpers = require('test.functional.helpers') +local nvim = helpers.meths +local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq +local curbuf, buf = helpers.curbuf, helpers.bufmeths +local source, execute = helpers.source, helpers.execute + +local function declare_hook_function() + source([[ + fu! AutoCommand(match, bufnr, winnr) + let l:acc = { + \ 'option' : a:match, + \ 'oldval' : v:option_old, + \ 'newval' : v:option_new, + \ 'scope' : v:option_type, + \ 'attr' : { + \ 'bufnr' : a:bufnr, + \ 'winnr' : a:winnr, + \ } + \ } + call add(g:ret, l:acc) + endfu + ]]) +end + +local function set_hook(pattern) + execute( + 'au OptionSet ' + .. pattern .. + ' :call AutoCommand(expand("<amatch>"), bufnr("%"), winnr())' + ) +end + +local function init_var() + execute('let g:ret = []') +end + +local function get_result() + local ret = nvim.get_var('ret') + init_var() + return ret +end + +local function expected_table(option, oldval, newval, scope, attr) + return { + option = option, + oldval = tostring(oldval), + newval = tostring(newval), + scope = scope, + attr = attr, + } +end + +local function expected_combination(...) + local args = {...} + local ret = get_result() + + if not (#args == #ret) then + local expecteds = {} + for _, v in pairs(args) do + table.insert(expecteds, expected_table(unpack(v))) + end + eq(expecteds, ret) + return + end + + for i, v in ipairs(args) do + local attr = v[5] + if not attr then + -- remove attr entries + ret[i].attr = nil + else + -- remove attr entries which are not required + for k in pairs(ret[i].attr) do + if not attr[k] then + ret[i].attr[k] = nil + end + end + end + eq(expected_table(unpack(v)), ret[i]) + end +end + +local function expected_empty() + eq({}, get_result()) +end + +local function make_buffer() + local old_buf = curbuf() + execute('new') + local new_buf = curbuf() + execute('wincmd p') -- move previous window + + neq(old_buf, new_buf) + eq(old_buf, curbuf()) + + return new_buf +end + +describe('au OptionSet', function() + describe('with any opton (*)', function() + + before_each(function() + clear() + declare_hook_function() + init_var() + set_hook('*') + end) + + it('should be called in setting number option', function() + execute('set nu') + expected_combination({'number', 0, 1, 'global'}) + + execute('setlocal nonu') + expected_combination({'number', 1, 0, 'local'}) + + execute('setglobal nonu') + expected_combination({'number', 1, 0, 'global'}) + end) + + it('should be called in setting autoindent option',function() + execute('setlocal ai') + expected_combination({'autoindent', 0, 1, 'local'}) + + execute('setglobal ai') + expected_combination({'autoindent', 0, 1, 'global'}) + + execute('set noai') + expected_combination({'autoindent', 1, 0, 'global'}) + end) + + it('should be called in inverting global autoindent option',function() + execute('set ai!') + expected_combination({'autoindent', 0, 1, 'global'}) + end) + + it('should be called in being unset local autoindent option',function() + execute('setlocal ai') + expected_combination({'autoindent', 0, 1, 'local'}) + + execute('setlocal ai<') + expected_combination({'autoindent', 1, 0, 'local'}) + end) + + it('should be called in setting global list and number option at the same time',function() + execute('set list nu') + expected_combination( + {'list', 0, 1, 'global'}, + {'number', 0, 1, 'global'} + ) + end) + + it('should not print anything, use :noa', function() + execute('noa set nolist nonu') + expected_empty() + end) + + it('should be called in setting local acd', function() + execute('setlocal acd') + expected_combination({'autochdir', 0, 1, 'local'}) + end) + + it('should be called in setting autoread', function() + execute('set noar') + expected_combination({'autoread', 1, 0, 'global'}) + + execute('setlocal ar') + expected_combination({'autoread', 0, 1, 'local'}) + end) + + it('should be called in inverting global autoread', function() + execute('setglobal invar') + expected_combination({'autoread', 1, 0, 'global'}) + end) + + it('should be called in setting backspace option through :let', function() + execute('let &bs=""') + expected_combination({'backspace', 'indent,eol,start', '', 'global'}) + end) + + describe('being set by setbufvar()', function() + it('should not trigger because option name is invalid', function() + execute('call setbufvar(1, "&l:bk", 1)') + expected_empty() + end) + + it('should trigger using correct option name', function() + execute('call setbufvar(1, "&backup", 1)') + expected_combination({'backup', 0, 1, 'local'}) + end) + + it('should trigger if the current buffer is different from the targetted buffer', function() + local new_buffer = make_buffer() + local new_bufnr = buf.get_number(new_buffer) + + execute('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")') + expected_combination({'buftype', '', 'nofile', 'local', {bufnr = new_bufnr}}) + end) + end) + end) + + describe('with specific option', function() + + before_each(function() + clear() + declare_hook_function() + init_var() + end) + + it('should be called iff setting readonly', function() + set_hook('readonly') + + execute('set nu') + expected_empty() + + execute('setlocal ro') + expected_combination({'readonly', 0, 1, 'local'}) + + execute('setglobal ro') + expected_combination({'readonly', 0, 1, 'global'}) + + execute('set noro') + expected_combination({'readonly', 1, 0, 'global'}) + end) + + describe('being set by setbufvar()', function() + it('should not trigger because option name does not match with backup', function() + set_hook('backup') + + execute('call setbufvar(1, "&l:bk", 1)') + expected_empty() + end) + + it('should trigger, use correct option name backup', function() + set_hook('backup') + + execute('call setbufvar(1, "&backup", 1)') + expected_combination({'backup', 0, 1, 'local'}) + end) + + it('should trigger if the current buffer is different from the targetted buffer', function() + set_hook('buftype') + + local new_buffer = make_buffer() + local new_bufnr = buf.get_number(new_buffer) + + execute('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")') + expected_combination({'buftype', '', 'nofile', 'local', {bufnr = new_bufnr}}) + end) + end) + + describe('being set by neovim api', function() + it('should trigger if a boolean option be set globally', function() + set_hook('autochdir') + + nvim.set_option('autochdir', true) + eq(true, nvim.get_option('autochdir')) + expected_combination({'autochdir', '0', '1', 'global'}) + end) + + it('should trigger if a number option be set globally', function() + set_hook('cmdheight') + + nvim.set_option('cmdheight', 5) + eq(5, nvim.get_option('cmdheight')) + expected_combination({'cmdheight', 1, 5, 'global'}) + end) + + it('should trigger if a string option be set globally', function() + set_hook('ambiwidth') + + nvim.set_option('ambiwidth', 'double') + eq('double', nvim.get_option('ambiwidth')) + expected_combination({'ambiwidth', 'single', 'double', 'global'}) + end) + end) + end) +end) diff --git a/test/functional/legacy/listlbr_utf8_spec.lua b/test/functional/legacy/listlbr_utf8_spec.lua index 15d12ac4af..69e7b87a21 100644 --- a/test/functional/legacy/listlbr_utf8_spec.lua +++ b/test/functional/legacy/listlbr_utf8_spec.lua @@ -1,8 +1,8 @@ -- Test for linebreak and list option in utf-8 mode local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local source = helpers.source +local clear, expect = helpers.clear, helpers.expect describe('linebreak', function() setup(clear) diff --git a/test/functional/legacy/nested_function_spec.lua b/test/functional/legacy/nested_function_spec.lua index 87371c8294..fac3b03191 100644 --- a/test/functional/legacy/nested_function_spec.lua +++ b/test/functional/legacy/nested_function_spec.lua @@ -1,7 +1,7 @@ -- Tests for nested function. local helpers = require('test.functional.helpers') -local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local clear, insert = helpers.clear, helpers.insert local execute, expect, source = helpers.execute, helpers.expect, helpers.source describe('test_nested_function', function() diff --git a/test/functional/legacy/qf_title_spec.lua b/test/functional/legacy/qf_title_spec.lua index aa005117be..01c781cc05 100644 --- a/test/functional/legacy/qf_title_spec.lua +++ b/test/functional/legacy/qf_title_spec.lua @@ -1,8 +1,8 @@ -- Tests for quickfix window's title local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source -local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect +local insert, source = helpers.insert, helpers.source +local clear, expect = helpers.clear, helpers.expect describe('qf_title', function() setup(clear) diff --git a/test/functional/legacy/signs_spec.lua b/test/functional/legacy/signs_spec.lua index 89b2bf3b73..5a834c39e3 100644 --- a/test/functional/legacy/signs_spec.lua +++ b/test/functional/legacy/signs_spec.lua @@ -1,7 +1,6 @@ -- Tests for signs local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('signs', function() diff --git a/test/functional/legacy/writefile_spec.lua b/test/functional/legacy/writefile_spec.lua index e7a260bcd9..efdfc1d09f 100644 --- a/test/functional/legacy/writefile_spec.lua +++ b/test/functional/legacy/writefile_spec.lua @@ -1,7 +1,6 @@ -- Tests for writefile() local helpers = require('test.functional.helpers') -local feed, insert, source = helpers.feed, helpers.insert, helpers.source local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect describe('writefile', function() diff --git a/test/functional/normal/K_spec.lua b/test/functional/normal/K_spec.lua index dbda6dcb93..df6b429f50 100644 --- a/test/functional/normal/K_spec.lua +++ b/test/functional/normal/K_spec.lua @@ -1,7 +1,6 @@ local helpers = require('test.functional.helpers') -local execute, eq, clear, eval, feed, ok = - helpers.execute, helpers.eq, helpers.clear, helpers.eval, - helpers.feed, helpers.ok +local eq, clear, eval, feed = + helpers.eq, helpers.clear, helpers.eval, helpers.feed describe('K', function() local test_file = 'K_spec_out' diff --git a/test/functional/plugin/helpers.lua b/test/functional/plugin/helpers.lua new file mode 100644 index 0000000000..cc76794267 --- /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_args = {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_args) + else + return nvim_args + 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..4100a30452 --- /dev/null +++ b/test/functional/plugin/shada_spec.lua @@ -0,0 +1,2850 @@ +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 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_, _) + 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', + ' + sb search backward TRUE', + ' + 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}, + 'sb': {'_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', + ' + sb search backward 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', + ' + sb search backward 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', + ' + sb search backward 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}, + 'sb': {'_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', + ' + sb search backward 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', + ' + sb search backward 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}, + 'sb': {'_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', + ' + sb search backward 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, + 'sb': 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) + + teardown(function() + os.remove(fname) + 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 + -- luacheck: ignore + 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) diff --git a/test/functional/provider/define_spec.lua b/test/functional/provider/define_spec.lua index 9b97ed84d9..6e8a3b89cd 100644 --- a/test/functional/provider/define_spec.lua +++ b/test/functional/provider/define_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers') local eval, command, nvim = helpers.eval, helpers.command, helpers.nvim local eq, run, stop = helpers.eq, helpers.run, helpers.stop -local clear, feed = helpers.clear, helpers.feed +local clear = helpers.clear local function get_prefix(sync) @@ -12,8 +12,8 @@ local function get_prefix(sync) end -local function call(fn, args) - command('call '..fn..'('..args..')') +local function call(fn, arguments) + command('call '..fn..'('..arguments..')') end @@ -87,9 +87,9 @@ local function command_specs_for(fn, sync, first_arg_factory, init) command('RpcCommand arg1 arg2 arg3') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({'arg1', 'arg2', 'arg3'}, args[1]) + eq({'arg1', 'arg2', 'arg3'}, arguments[1]) return '' end @@ -104,9 +104,9 @@ local function command_specs_for(fn, sync, first_arg_factory, init) command('1,1RpcCommand') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({1, 1}, args[1]) + eq({1, 1}, arguments[1]) return '' end @@ -121,10 +121,10 @@ local function command_specs_for(fn, sync, first_arg_factory, init) command('1,1RpcCommand arg') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, args[1]) - eq({1, 1}, args[2]) + eq({'arg'}, arguments[1]) + eq({1, 1}, arguments[2]) return '' end @@ -139,10 +139,10 @@ local function command_specs_for(fn, sync, first_arg_factory, init) command('5RpcCommand arg') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, args[1]) - eq(5, args[2]) + eq({'arg'}, arguments[1]) + eq(5, arguments[2]) return '' end @@ -157,11 +157,11 @@ local function command_specs_for(fn, sync, first_arg_factory, init) command('5RpcCommand! arg') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, args[1]) - eq(5, args[2]) - eq(1, args[3]) + eq({'arg'}, arguments[1]) + eq(5, arguments[2]) + eq(1, arguments[3]) return '' end @@ -177,12 +177,12 @@ local function command_specs_for(fn, sync, first_arg_factory, init) command('5RpcCommand! b arg') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, args[1]) - eq(5, args[2]) - eq(1, args[3]) - eq('b', args[4]) + eq({'arg'}, arguments[1]) + eq(5, arguments[2]) + eq(1, arguments[3]) + eq('b', arguments[4]) return '' end @@ -199,13 +199,13 @@ local function command_specs_for(fn, sync, first_arg_factory, init) command('5RpcCommand! b arg') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({'arg'}, args[1]) - eq(5, args[2]) - eq(1, args[3]) - eq('b', args[4]) - eq('regb', args[5]) + eq({'arg'}, arguments[1]) + eq(5, arguments[2]) + eq(1, arguments[3]) + eq('b', arguments[4]) + eq('regb', arguments[5]) return '' end @@ -243,7 +243,7 @@ local function autocmd_specs_for(fn, sync, first_arg_factory, init) command('doautocmd BufEnter x.c') end - local function handler(method, args) + local function handler(method) eq('test-handler', method) return '' end @@ -259,9 +259,9 @@ local function autocmd_specs_for(fn, sync, first_arg_factory, init) command('doautocmd BufEnter x.c') end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq('x.c', args[1]) + eq('x.c', arguments[1]) return '' end @@ -303,9 +303,9 @@ local function function_specs_for(fn, sync, first_arg_factory, init) end end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({{1, 'a', {'b', 'c'}}}, args) + eq({{1, 'a', {'b', 'c'}}}, arguments) return 'rv' end @@ -324,9 +324,9 @@ local function function_specs_for(fn, sync, first_arg_factory, init) end end - local function handler(method, args) + local function handler(method, arguments) eq('test-handler', method) - eq({{1, 'a', {'b', 'c'}}, 4}, args) + eq({{1, 'a', {'b', 'c'}}, 4}, arguments) return 'rv' end diff --git a/test/functional/server/server_spec.lua b/test/functional/server/server_spec.lua index 1cb3c879b9..d9ce96057e 100644 --- a/test/functional/server/server_spec.lua +++ b/test/functional/server/server_spec.lua @@ -1,7 +1,6 @@ local helpers = require('test.functional.helpers') -local nvim, eq, neq, ok, eval - = helpers.nvim, helpers.eq, helpers.neq, helpers.ok, helpers.eval +local nvim, eq, neq, eval = helpers.nvim, helpers.eq, helpers.neq, helpers.eval local clear = helpers.clear describe('serverstart(), serverstop()', function() diff --git a/test/functional/shada/buffers_spec.lua b/test/functional/shada/buffers_spec.lua index 3666b718f0..fd4809e01a 100644 --- a/test/functional/shada/buffers_spec.lua +++ b/test/functional/shada/buffers_spec.lua @@ -1,7 +1,7 @@ -- ShaDa buffer list saving/reading support local helpers = require('test.functional.helpers') -local nvim_command, funcs, eq = - helpers.command, helpers.funcs, helpers.eq +local nvim_command, funcs, eq, curbufmeths = + helpers.command, helpers.funcs, helpers.eq, helpers.curbufmeths local shada_helpers = require('test.functional.shada.helpers') local reset, set_additional_cmd, clear = @@ -9,8 +9,8 @@ local reset, set_additional_cmd, clear = shada_helpers.clear describe('ShaDa support code', function() - testfilename = 'Xtestfile-functional-shada-buffers' - testfilename_2 = 'Xtestfile-functional-shada-buffers-2' + local testfilename = 'Xtestfile-functional-shada-buffers' + local testfilename_2 = 'Xtestfile-functional-shada-buffers-2' before_each(reset) after_each(clear) @@ -48,4 +48,43 @@ describe('ShaDa support code', function() eq(1, funcs.bufnr('$')) eq('', funcs.bufname(1)) end) + + it('does not dump unlisted buffer', function() + set_additional_cmd('set shada+=%') + reset() + nvim_command('edit ' .. testfilename) + nvim_command('edit ' .. testfilename_2) + curbufmeths.set_option('buflisted', false) + nvim_command('qall') + reset() + eq(2, funcs.bufnr('$')) + eq('', funcs.bufname(1)) + eq(testfilename, funcs.bufname(2)) + end) + + it('does not dump quickfix buffer', function() + set_additional_cmd('set shada+=%') + reset() + nvim_command('edit ' .. testfilename) + nvim_command('edit ' .. testfilename_2) + curbufmeths.set_option('buftype', 'quickfix') + nvim_command('qall') + reset() + eq(2, funcs.bufnr('$')) + eq('', funcs.bufname(1)) + eq(testfilename, funcs.bufname(2)) + end) + + it('does not dump unnamed buffers', function() + set_additional_cmd('set shada+=% hidden') + reset() + curbufmeths.set_line(0, 'foo') + nvim_command('enew') + curbufmeths.set_line(0, 'bar') + eq(2, funcs.bufnr('$')) + nvim_command('qall!') + reset() + eq(1, funcs.bufnr('$')) + eq('', funcs.bufname(1)) + end) end) diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua index 342dee377b..2ca0b16e75 100644 --- a/test/functional/shada/compatibility_spec.lua +++ b/test/functional/shada/compatibility_spec.lua @@ -4,9 +4,8 @@ local nvim_command, funcs, eq = helpers.command, helpers.funcs, helpers.eq local exc_exec = helpers.exc_exec local shada_helpers = require('test.functional.shada.helpers') -local reset, set_additional_cmd, clear, get_shada_rw = - shada_helpers.reset, shada_helpers.set_additional_cmd, - shada_helpers.clear, shada_helpers.get_shada_rw +local reset, clear, get_shada_rw = shada_helpers.reset, shada_helpers.clear, + shada_helpers.get_shada_rw local read_shada_file = shada_helpers.read_shada_file local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compatibility.shada') @@ -181,7 +180,7 @@ describe('ShaDa forward compatibility support code', function() end eq(3, found) nvim_command('wshada! ' .. shada_fname) - local found = 0 + found = 0 for i, subv in ipairs(read_shada_file(shada_fname)) do if i == 1 then eq(1, subv.type) @@ -249,7 +248,7 @@ describe('ShaDa forward compatibility support code', function() end eq(1, found) nvim_command('wshada! ' .. shada_fname) - local found = 0 + found = 0 for i, v in ipairs(read_shada_file(shada_fname)) do if i == 1 then eq(1, v.type) @@ -289,7 +288,7 @@ describe('ShaDa forward compatibility support code', function() end eq(1, found) nvim_command('wshada! ' .. shada_fname) - local found = 0 + found = 0 for i, v in ipairs(read_shada_file(shada_fname)) do if i == 1 then eq(1, v.type) @@ -395,7 +394,7 @@ describe('ShaDa forward compatibility support code', function() end eq(1, found) nvim_command('wshada! ' .. shada_fname) - local found = 0 + found = 0 for i, v in ipairs(read_shada_file(shada_fname)) do if i == 1 then eq(1, v.type) @@ -432,7 +431,7 @@ describe('ShaDa forward compatibility support code', function() end eq(1, found) nvim_command('wshada! ' .. shada_fname) - local found = 0 + found = 0 for i, v in ipairs(read_shada_file(shada_fname)) do if i == 1 then eq(1, v.type) diff --git a/test/functional/shada/errors_spec.lua b/test/functional/shada/errors_spec.lua index 16ae77af02..62b9e6c84d 100644 --- a/test/functional/shada/errors_spec.lua +++ b/test/functional/shada/errors_spec.lua @@ -124,6 +124,11 @@ describe('ShaDa error handling', function() eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sc key value which is not a boolean', exc_exec(sdrcmd())) end) + it('fails on search pattern item with NIL search_backward key value', function() + wshada('\002\000\009\130\162sX\192\162sb\192') + eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sb key value which is not a boolean', exc_exec(sdrcmd())) + end) + it('fails on search pattern item with NIL has_line_offset key value', function() wshada('\002\000\009\130\162sX\192\162sl\192') eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sl key value which is not a boolean', exc_exec(sdrcmd())) diff --git a/test/functional/shada/helpers.lua b/test/functional/shada/helpers.lua index c2ff4cadd1..146ae8d51e 100644 --- a/test/functional/shada/helpers.lua +++ b/test/functional/shada/helpers.lua @@ -9,15 +9,14 @@ local tmpname = os.tmpname() local additional_cmd = '' local function nvim_argv() - local ret - local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', tmpname, '-N', - '--cmd', 'set shortmess+=I background=light noswapfile', - '--cmd', additional_cmd, - '--embed'} + local argv = {nvim_prog, '-u', 'NONE', '-i', tmpname, '-N', + '--cmd', 'set shortmess+=I background=light noswapfile', + '--cmd', additional_cmd, + '--embed'} if helpers.prepend_argv then - return merge_args(helpers.prepend_argv, nvim_argv) + return merge_args(helpers.prepend_argv, argv) else - return nvim_argv + return argv end end @@ -88,7 +87,6 @@ return { reset=reset, set_additional_cmd=set_additional_cmd, clear=clear, - exc_exec=exc_exec, get_shada_rw=get_shada_rw, read_shada_file=read_shada_file, } diff --git a/test/functional/shada/history_spec.lua b/test/functional/shada/history_spec.lua index 1123f829d2..94513945d0 100644 --- a/test/functional/shada/history_spec.lua +++ b/test/functional/shada/history_spec.lua @@ -107,14 +107,32 @@ describe('ShaDa support code', function() end) it('dumps and loads last search pattern with offset', function() - funcs.setline('.', {'foo', 'bar'}) + meths.set_option('wrapscan', false) + funcs.setline('.', {'foo', 'bar--'}) nvim_feed('gg0/a/e+1\n') eq({0, 2, 3, 0}, funcs.getpos('.')) nvim_command('wshada') reset() - funcs.setline('.', {'foo', 'bar'}) + meths.set_option('wrapscan', false) + funcs.setline('.', {'foo', 'bar--'}) nvim_feed('gg0n') eq({0, 2, 3, 0}, funcs.getpos('.')) + eq(1, meths.get_vvar('searchforward')) + end) + + it('dumps and loads last search pattern with offset and backward direction', + function() + meths.set_option('wrapscan', false) + funcs.setline('.', {'foo', 'bar--'}) + nvim_feed('G$?a?e+1\n') + eq({0, 2, 3, 0}, funcs.getpos('.')) + nvim_command('wshada') + reset() + meths.set_option('wrapscan', false) + funcs.setline('.', {'foo', 'bar--'}) + nvim_feed('G$n') + eq({0, 2, 3, 0}, funcs.getpos('.')) + eq(0, meths.get_vvar('searchforward')) end) it('saves v:hlsearch=1', function() diff --git a/test/functional/shada/marks_spec.lua b/test/functional/shada/marks_spec.lua index 6818844ebd..955a6f382b 100644 --- a/test/functional/shada/marks_spec.lua +++ b/test/functional/shada/marks_spec.lua @@ -15,15 +15,15 @@ local nvim_current_line = function() end describe('ShaDa support code', function() - testfilename = 'Xtestfile-functional-shada-marks' - testfilename_2 = 'Xtestfile-functional-shada-marks-2' + local testfilename = 'Xtestfile-functional-shada-marks' + local testfilename_2 = 'Xtestfile-functional-shada-marks-2' before_each(function() reset() local fd = io.open(testfilename, 'w') fd:write('test\n') fd:write('test2\n') fd:close() - local fd = io.open(testfilename_2, 'w') + fd = io.open(testfilename_2, 'w') fd:write('test3\n') fd:write('test4\n') fd:close() @@ -115,7 +115,7 @@ describe('ShaDa support code', function() eq(tf_full, oldfiles[1]) eq(tf_full_2, oldfiles[2]) nvim_command('rshada!') - local oldfiles = meths.get_vvar('oldfiles') + oldfiles = meths.get_vvar('oldfiles') table.sort(oldfiles) eq(2, #oldfiles) eq(testfilename, oldfiles[1]:sub(-#testfilename)) diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua index 7066ca9f54..221f989409 100644 --- a/test/functional/shada/merging_spec.lua +++ b/test/functional/shada/merging_spec.lua @@ -1,7 +1,7 @@ -- ShaDa merging data support local helpers = require('test.functional.helpers') -local nvim_command, meths, funcs, curbufmeths, eq = - helpers.command, helpers.meths, helpers.funcs, +local nvim_command, funcs, curbufmeths, eq = + helpers.command, helpers.funcs, helpers.curbufmeths, helpers.eq local exc_exec, redir_exec = helpers.exc_exec, helpers.redir_exec @@ -870,7 +870,7 @@ describe('ShaDa jumps support code', function() end wshada(shada) eq(0, exc_exec(sdrcmd())) - local shada = '' + shada = '' for i = 1,101 do local t = i * 2 shada = shada .. ( @@ -964,7 +964,7 @@ describe('ShaDa changes support code', function() end wshada(shada) eq(0, exc_exec(sdrcmd())) - local shada = '' + shada = '' for i = 1,101 do local t = i * 2 shada = shada .. ( @@ -1001,7 +1001,7 @@ describe('ShaDa changes support code', function() end wshada(shada) eq(0, exc_exec(sdrcmd())) - local shada = '' + shada = '' for i = 1,100 do shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c' ):format(i, i) diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua index 4985c24aec..00b16e9158 100644 --- a/test/functional/shell/viml_system_spec.lua +++ b/test/functional/shell/viml_system_spec.lua @@ -133,7 +133,7 @@ describe('system()', function() -- write more than 1mb of data, which should be enough to overcome -- the os buffer limit and force multiple event loop iterations to write -- everything - for i = 1, 0xffff do + for _ = 1, 0xffff do input[#input + 1] = '01234567890ABCDEFabcdef' end input = table.concat(input, '\n') @@ -299,7 +299,7 @@ describe('systemlist()', function() describe('passing a lot of input', function() it('returns the program output', function() local input = {} - for i = 1, 0xffff do + for _ = 1, 0xffff do input[#input + 1] = '01234567890ABCDEFabcdef' end nvim('set_var', 'input', input) diff --git a/test/functional/terminal/altscreen_spec.lua b/test/functional/terminal/altscreen_spec.lua index 9ec0fc7c5a..d9d96b25f9 100644 --- a/test/functional/terminal/altscreen_spec.lua +++ b/test/functional/terminal/altscreen_spec.lua @@ -1,6 +1,5 @@ local helpers = require('test.functional.helpers') local thelpers = require('test.functional.terminal.helpers') -local Screen = require('test.functional.ui.screen') local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf local feed = helpers.feed local feed_data = thelpers.feed_data diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua index ffdfec4428..55ef254a63 100644 --- a/test/functional/terminal/buffer_spec.lua +++ b/test/functional/terminal/buffer_spec.lua @@ -1,5 +1,4 @@ local helpers = require('test.functional.helpers') -local Screen = require('test.functional.ui.screen') local thelpers = require('test.functional.terminal.helpers') local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim local wait = helpers.wait diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua index 7f07467fde..e9cb010003 100644 --- a/test/functional/terminal/cursor_spec.lua +++ b/test/functional/terminal/cursor_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') local thelpers = require('test.functional.terminal.helpers') local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim -local nvim_dir, execute, eq = helpers.nvim_dir, helpers.execute, helpers.eq +local nvim_dir, execute = helpers.nvim_dir, helpers.execute local hide_cursor = thelpers.hide_cursor local show_cursor = thelpers.show_cursor diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua index 611ba55793..493539b4d3 100644 --- a/test/functional/terminal/ex_terminal_spec.lua +++ b/test/functional/terminal/ex_terminal_spec.lua @@ -2,8 +2,7 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') local clear, wait, nvim = helpers.clear, helpers.wait, helpers.nvim local nvim_dir = helpers.nvim_dir -local execute, source = helpers.execute, helpers.source -local eq, neq = helpers.eq, helpers.neq +local execute = helpers.execute describe(':terminal', function() local screen diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua index ae13aab277..a32ae650d6 100644 --- a/test/functional/terminal/helpers.lua +++ b/test/functional/terminal/helpers.lua @@ -72,7 +72,7 @@ local function screen_setup(extra_height, command) empty_line, empty_line, } - for i = 1, extra_height do + for _ = 1, extra_height do table.insert(expected, empty_line) end diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua index 1a96cb4dba..045f5aa42f 100644 --- a/test/functional/terminal/highlight_spec.lua +++ b/test/functional/terminal/highlight_spec.lua @@ -40,7 +40,7 @@ describe('terminal window highlighting', function() ]]) end) - function descr(title, attr_num, set_attrs_fn) + local function descr(title, attr_num, set_attrs_fn) local function sub(s) return s:gsub('NUM', attr_num) end diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index ac61abebcb..c4bd3c2663 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -1,8 +1,7 @@ -local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers') local thelpers = require('test.functional.terminal.helpers') -local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf -local feed, execute, nvim = helpers.feed, helpers.execute, helpers.nvim +local clear = helpers.clear +local feed, nvim = helpers.feed, helpers.nvim local feed_data = thelpers.feed_data describe('terminal mouse', function() diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 9a1fdfca55..14700a2622 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -1,10 +1,10 @@ -- Some sanity checks for the TUI using the builtin terminal emulator -- as a simple way to send keys and assert screen state. -local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers') local thelpers = require('test.functional.terminal.helpers') local feed = thelpers.feed_data local execute = helpers.execute +local nvim_dir = helpers.nvim_dir describe('tui', function() local screen @@ -148,10 +148,43 @@ describe('tui', function() -- TERMINAL -- | ]]) end) +end) + +describe('tui with non-tty file descriptors', function() + before_each(helpers.clear) + + after_each(function() + os.remove('testF') -- ensure test file is removed + end) + + it('can handle pipes as stdout and stderr', function() + local screen = thelpers.screen_setup(0, '"'..helpers.nvim_prog..' -u NONE -i NONE --cmd \'set noswapfile\' --cmd \'normal iabc\' > /dev/null 2>&1 && cat testF && rm testF"') + screen:set_default_attr_ids({}) + screen:set_default_attr_ignore(true) + feed(':w testF\n:q\n') + screen:expect([[ + :w testF | + :q | + abc | + | + [Process exited 0] | + | + -- TERMINAL -- | + ]]) + end) +end) + +describe('tui focus event handling', function() + local screen - it('can handle focus events', function() + before_each(function() + helpers.clear() + screen = thelpers.screen_setup(0, '["'..helpers.nvim_prog..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile"]') execute('autocmd FocusGained * echo "gained"') execute('autocmd FocusLost * echo "lost"') + end) + + it('can handle focus events in normal mode', function() feed('\x1b[I') screen:expect([[ {1: } | @@ -174,27 +207,79 @@ describe('tui', function() -- TERMINAL -- | ]]) end) -end) -describe('tui with non-tty file descriptors', function() - before_each(helpers.clear) + it('can handle focus events in insert mode', function() + execute('set noshowmode') + feed('i') + feed('\x1b[I') + screen:expect([[ + {1: } | + ~ | + ~ | + ~ | + [No Name] | + gained | + -- TERMINAL -- | + ]]) + feed('\x1b[O') + screen:expect([[ + {1: } | + ~ | + ~ | + ~ | + [No Name] | + lost | + -- TERMINAL -- | + ]]) + end) - after_each(function() - os.remove('testF') -- ensure test file is removed + it('can handle focus events in cmdline mode', function() + feed(':') + feed('\x1b[I') + screen:expect([[ + | + ~ | + ~ | + ~ | + [No Name] | + g{1:a}ined | + -- TERMINAL -- | + ]]) + feed('\x1b[O') + screen:expect([[ + | + ~ | + ~ | + ~ | + [No Name] | + l{1:o}st | + -- TERMINAL -- | + ]]) end) - it('can handle pipes as stdout and stderr', function() - local screen = thelpers.screen_setup(0, '"'..helpers.nvim_prog..' -u NONE -i NONE --cmd \'set noswapfile\' --cmd \'normal iabc\' > /dev/null 2>&1 && cat testF && rm testF"') - screen:set_default_attr_ids({}) - screen:set_default_attr_ignore(true) - feed(':w testF\n:q\n') + it('can handle focus events in terminal mode', function() + execute('set shell='..nvim_dir..'/shell-test') + execute('set laststatus=0') + execute('set noshowmode') + execute('terminal') + feed('\x1b[I') screen:expect([[ - :w testF | - :q | - abc | + ready $ | + [Process exited 0]{1: } | | - [Process exited 0] | | + | + gained | + -- TERMINAL -- | + ]]) + feed('\x1b[O') + screen:expect([[ + ready $ | + [Process exited 0]{1: } | + | + | + | + lost | -- TERMINAL -- | ]]) end) diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua index c2b9390a11..6c236ed868 100644 --- a/test/functional/terminal/window_spec.lua +++ b/test/functional/terminal/window_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers') local thelpers = require('test.functional.terminal.helpers') -local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim -local wait, eq = helpers.wait, helpers.eq +local feed, clear = helpers.feed, helpers.clear +local wait = helpers.wait describe('terminal window', function() diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua index c102b1f133..727eba2717 100644 --- a/test/functional/terminal/window_split_tab_spec.lua +++ b/test/functional/terminal/window_split_tab_spec.lua @@ -1,8 +1,7 @@ local helpers = require('test.functional.helpers') local thelpers = require('test.functional.terminal.helpers') -local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf +local clear = helpers.clear local feed, nvim = helpers.feed, helpers.nvim -local feed_data = thelpers.feed_data describe('terminal', function() local screen diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 33a53ef201..f9b112e464 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') -local clear, feed, nvim = helpers.clear, helpers.feed, helpers.nvim +local clear, feed = helpers.clear, helpers.feed local execute, request, eq = helpers.execute, helpers.request, helpers.eq diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua index a7c8e02def..4818830940 100644 --- a/test/functional/ui/input_spec.lua +++ b/test/functional/ui/input_spec.lua @@ -8,7 +8,6 @@ describe('mappings', function() local cid local add_mapping = function(mapping, send) - local str = 'mapped '..mapping local cmd = "nnoremap "..mapping.." :call rpcnotify("..cid..", 'mapped', '" ..send:gsub('<', '<lt>').."')<cr>" execute(cmd) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index c767f9b83a..e1c2d14759 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -106,8 +106,8 @@ -- use `screen:snapshot_util({},true)` local helpers = require('test.functional.helpers') -local request, run, stop = helpers.request, helpers.run, helpers.stop -local eq, dedent = helpers.eq, helpers.dedent +local request, run = helpers.request, helpers.run +local dedent = helpers.dedent local Screen = {} Screen.__index = Screen @@ -241,7 +241,7 @@ function Screen:wait(check, timeout) checked = true if not err then success_seen = true - stop() + helpers.stop() elseif success_seen and #args > 0 then failure_after_success = true --print(require('inspect')(args)) @@ -294,9 +294,9 @@ end function Screen:_handle_resize(width, height) local rows = {} - for i = 1, height do + for _ = 1, height do local cols = {} - for j = 1, width do + for _ = 1, width do table.insert(cols, {text = ' ', attrs = {}}) end table.insert(rows, cols) @@ -448,7 +448,7 @@ function Screen:_row_repr(row, attr_ids, attr_ignore) local rv = {} local current_attr_id for i = 1, self._width do - local attr_id = get_attr_id(attr_ids, attr_ignore, row[i].attrs) + local attr_id = self:_get_attr_id(attr_ids, attr_ignore, row[i].attrs) if current_attr_id and attr_id ~= current_attr_id then -- close current attribute bracket, add it before any whitespace -- up to the current cell @@ -524,8 +524,8 @@ function Screen:print_snapshot(attrs, ignore) local row = self._rows[i] for j = 1, self._width do local attr = row[j].attrs - if attr_index(attrs, attr) == nil and attr_index(ignore, attr) == nil then - if not equal_attrs(attr, {}) then + if self:_attr_index(attrs, attr) == nil and self:_attr_index(ignore, attr) == nil then + if not self:_equal_attrs(attr, {}) then table.insert(attrs, attr) end end @@ -544,7 +544,7 @@ function Screen:print_snapshot(attrs, ignore) if self._default_attr_ids == nil or self._default_attr_ids[i] ~= a then alldefault = false end - local dict = "{"..pprint_attrs(a).."}" + local dict = "{"..self:_pprint_attrs(a).."}" table.insert(attrstrs, "["..tostring(i).."] = "..dict) end local attrstr = "{"..table.concat(attrstrs, ", ").."}" @@ -558,7 +558,7 @@ function Screen:print_snapshot(attrs, ignore) io.stdout:flush() end -function pprint_attrs(attrs) +function Screen:_pprint_attrs(attrs) local items = {} for f, v in pairs(attrs) do local desc = tostring(v) @@ -572,7 +572,7 @@ function pprint_attrs(attrs) return table.concat(items, ", ") end -function backward_find_meaningful(tbl, from) +function backward_find_meaningful(tbl, from) -- luacheck: ignore for i = from or #tbl, 1, -1 do if tbl[i] ~= ' ' then return i + 1 @@ -581,24 +581,24 @@ function backward_find_meaningful(tbl, from) return from end -function get_attr_id(attr_ids, ignore, attrs) +function Screen:_get_attr_id(attr_ids, ignore, attrs) if not attr_ids then return end for id, a in pairs(attr_ids) do - if equal_attrs(a, attrs) then + if self:_equal_attrs(a, attrs) then return id end end - if equal_attrs(attrs, {}) or - ignore == true or attr_index(ignore, attrs) ~= nil then + if self:_equal_attrs(attrs, {}) or + ignore == true or self:_attr_index(ignore, attrs) ~= nil then -- ignore this attrs return nil end - return "UNEXPECTED "..pprint_attrs(attrs) + return "UNEXPECTED "..self:_pprint_attrs(attrs) end -function equal_attrs(a, b) +function Screen:_equal_attrs(a, b) return a.bold == b.bold and a.standout == b.standout and a.underline == b.underline and a.undercurl == b.undercurl and a.italic == b.italic and a.reverse == b.reverse and @@ -606,12 +606,12 @@ function equal_attrs(a, b) a.background == b.background end -function attr_index(attrs, attr) +function Screen:_attr_index(attrs, attr) if not attrs then return nil end for i,a in pairs(attrs) do - if equal_attrs(a, attr) then + if self:_equal_attrs(a, attr) then return i end end diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 092cc8c126..a4545eeff0 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') local spawn, set_session, clear = helpers.spawn, helpers.set_session, helpers.clear local feed, execute = helpers.feed, helpers.execute -local insert, wait = helpers.insert, helpers.wait +local insert = helpers.insert describe('Initial screen', function() local screen @@ -11,9 +11,6 @@ describe('Initial screen', function() '--embed'} before_each(function() - if session then - session:exit(0) - end local screen_nvim = spawn(nvim_argv) set_session(screen_nvim) screen = Screen.new() diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index d04329e1e2..e4217abcfe 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -1,7 +1,7 @@ local helpers = require('test.functional.helpers') local Screen = require('test.functional.ui.screen') -local clear, feed, nvim, insert = helpers.clear, helpers.feed, helpers.nvim, helpers.insert -local execute, request, eq = helpers.execute, helpers.request, helpers.eq +local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local execute = helpers.execute describe('search highlighting', function() local screen diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua index 5e3d4a6658..12f542de7f 100644 --- a/test/functional/viml/completion_spec.lua +++ b/test/functional/viml/completion_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers') -local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute +local clear, feed = helpers.clear, helpers.feed local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq local execute, source = helpers.execute, helpers.source |