Class: Pikuri::Lsp::Testing::Wire
- Inherits:
-
Object
- Object
- Pikuri::Lsp::Testing::Wire
- Defined in:
- lib/pikuri/lsp/testing.rb
Overview
The server side of one LSP channel: hand-rolled framing over a pair of pipes, blocking reads, and no behaviour of its own.
Drive it from the example's thread with the client under test on a worker (or use FakeServer). A spec that writes more than the pipe buffer with nobody reading will deadlock.
Class Method Summary collapse
-
.channel ⇒ Array(Hash{Symbol => IO}, Wire)
The client's
{stdin:, stdout:}kwargs, and the server side of the same pair.
Instance Method Summary collapse
-
#close ⇒ void
Close both ends — from the client's side, indistinguishable from the server dying.
-
#handshake(capabilities: {}, server_info: nil) ⇒ Hash
Play the server half of the handshake: answer
initialize, absorbinitialized. -
#initialize(read:, write:) ⇒ Wire
constructor
A new instance of Wire.
- #notify(method, params = {}) ⇒ void
- #reply(request, result) ⇒ void
- #reply_error(request, code:, message:) ⇒ void
-
#request(method, params = {}, id: 'server-1') ⇒ void
Ask the client something, which a real server does for
window/workDoneProgress/createandworkspace/configuration. - #send_message(message) ⇒ void
-
#send_raw(body) ⇒ void
Frame and send
bodyexactly as given — the door recorded bytes come through. -
#take ⇒ Hash{String => Object}
The next message the client wrote, blocking until there is one.
Constructor Details
#initialize(read:, write:) ⇒ Wire
Returns a new instance of Wire.
71 72 73 74 |
# File 'lib/pikuri/lsp/testing.rb', line 71 def initialize(read:, write:) @read = read @write = write end |
Class Method Details
.channel ⇒ Array(Hash{Symbol => IO}, Wire)
Returns the client's
{stdin:, stdout:} kwargs, and the server side of the same pair.
62 63 64 65 66 67 |
# File 'lib/pikuri/lsp/testing.rb', line 62 def self.channel to_server = IO.pipe to_client = IO.pipe [{ stdin: to_server[1], stdout: to_client[0] }, new(read: to_server[0], write: to_client[1])] end |
Instance Method Details
#close ⇒ void
This method returns an undefined value.
Close both ends — from the client's side, indistinguishable from the server dying.
167 168 169 |
# File 'lib/pikuri/lsp/testing.rb', line 167 def close [@write, @read].each { |io| io.close unless io.closed? } end |
#handshake(capabilities: {}, server_info: nil) ⇒ Hash
Play the server half of the handshake: answer initialize, absorb
initialized.
150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/pikuri/lsp/testing.rb', line 150 def handshake(capabilities: {}, server_info: nil) request = take raise "expected initialize, got #{request['method'].inspect}" unless request['method'] == 'initialize' result = { 'capabilities' => capabilities } result['serverInfo'] = server_info if server_info reply(request, result) absorbed = take raise "expected initialized, got #{absorbed['method'].inspect}" unless absorbed['method'] == 'initialized' request end |
#notify(method, params = {}) ⇒ void
This method returns an undefined value.
126 127 128 |
# File 'lib/pikuri/lsp/testing.rb', line 126 def notify(method, params = {}) ('jsonrpc' => '2.0', 'method' => method, 'params' => params) end |
#reply(request, result) ⇒ void
This method returns an undefined value.
109 110 111 |
# File 'lib/pikuri/lsp/testing.rb', line 109 def reply(request, result) ('jsonrpc' => '2.0', 'id' => request['id'], 'result' => result) end |
#reply_error(request, code:, message:) ⇒ void
This method returns an undefined value.
118 119 120 121 |
# File 'lib/pikuri/lsp/testing.rb', line 118 def reply_error(request, code:, message:) ('jsonrpc' => '2.0', 'id' => request['id'], 'error' => { 'code' => code, 'message' => }) end |
#request(method, params = {}, id: 'server-1') ⇒ void
This method returns an undefined value.
Ask the client something, which a real server does for
window/workDoneProgress/create and workspace/configuration.
138 139 140 |
# File 'lib/pikuri/lsp/testing.rb', line 138 def request(method, params = {}, id: 'server-1') ('jsonrpc' => '2.0', 'id' => id, 'method' => method, 'params' => params) end |
#send_message(message) ⇒ void
This method returns an undefined value.
101 102 103 |
# File 'lib/pikuri/lsp/testing.rb', line 101 def () send_raw(JSON.generate()) end |
#send_raw(body) ⇒ void
This method returns an undefined value.
Frame and send body exactly as given — the door recorded bytes come
through.
94 95 96 97 |
# File 'lib/pikuri/lsp/testing.rb', line 94 def send_raw(body) @write.write("Content-Length: #{body.bytesize}\r\n\r\n#{body}") @write.flush end |
#take ⇒ Hash{String => Object}
The next message the client wrote, blocking until there is one.
80 81 82 83 84 85 86 87 |
# File 'lib/pikuri/lsp/testing.rb', line 80 def take headers = {} while (line = @read.readline("\r\n").chomp("\r\n")) != '' key, value = line.split(':', 2) headers[key.strip.downcase] = value.strip end JSON.parse(@read.read(Integer(headers.fetch('content-length')))) end |