diff options
Diffstat (limited to 'test/client')
-rw-r--r-- | test/client/msgpack_rpc_stream.lua | 53 | ||||
-rw-r--r-- | test/client/session.lua | 44 | ||||
-rw-r--r-- | test/client/uv_stream.lua | 63 |
3 files changed, 97 insertions, 63 deletions
diff --git a/test/client/msgpack_rpc_stream.lua b/test/client/msgpack_rpc_stream.lua index 5711616b17..7131940a58 100644 --- a/test/client/msgpack_rpc_stream.lua +++ b/test/client/msgpack_rpc_stream.lua @@ -1,15 +1,4 @@ -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 mpack = vim.mpack local Response = {} Response.__index = Response @@ -17,7 +6,7 @@ Response.__index = Response function Response.new(msgpack_rpc_stream, request_id) return setmetatable({ _msgpack_rpc_stream = msgpack_rpc_stream, - _request_id = request_id + _request_id = request_id, }, Response) end @@ -33,27 +22,33 @@ function Response:send(value, is_error) self._msgpack_rpc_stream._stream:write(data) end +--- @class test.MsgpackRpcStream +--- @field private _stream test.Stream +--- @field private __pack table 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 - } - }), + _pack = mpack.Packer(), _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 - } - }) + -- Buffer + [0] = function(_c, s) + return mpack.decode(s) + end, + -- Window + [1] = function(_c, s) + return mpack.decode(s) + end, + -- Tabpage + [2] = function(_c, s) + return mpack.decode(s) + end, + }, + }), }), }, MsgpackRpcStream) end @@ -67,7 +62,7 @@ function MsgpackRpcStream:write(method, args, response_cb) data = self._session:notify() end - data = data .. self._pack(method) .. self._pack(args) + data = data .. self._pack(method) .. self._pack(args) self._stream:write(data) end @@ -80,12 +75,10 @@ function MsgpackRpcStream:read_start(request_cb, notification_cb, eof_cb) 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) + 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)) + request_cb(method_or_error, args_or_result, Response.new(self, id_or_cb)) else notification_cb(method_or_error, args_or_result) end diff --git a/test/client/session.lua b/test/client/session.lua index b1bf5ea75e..cf3d8c4f25 100644 --- a/test/client/session.lua +++ b/test/client/session.lua @@ -1,13 +1,19 @@ -local uv = require('luv') +local uv = vim.uv local MsgpackRpcStream = require('test.client.msgpack_rpc_stream') +--- @class test.Session +--- @field private _pending_messages string[] +--- @field private _msgpack_rpc_stream test.MsgpackRpcStream +--- @field private _prepare uv.uv_prepare_t +--- @field private _timer uv.uv_timer_t +--- @field private _is_running boolean 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 + Session.safe_pcall = require 'coxpcall'.pcall end local function resume(co, ...) @@ -25,8 +31,8 @@ local function resume(co, ...) end local function coroutine_exec(func, ...) - local args = {...} - local on_complete + local args = { ... } + local on_complete --- @type function? if #args > 0 and type(args[#args]) == 'function' then -- completion callback @@ -50,18 +56,20 @@ function Session.new(stream) _pending_messages = {}, _prepare = uv.new_prepare(), _timer = uv.new_timer(), - _is_running = false + _is_running = false, }, Session) end +--- @param timeout integer? +--- @return string? function Session:next_message(timeout) local function on_request(method, args, response) - table.insert(self._pending_messages, {'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}) + table.insert(self._pending_messages, { 'notification', method, args }) uv.stop() end @@ -83,11 +91,15 @@ function Session:next_message(timeout) end function Session:notify(method, ...) - self._msgpack_rpc_stream:write(method, {...}) + self._msgpack_rpc_stream:write(method, { ... }) end +--- @param method string +--- @param ... any +--- @return boolean +--- @return table function Session:request(method, ...) - local args = {...} + local args = { ... } local err, result if self._is_running then err, result = self:_yielding_request(method, args) @@ -141,8 +153,12 @@ function Session: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 + 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) self.closed = true end @@ -159,11 +175,11 @@ 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}) + table.insert(self._pending_messages, { 'request', method_, args_, response }) end local function on_notification(method_, args_) - table.insert(self._pending_messages, {'notification', method_, args_}) + table.insert(self._pending_messages, { 'notification', method_, args_ }) end self._msgpack_rpc_stream:write(method, args, function(e, r) @@ -187,7 +203,7 @@ function Session:_run(request_cb, notification_cb, timeout) 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."} + self.eof_err = { 1, 'EOF was received from Nvim. Likely the Nvim process crashed.' } end) uv.run() self._prepare:stop() diff --git a/test/client/uv_stream.lua b/test/client/uv_stream.lua index cea77f0dbd..0540c44eb2 100644 --- a/test/client/uv_stream.lua +++ b/test/client/uv_stream.lua @@ -1,18 +1,28 @@ -local uv = require('luv') +local uv = vim.uv +--- @class test.Stream +--- @field write fun(self, data: string|string[]) +--- @field read_start fun(self, cb: fun(chunk: string)) +--- @field read_stop fun(self) +--- @field close fun(self, signal?: string) + +--- @class vim.StdioStream : test.Stream +--- @field private _in uv.uv_pipe_t +--- @field private _out uv.uv_pipe_t local StdioStream = {} StdioStream.__index = StdioStream function StdioStream.open() local self = setmetatable({ - _in = uv.new_pipe(false), - _out = uv.new_pipe(false) + _in = assert(uv.new_pipe(false)), + _out = assert(uv.new_pipe(false)), }, StdioStream) self._in:open(0) self._out:open(1) return self end +--- @param data string|string[] function StdioStream:write(data) self._out:write(data) end @@ -35,34 +45,36 @@ function StdioStream:close() self._out:close() end +--- @class test.SocketStream : test.Stream +--- @field package _stream_error? string +--- @field package _socket uv.uv_pipe_t local SocketStream = {} SocketStream.__index = SocketStream function SocketStream.open(file) - local socket = uv.new_pipe(false) + local socket = assert(uv.new_pipe(false)) local self = setmetatable({ _socket = socket, - _stream_error = nil + _stream_error = nil, }, SocketStream) - uv.pipe_connect(socket, file, function (err) + 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 socket = assert(uv.new_tcp()) local self = setmetatable({ _socket = socket, - _stream_error = nil + _stream_error = nil, }, SocketStream) - uv.tcp_connect(socket, host, port, function (err) + 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) @@ -97,23 +109,36 @@ function SocketStream:close() uv.close(self._socket) end +--- @class test.ChildProcessStream : test.Stream +--- @field private _proc uv.uv_process_t +--- @field private _pid integer +--- @field private _child_stdin uv.uv_pipe_t +--- @field private _child_stdout uv.uv_pipe_t +--- @field status integer +--- @field signal integer local ChildProcessStream = {} ChildProcessStream.__index = ChildProcessStream +--- @param argv string[] +--- @param env string[]? +--- @param io_extra uv.uv_pipe_t? +--- @return test.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; + _child_stdin = uv.new_pipe(false), + _child_stdout = uv.new_pipe(false), + _exiting = false, }, ChildProcessStream) local prog = argv[1] - local args = {} + local args = {} --- @type string[] for i = 2, #argv do args[#args + 1] = argv[i] end + --- @diagnostic disable-next-line:missing-fields self._proc, self._pid = uv.spawn(prog, { - stdio = {self._child_stdin, self._child_stdout, 2, io_extra}, + stdio = { self._child_stdin, self._child_stdout, 2, io_extra }, args = args, + --- @diagnostic disable-next-line:assign-type-mismatch env = env, }, function(status, signal) self.status = status @@ -154,7 +179,7 @@ function ChildProcessStream:close(signal) self._child_stdin:close() self._child_stdout:close() if type(signal) == 'string' then - self._proc:kill('sig'..signal) + self._proc:kill('sig' .. signal) end while self.status == nil do uv.run 'once' @@ -163,7 +188,7 @@ function ChildProcessStream:close(signal) end return { - StdioStream = StdioStream; - ChildProcessStream = ChildProcessStream; - SocketStream = SocketStream; + StdioStream = StdioStream, + ChildProcessStream = ChildProcessStream, + SocketStream = SocketStream, } |