diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 5 | ||||
-rw-r--r-- | test/busted_runner.lua | 11 | ||||
-rw-r--r-- | test/client/msgpack_rpc_stream.lua | 112 | ||||
-rw-r--r-- | test/client/session.lua | 192 | ||||
-rw-r--r-- | test/client/uv_stream.lua | 169 | ||||
-rw-r--r-- | test/functional/api/rpc_fixture.lua | 7 | ||||
-rw-r--r-- | test/functional/api/server_requests_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/api/vim_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/ex_cmds/oldfiles_spec.lua | 5 | ||||
-rw-r--r-- | test/functional/ex_cmds/profile_spec.lua | 1 | ||||
-rw-r--r-- | test/functional/ex_cmds/swapfile_preserve_recover_spec.lua | 63 | ||||
-rw-r--r-- | test/functional/helpers.lua | 16 | ||||
-rw-r--r-- | test/functional/lua/filetype_spec.lua | 8 | ||||
-rw-r--r-- | test/functional/shada/helpers.lua | 1 | ||||
-rw-r--r-- | test/functional/shada/history_spec.lua | 1 | ||||
-rw-r--r-- | test/functional/shada/shada_spec.lua | 42 | ||||
-rw-r--r-- | test/functional/ui/screen_basic_spec.lua | 81 | ||||
-rw-r--r-- | test/functional/ui/searchhl_spec.lua | 29 | ||||
-rw-r--r-- | test/helpers.lua | 2 |
19 files changed, 682 insertions, 67 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7e5fb07382..dc74838760 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,6 +26,7 @@ if(BUSTED_PRG) -D BUILD_DIR=${CMAKE_BINARY_DIR} -D TEST_TYPE=unit -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${UNITTEST_PREREQS} USES_TERMINAL) @@ -47,8 +48,10 @@ if(BUSTED_PRG) -D BUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE} -D TEST_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D BUILD_DIR=${CMAKE_BINARY_DIR} + -D DEPS_PREFIX=${DEPS_PREFIX} -D TEST_TYPE=functional -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${FUNCTIONALTEST_PREREQS} USES_TERMINAL) @@ -65,6 +68,7 @@ if(BUSTED_PRG) -D BUILD_DIR=${CMAKE_BINARY_DIR} -D TEST_TYPE=benchmark -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${BENCHMARK_PREREQS} USES_TERMINAL) @@ -84,6 +88,7 @@ if(BUSTED_LUA_PRG) -D BUILD_DIR=${CMAKE_BINARY_DIR} -D TEST_TYPE=functional -D CIRRUS_CI=$ENV{CIRRUS_CI} + -D CI_BUILD=${CI_BUILD} -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake DEPENDS ${FUNCTIONALTEST_PREREQS} USES_TERMINAL) diff --git a/test/busted_runner.lua b/test/busted_runner.lua index b195ce3cc5..62d1e611e7 100644 --- a/test/busted_runner.lua +++ b/test/busted_runner.lua @@ -1 +1,12 @@ +local platform = vim.loop.os_uname() +if platform and platform.sysname:lower():find'windows' then + local deps_prefix = os.getenv 'DEPS_PREFIX' + if deps_prefix ~= nil and deps_prefix ~= "" then + package.path = deps_prefix.."/share/lua/5.1/?.lua;"..deps_prefix.."/share/lua/5.1/?/init.lua;"..package.path + package.path = deps_prefix.."/bin/lua/?.lua;"..deps_prefix.."/bin/lua/?/init.lua;"..package.path + package.cpath = deps_prefix.."/lib/lua/5.1/?.dll;"..package.cpath; + package.cpath = deps_prefix.."/bin/?.dll;"..deps_prefix.."/bin/loadall.dll;"..package.cpath; + end +end + require 'busted.runner'({ standalone = false }) diff --git a/test/client/msgpack_rpc_stream.lua b/test/client/msgpack_rpc_stream.lua new file mode 100644 index 0000000000..5711616b17 --- /dev/null +++ b/test/client/msgpack_rpc_stream.lua @@ -0,0 +1,112 @@ +local mpack = require('mpack') + +-- temporary hack to be able to manipulate buffer/window/tabpage +local Buffer = {} +Buffer.__index = Buffer +function Buffer.new(id) return setmetatable({id=id}, Buffer) end +local Window = {} +Window.__index = Window +function Window.new(id) return setmetatable({id=id}, Window) end +local Tabpage = {} +Tabpage.__index = Tabpage +function Tabpage.new(id) return setmetatable({id=id}, Tabpage) end + +local Response = {} +Response.__index = Response + +function Response.new(msgpack_rpc_stream, request_id) + return setmetatable({ + _msgpack_rpc_stream = msgpack_rpc_stream, + _request_id = request_id + }, Response) +end + +function Response:send(value, is_error) + local data = self._msgpack_rpc_stream._session:reply(self._request_id) + if is_error then + data = data .. self._msgpack_rpc_stream._pack(value) + data = data .. self._msgpack_rpc_stream._pack(mpack.NIL) + else + data = data .. self._msgpack_rpc_stream._pack(mpack.NIL) + data = data .. self._msgpack_rpc_stream._pack(value) + end + self._msgpack_rpc_stream._stream:write(data) +end + +local MsgpackRpcStream = {} +MsgpackRpcStream.__index = MsgpackRpcStream + +function MsgpackRpcStream.new(stream) + return setmetatable({ + _stream = stream, + _pack = mpack.Packer({ + ext = { + [Buffer] = function(o) return 0, mpack.encode(o.id) end, + [Window] = function(o) return 1, mpack.encode(o.id) end, + [Tabpage] = function(o) return 2, mpack.encode(o.id) end + } + }), + _session = mpack.Session({ + unpack = mpack.Unpacker({ + ext = { + [0] = function(_c, s) return Buffer.new(mpack.decode(s)) end, + [1] = function(_c, s) return Window.new(mpack.decode(s)) end, + [2] = function(_c, s) return Tabpage.new(mpack.decode(s)) end + } + }) + }), + }, MsgpackRpcStream) +end + +function MsgpackRpcStream:write(method, args, response_cb) + local data + if response_cb then + assert(type(response_cb) == 'function') + data = self._session:request(response_cb) + else + data = self._session:notify() + end + + data = data .. self._pack(method) .. self._pack(args) + self._stream:write(data) +end + +function MsgpackRpcStream:read_start(request_cb, notification_cb, eof_cb) + self._stream:read_start(function(data) + if not data then + return eof_cb() + end + local type, id_or_cb, method_or_error, args_or_result + local pos = 1 + local len = #data + while pos <= len do + type, id_or_cb, method_or_error, args_or_result, pos = + self._session:receive(data, pos) + if type == 'request' or type == 'notification' then + if type == 'request' then + request_cb(method_or_error, args_or_result, Response.new(self, + id_or_cb)) + else + notification_cb(method_or_error, args_or_result) + end + elseif type == 'response' then + if method_or_error == mpack.NIL then + method_or_error = nil + else + args_or_result = nil + end + id_or_cb(method_or_error, args_or_result) + end + end + end) +end + +function MsgpackRpcStream:read_stop() + self._stream:read_stop() +end + +function MsgpackRpcStream:close(signal) + self._stream:close(signal) +end + +return MsgpackRpcStream diff --git a/test/client/session.lua b/test/client/session.lua new file mode 100644 index 0000000000..0509fa88be --- /dev/null +++ b/test/client/session.lua @@ -0,0 +1,192 @@ +local uv = require('luv') +local MsgpackRpcStream = require('test.client.msgpack_rpc_stream') + +local Session = {} +Session.__index = Session +if package.loaded['jit'] then + -- luajit pcall is already coroutine safe + Session.safe_pcall = pcall +else + Session.safe_pcall = require'coxpcall'.pcall +end + +local function resume(co, ...) + local status, result = coroutine.resume(co, ...) + + if coroutine.status(co) == 'dead' then + if not status then + error(result) + end + return + end + + assert(coroutine.status(co) == 'suspended') + result(co) +end + +local function coroutine_exec(func, ...) + local args = {...} + local on_complete + + if #args > 0 and type(args[#args]) == 'function' then + -- completion callback + on_complete = table.remove(args) + end + + resume(coroutine.create(function() + local status, result, flag = Session.safe_pcall(func, unpack(args)) + if on_complete then + coroutine.yield(function() + -- run the completion callback on the main thread + on_complete(status, result, flag) + end) + end + end)) +end + +function Session.new(stream) + return setmetatable({ + _msgpack_rpc_stream = MsgpackRpcStream.new(stream), + _pending_messages = {}, + _prepare = uv.new_prepare(), + _timer = uv.new_timer(), + _is_running = false + }, Session) +end + +function Session:next_message(timeout) + local function on_request(method, args, response) + table.insert(self._pending_messages, {'request', method, args, response}) + uv.stop() + end + + local function on_notification(method, args) + table.insert(self._pending_messages, {'notification', method, args}) + uv.stop() + end + + if self._is_running then + error('Event loop already running') + end + + if #self._pending_messages > 0 then + return table.remove(self._pending_messages, 1) + end + + self:_run(on_request, on_notification, timeout) + return table.remove(self._pending_messages, 1) +end + +function Session:notify(method, ...) + self._msgpack_rpc_stream:write(method, {...}) +end + +function Session:request(method, ...) + local args = {...} + local err, result + if self._is_running then + err, result = self:_yielding_request(method, args) + else + err, result = self:_blocking_request(method, args) + end + + if err then + return false, err + end + + return true, result +end + +function Session:run(request_cb, notification_cb, setup_cb, timeout) + local function on_request(method, args, response) + coroutine_exec(request_cb, method, args, function(status, result, flag) + if status then + response:send(result, flag) + else + response:send(result, true) + end + end) + end + + local function on_notification(method, args) + coroutine_exec(notification_cb, method, args) + end + + self._is_running = true + + if setup_cb then + coroutine_exec(setup_cb) + end + + while #self._pending_messages > 0 do + local msg = table.remove(self._pending_messages, 1) + if msg[1] == 'request' then + on_request(msg[2], msg[3], msg[4]) + else + on_notification(msg[2], msg[3]) + end + end + + self:_run(on_request, on_notification, timeout) + self._is_running = false +end + +function Session:stop() + uv.stop() +end + +function Session:close(signal) + if not self._timer:is_closing() then self._timer:close() end + if not self._prepare:is_closing() then self._prepare:close() end + self._msgpack_rpc_stream:close(signal) +end + +function Session:_yielding_request(method, args) + return coroutine.yield(function(co) + self._msgpack_rpc_stream:write(method, args, function(err, result) + resume(co, err, result) + end) + end) +end + +function Session:_blocking_request(method, args) + local err, result + + local function on_request(method_, args_, response) + table.insert(self._pending_messages, {'request', method_, args_, response}) + end + + local function on_notification(method_, args_) + table.insert(self._pending_messages, {'notification', method_, args_}) + end + + self._msgpack_rpc_stream:write(method, args, function(e, r) + err = e + result = r + uv.stop() + end) + + self:_run(on_request, on_notification) + return (err or self.eof_err), result +end + +function Session:_run(request_cb, notification_cb, timeout) + if type(timeout) == 'number' then + self._prepare:start(function() + self._timer:start(timeout, 0, function() + uv.stop() + end) + self._prepare:stop() + end) + end + self._msgpack_rpc_stream:read_start(request_cb, notification_cb, function() + uv.stop() + self.eof_err = {1, "EOF was received from Nvim. Likely the Nvim process crashed."} + end) + uv.run() + self._prepare:stop() + self._timer:stop() + self._msgpack_rpc_stream:read_stop() +end + +return Session diff --git a/test/client/uv_stream.lua b/test/client/uv_stream.lua new file mode 100644 index 0000000000..cea77f0dbd --- /dev/null +++ b/test/client/uv_stream.lua @@ -0,0 +1,169 @@ +local uv = require('luv') + +local StdioStream = {} +StdioStream.__index = StdioStream + +function StdioStream.open() + local self = setmetatable({ + _in = uv.new_pipe(false), + _out = uv.new_pipe(false) + }, StdioStream) + self._in:open(0) + self._out:open(1) + return self +end + +function StdioStream:write(data) + self._out:write(data) +end + +function StdioStream:read_start(cb) + self._in:read_start(function(err, chunk) + if err then + error(err) + end + cb(chunk) + end) +end + +function StdioStream:read_stop() + self._in:read_stop() +end + +function StdioStream:close() + self._in:close() + self._out:close() +end + +local SocketStream = {} +SocketStream.__index = SocketStream + +function SocketStream.open(file) + local socket = uv.new_pipe(false) + local self = setmetatable({ + _socket = socket, + _stream_error = nil + }, SocketStream) + uv.pipe_connect(socket, file, function (err) + self._stream_error = self._stream_error or err + end) + return self +end + +function SocketStream.connect(host, port) + local socket = uv.new_tcp() + local self = setmetatable({ + _socket = socket, + _stream_error = nil + }, SocketStream) + uv.tcp_connect(socket, host, port, function (err) + self._stream_error = self._stream_error or err + end) + return self +end + + +function SocketStream:write(data) + if self._stream_error then + error(self._stream_error) + end + uv.write(self._socket, data, function(err) + if err then + error(self._stream_error or err) + end + end) +end + +function SocketStream:read_start(cb) + if self._stream_error then + error(self._stream_error) + end + uv.read_start(self._socket, function(err, chunk) + if err then + error(err) + end + cb(chunk) + end) +end + +function SocketStream:read_stop() + if self._stream_error then + error(self._stream_error) + end + uv.read_stop(self._socket) +end + +function SocketStream:close() + uv.close(self._socket) +end + +local ChildProcessStream = {} +ChildProcessStream.__index = ChildProcessStream + +function ChildProcessStream.spawn(argv, env, io_extra) + local self = setmetatable({ + _child_stdin = uv.new_pipe(false); + _child_stdout = uv.new_pipe(false); + _exiting = false; + }, ChildProcessStream) + local prog = argv[1] + local args = {} + for i = 2, #argv do + args[#args + 1] = argv[i] + end + self._proc, self._pid = uv.spawn(prog, { + stdio = {self._child_stdin, self._child_stdout, 2, io_extra}, + args = args, + env = env, + }, function(status, signal) + self.status = status + self.signal = signal + end) + + if not self._proc then + local err = self._pid + error(err) + end + + return self +end + +function ChildProcessStream:write(data) + self._child_stdin:write(data) +end + +function ChildProcessStream:read_start(cb) + self._child_stdout:read_start(function(err, chunk) + if err then + error(err) + end + cb(chunk) + end) +end + +function ChildProcessStream:read_stop() + self._child_stdout:read_stop() +end + +function ChildProcessStream:close(signal) + if self._closed then + return + end + self._closed = true + self:read_stop() + self._child_stdin:close() + self._child_stdout:close() + if type(signal) == 'string' then + self._proc:kill('sig'..signal) + end + while self.status == nil do + uv.run 'once' + end + return self.status, self.signal +end + +return { + StdioStream = StdioStream; + ChildProcessStream = ChildProcessStream; + SocketStream = SocketStream; +} diff --git a/test/functional/api/rpc_fixture.lua b/test/functional/api/rpc_fixture.lua index 94df751363..c860a6da59 100644 --- a/test/functional/api/rpc_fixture.lua +++ b/test/functional/api/rpc_fixture.lua @@ -4,9 +4,8 @@ package.path = arg[1] package.cpath = arg[2] -local mpack = require('mpack') -local StdioStream = require('nvim.stdio_stream') -local Session = require('nvim.session') +local StdioStream = require'test.client.uv_stream'.StdioStream +local Session = require'test.client.session' local stdio_stream = StdioStream.open() local session = Session.new(stdio_stream) @@ -19,7 +18,7 @@ local function on_request(method, args) return "done!" elseif method == "exit" then session:stop() - return mpack.NIL + return vim.NIL end end diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index e6bfc6b64f..cb273aedba 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -237,7 +237,7 @@ describe('server -> client', function() \ } ]]) meths.set_var("args", { - helpers.test_lua_prg, + nvim_prog, '-ll', 'test/functional/api/rpc_fixture.lua', package.path, package.cpath, diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 8fcdd9620b..fc550f5861 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -59,7 +59,7 @@ describe('API', function() -- XXX: This must be the last one, else next one will fail: -- "Packer instance already working. Use another Packer ..." - matches("can't serialize object$", + matches("can't serialize object of type .$", pcall_err(request, nil)) end) diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua index 5f87c3cdd9..19611429e0 100644 --- a/test/functional/ex_cmds/oldfiles_spec.lua +++ b/test/functional/ex_cmds/oldfiles_spec.lua @@ -2,6 +2,8 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear +local command = helpers.command +local expect_exit = helpers.expect_exit local buf, eq, feed_command = helpers.curbufmeths, helpers.eq, helpers.feed_command local feed, poke_eventloop = helpers.feed, helpers.poke_eventloop local ok = helpers.ok @@ -19,6 +21,7 @@ describe(':oldfiles', function() before_each(_clear) after_each(function() + expect_exit(command, 'qall!') os.remove(shada_file) end) @@ -42,6 +45,7 @@ describe(':oldfiles', function() | Press ENTER or type command to continue^ | ]]) + feed('<CR>') end) it('can be filtered with :filter', function() @@ -107,6 +111,7 @@ describe(':browse oldfiles', function() end) after_each(function() + expect_exit(command, 'qall!') os.remove(shada_file) end) diff --git a/test/functional/ex_cmds/profile_spec.lua b/test/functional/ex_cmds/profile_spec.lua index 2b92f8d0de..bf045a4d1d 100644 --- a/test/functional/ex_cmds/profile_spec.lua +++ b/test/functional/ex_cmds/profile_spec.lua @@ -30,6 +30,7 @@ describe(':profile', function() before_each(helpers.clear) after_each(function() + helpers.expect_exit(command, 'qall!') if lfs.attributes(tempfile, 'uid') ~= nil then os.remove(tempfile) end diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua index 8eed00c973..ad59025d47 100644 --- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua +++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua @@ -13,6 +13,7 @@ local nvim_prog = helpers.nvim_prog local ok = helpers.ok local rmdir = helpers.rmdir local new_argv = helpers.new_argv +local new_pipename = helpers.new_pipename local pesc = helpers.pesc local os_kill = helpers.os_kill local set_session = helpers.set_session @@ -37,10 +38,21 @@ describe(':recover', function() end) -describe(':preserve', function() +describe("preserve and (R)ecover with custom 'directory'", function() local swapdir = lfs.currentdir()..'/Xtest_recover_dir' + local testfile = 'Xtest_recover_file1' + -- Put swapdir at the start of the 'directory' list. #1836 + -- Note: `set swapfile` *must* go after `set directory`: otherwise it may + -- attempt to create a swapfile in different directory. + local init = [[ + set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[// + set swapfile fileformat=unix undolevels=-1 + ]] + + local nvim1 before_each(function() - clear() + nvim1 = spawn(new_argv()) + set_session(nvim1) rmdir(swapdir) lfs.mkdir(swapdir) end) @@ -49,25 +61,15 @@ describe(':preserve', function() rmdir(swapdir) end) - it("saves to custom 'directory' and (R)ecovers #1836", function() - local testfile = 'Xtest_recover_file1' - -- Put swapdir at the start of the 'directory' list. #1836 - -- Note: `set swapfile` *must* go after `set directory`: otherwise it may - -- attempt to create a swapfile in different directory. - local init = [[ - set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[// - set swapfile fileformat=unix undolevels=-1 - ]] - + local function setup_swapname() exec(init) command('edit! '..testfile) feed('isometext<esc>') - command('preserve') exec('redir => g:swapname | silent swapname | redir END') + return eval('g:swapname') + end - local swappath1 = eval('g:swapname') - - os_kill(eval('getpid()')) + local function test_recover(swappath1) -- Start another Nvim instance. local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'}, true) @@ -90,6 +92,35 @@ describe(':preserve', function() -- Verify that :swapname was not truncated (:help 'shortmess'). ok(nil == string.find(swappath1, '%.%.%.')) ok(nil == string.find(swappath2, '%.%.%.')) + end + + it('with :preserve and SIGKILL', function() + local swappath1 = setup_swapname() + command('preserve') + os_kill(eval('getpid()')) + test_recover(swappath1) + end) + + it('closing stdio channel without :preserve #22096', function() + local swappath1 = setup_swapname() + nvim1:close() + test_recover(swappath1) + end) + + it('killing TUI process without :preserve #22096', function() + helpers.skip(helpers.is_os('win')) + local screen = Screen.new() + screen:attach() + local child_server = new_pipename() + funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server}) + screen:expect({any = pesc('[No Name]')}) -- Wait for the child process to start. + local child_session = helpers.connect(child_server) + set_session(child_session) + local swappath1 = setup_swapname() + set_session(nvim1) + command('call chanclose(&channel)') -- Kill the child process. + screen:expect({any = pesc('[Process exited 1]')}) -- Wait for the child process to stop. + test_recover(swappath1) end) end) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 6400db9f87..cd6b535477 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -1,14 +1,11 @@ -require('coxpcall') local luv = require('luv') local lfs = require('lfs') -local mpack = require('mpack') local global_helpers = require('test.helpers') --- nvim client: Found in .deps/usr/share/lua/<version>/nvim/ if "bundled". -local Session = require('nvim.session') -local TcpStream = require('nvim.tcp_stream') -local SocketStream = require('nvim.socket_stream') -local ChildProcessStream = require('nvim.child_process_stream') +local Session = require('test.client.session') +local uv_stream = require('test.client.uv_stream') +local SocketStream = uv_stream.SocketStream +local ChildProcessStream = uv_stream.ChildProcessStream local check_cores = global_helpers.check_cores local check_logs = global_helpers.check_logs @@ -23,7 +20,6 @@ local tbl_contains = global_helpers.tbl_contains local fail = global_helpers.fail local module = { - NIL = mpack.NIL, mkdir = lfs.mkdir, } @@ -202,7 +198,7 @@ function module.expect_msg_seq(...) end local function call_and_stop_on_error(lsession, ...) - local status, result = copcall(...) -- luacheck: ignore + local status, result = Session.safe_pcall(...) -- luacheck: ignore if not status then lsession:stop() last_error = result @@ -428,7 +424,7 @@ end -- Creates a new Session connected by domain socket (named pipe) or TCP. function module.connect(file_or_address) local addr, port = string.match(file_or_address, "(.*):(%d+)") - local stream = (addr and port) and TcpStream.open(addr, port) or + local stream = (addr and port) and SocketStream.connect(addr, port) or SocketStream.open(file_or_address) return Session.new(stream) end diff --git a/test/functional/lua/filetype_spec.lua b/test/functional/lua/filetype_spec.lua index 2a7be53164..034665f717 100644 --- a/test/functional/lua/filetype_spec.lua +++ b/test/functional/lua/filetype_spec.lua @@ -94,6 +94,14 @@ describe('vim.filetype', function() return vim.filetype.match({ buf = 0 }) ]]) end) + + it('works with contents #22180', function() + eq('sh', exec_lua [[ + -- Needs to be set so detect#sh doesn't fail + vim.g.ft_ignore_pat = "\\.\\(Z\\|gz\\|bz2\\|zip\\|tgz\\)$" + return vim.filetype.match({ contents = { '#!/usr/bin/env bash' } }) + ]]) + end) end) describe('filetype.lua', function() diff --git a/test/functional/shada/helpers.lua b/test/functional/shada/helpers.lua index fb3ec4a87c..cd99d38345 100644 --- a/test/functional/shada/helpers.lua +++ b/test/functional/shada/helpers.lua @@ -33,6 +33,7 @@ local function reset(o) end local clear = function() + helpers.expect_exit(helpers.command, 'qall!') os.remove(tmpname) end diff --git a/test/functional/shada/history_spec.lua b/test/functional/shada/history_spec.lua index d1daf6c7cc..aa4106ad63 100644 --- a/test/functional/shada/history_spec.lua +++ b/test/functional/shada/history_spec.lua @@ -32,7 +32,6 @@ describe('ShaDa support code', function() nvim_command('rshada') eq('" Test 2', funcs.histget(':', -1)) eq('" Test', funcs.histget(':', -2)) - expect_exit(nvim_command, 'qall') end) it('respects &history when dumping', diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua index 88a99d9b55..24bd363e95 100644 --- a/test/functional/shada/shada_spec.lua +++ b/test/functional/shada/shada_spec.lua @@ -126,34 +126,16 @@ describe('ShaDa support code', function() wshada(s .. table.concat(msgpack, e .. s) .. e) eq(0, exc_exec('wshada ' .. shada_fname)) local found = 0 - local typ = mpack.unpack(s) + local typ = mpack.decode(s) for _, v in ipairs(read_shada_file(shada_fname)) do if v.type == typ then found = found + 1 - eq(mpack.unpack(msgpack[found]), v.timestamp) + eq(mpack.decode(msgpack[found]), v.timestamp) end end eq(#msgpack, found) end) - it('does not write NONE file', function() - local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', - '--headless', '--cmd', 'qall'}, true) - session:close() - eq(nil, lfs.attributes('NONE')) - eq(nil, lfs.attributes('NONE.tmp.a')) - end) - - it('does not read NONE file', function() - write_file('NONE', '\005\001\015\131\161na\162rX\194\162rc\145\196\001-') - local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', - '--headless'}, true) - set_session(session) - eq('', funcs.getreg('a')) - session:close() - os.remove('NONE') - end) - local marklike = {[7]=true, [8]=true, [10]=true, [11]=true} local find_file = function(fname) local found = {} @@ -263,3 +245,23 @@ describe('ShaDa support code', function() meths.set_option('shada', '') end) end) + +describe('ShaDa support code', function() + it('does not write NONE file', function() + local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', + '--headless', '--cmd', 'qall'}, true) + session:close() + eq(nil, lfs.attributes('NONE')) + eq(nil, lfs.attributes('NONE.tmp.a')) + end) + + it('does not read NONE file', function() + write_file('NONE', '\005\001\015\131\161na\162rX\194\162rc\145\196\001-') + local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed', + '--headless'}, true) + set_session(session) + eq('', funcs.getreg('a')) + session:close() + os.remove('NONE') + end) +end) diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 3bd2289a73..439021ad87 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -61,6 +61,7 @@ local function screen_tests(linegrid) [5] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Fuchsia}, [6] = {bold = true, foreground = Screen.colors.Fuchsia}, [7] = {bold = true, foreground = Screen.colors.SeaGreen}, + [8] = {foreground = Screen.colors.White, background = Screen.colors.Red}, } ) end) @@ -866,12 +867,9 @@ local function screen_tests(linegrid) end) describe('resize', function() - before_each(function() + it('rebuilds the whole screen', function() screen:try_resize(25, 5) feed('iresize') - end) - - it('rebuilds the whole screen', function() screen:expect([[ resize^ | {0:~ }| @@ -882,6 +880,7 @@ local function screen_tests(linegrid) end) it('has minimum width/height values', function() + feed('iresize') screen:try_resize(1, 1) screen:expect([[ resize^ | @@ -896,7 +895,8 @@ local function screen_tests(linegrid) end) it('VimResized autocommand does not cause invalid UI events #20692 #20759', function() - feed('<Esc>') + screen:try_resize(25, 5) + feed('iresize<Esc>') command([[autocmd VimResized * redrawtabline]]) command([[autocmd VimResized * lua vim.api.nvim_echo({ { 'Hello' } }, false, {})]]) command([[autocmd VimResized * let g:echospace = v:echospace]]) @@ -919,6 +919,77 @@ local function screen_tests(linegrid) ]]) eq(29, meths.get_var('echospace')) end) + + it('messages from the same Ex command as resize are visible #22225', function() + feed(':set columns=20 | call<CR>') + screen:expect([[ + | + | + | + | + | + | + | + | + | + {1: }| + {8:E471: Argument requi}| + {8:red} | + {7:Press ENTER or type }| + {7:command to continue}^ | + ]]) + feed('<CR>') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + feed(':set columns=0<CR>') + screen:expect([[ + | + | + | + | + | + {1: }| + {8:E594: Need a}| + {8:t least 12 c}| + {8:olumns: colu}| + {8:mns=0} | + {7:Press ENTER }| + {7:or type comm}| + {7:and to conti}| + {7:nue}^ | + ]]) + feed('<CR>') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) end) describe('press enter', function() diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 18bbb56a61..404cc6d043 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -10,7 +10,6 @@ local testprg = helpers.testprg describe('search highlighting', function() local screen - local colors = Screen.colors before_each(function() clear() @@ -18,9 +17,9 @@ describe('search highlighting', function() screen:attach() screen:set_default_attr_ids( { [1] = {bold=true, foreground=Screen.colors.Blue}, - [2] = {background = colors.Yellow}, -- Search + [2] = {background = Screen.colors.Yellow}, -- Search [3] = {reverse = true}, - [4] = {foreground = colors.Red}, -- Message + [4] = {foreground = Screen.colors.Red}, -- Message [6] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGrey}, -- Folded }) end) @@ -498,6 +497,20 @@ describe('search highlighting', function() {1:~ }│{1:~ }| //^ | ]]) + feed('<Esc>') + + -- incsearch works after c_CTRL-R_CTRL-R + command('let @" = "file"') + feed('/<C-R><C-R>"') + screen:expect([[ + the first line │the first line | + in a little {3:file} │in a little {2:file} | + {1:~ }│{1:~ }| + {1:~ }│{1:~ }| + {1:~ }│{1:~ }| + {1:~ }│{1:~ }| + /file^ | + ]]) end) it('works with incsearch and offset', function() @@ -572,12 +585,12 @@ describe('search highlighting', function() it('works with matchadd and syntax', function() screen:set_default_attr_ids { [1] = {bold=true, foreground=Screen.colors.Blue}; - [2] = {background = colors.Yellow}; + [2] = {background = Screen.colors.Yellow}; [3] = {reverse = true}; - [4] = {foreground = colors.Red}; - [5] = {bold = true, background = colors.Green}; - [6] = {italic = true, background = colors.Magenta}; - [7] = {bold = true, background = colors.Yellow}; + [4] = {foreground = Screen.colors.Red}; + [5] = {bold = true, background = Screen.colors.Green}; + [6] = {italic = true, background = Screen.colors.Magenta}; + [7] = {bold = true, background = Screen.colors.Yellow}; [8] = {foreground = Screen.colors.Blue4, background = Screen.colors.LightGray}; } feed_command('set hlsearch') diff --git a/test/helpers.lua b/test/helpers.lua index 82ff23bef8..d45536b42b 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -1,5 +1,5 @@ require('test.compat') -local shared = require('vim.shared') +local shared = vim local assert = require('luassert') local busted = require('busted') local luv = require('luv') |