neovim 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -1
- data/.travis.yml +2 -3
- data/CHANGELOG.md +29 -0
- data/Gemfile +0 -11
- data/README.md +3 -3
- data/Rakefile +1 -1
- data/appveyor.yml +9 -1
- data/lib/neovim.rb +3 -3
- data/lib/neovim/client.rb +2 -3
- data/lib/neovim/connection.rb +69 -0
- data/lib/neovim/event_loop.rb +34 -34
- data/lib/neovim/host.rb +47 -51
- data/lib/neovim/host/loader.rb +1 -4
- data/lib/neovim/logging.rb +8 -8
- data/lib/neovim/message.rb +70 -0
- data/lib/neovim/plugin.rb +0 -3
- data/lib/neovim/plugin/handler.rb +6 -6
- data/lib/neovim/remote_object.rb +1 -1
- data/lib/neovim/ruby_provider.rb +25 -14
- data/lib/neovim/session.rb +36 -43
- data/lib/neovim/version.rb +1 -1
- data/neovim.gemspec +4 -0
- data/spec/acceptance/runtime/rplugin/ruby/autocmds.rb +3 -3
- data/spec/acceptance/runtime/rplugin/ruby/commands.rb +15 -15
- data/spec/acceptance/runtime/rplugin/ruby/functions.rb +5 -5
- data/spec/acceptance_spec.rb +19 -16
- data/spec/helper.rb +15 -0
- data/spec/neovim/connection_spec.rb +79 -0
- data/spec/neovim/event_loop_spec.rb +36 -50
- data/spec/neovim/host/loader_spec.rb +16 -9
- data/spec/neovim/host_spec.rb +82 -92
- data/spec/neovim/logging_spec.rb +6 -6
- data/spec/neovim/message_spec.rb +119 -0
- data/spec/neovim/plugin_spec.rb +31 -31
- data/spec/neovim/session_spec.rb +1 -1
- metadata +38 -15
- data/lib/neovim/event_loop/connection.rb +0 -78
- data/lib/neovim/event_loop/message_builder.rb +0 -127
- data/lib/neovim/event_loop/serializer.rb +0 -37
- data/spec/acceptance/runtime/rplugin.vim +0 -37
- data/spec/neovim/event_loop/connection_spec.rb +0 -89
- data/spec/neovim/event_loop/message_builder_spec.rb +0 -105
- data/spec/neovim/event_loop/serializer_spec.rb +0 -63
data/spec/neovim/session_spec.rb
CHANGED
@@ -24,7 +24,7 @@ module Neovim
|
|
24
24
|
expect(session.request(:nvim_get_current_line)).to eq(large_str)
|
25
25
|
end
|
26
26
|
|
27
|
-
it "fails outside of the main thread" do
|
27
|
+
it "fails outside of the main thread", :silence_thread_exceptions do
|
28
28
|
expect {
|
29
29
|
Thread.new { session.request(:nvim_strwidth, "foo") }.join
|
30
30
|
}.to raise_error(/outside of the main thread/)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neovim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Genco
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -80,6 +80,34 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: coveralls
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: rspec
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,16 +147,15 @@ files:
|
|
119
147
|
- lib/neovim/api.rb
|
120
148
|
- lib/neovim/buffer.rb
|
121
149
|
- lib/neovim/client.rb
|
150
|
+
- lib/neovim/connection.rb
|
122
151
|
- lib/neovim/current.rb
|
123
152
|
- lib/neovim/event_loop.rb
|
124
|
-
- lib/neovim/event_loop/connection.rb
|
125
|
-
- lib/neovim/event_loop/message_builder.rb
|
126
|
-
- lib/neovim/event_loop/serializer.rb
|
127
153
|
- lib/neovim/executable.rb
|
128
154
|
- lib/neovim/host.rb
|
129
155
|
- lib/neovim/host/loader.rb
|
130
156
|
- lib/neovim/line_range.rb
|
131
157
|
- lib/neovim/logging.rb
|
158
|
+
- lib/neovim/message.rb
|
132
159
|
- lib/neovim/plugin.rb
|
133
160
|
- lib/neovim/plugin/dsl.rb
|
134
161
|
- lib/neovim/plugin/handler.rb
|
@@ -164,7 +191,6 @@ files:
|
|
164
191
|
- spec/acceptance/rubyfile/set_pwd_before.rb
|
165
192
|
- spec/acceptance/rubyfile_spec.vim
|
166
193
|
- spec/acceptance/runtime/init.vim
|
167
|
-
- spec/acceptance/runtime/rplugin.vim
|
168
194
|
- spec/acceptance/runtime/rplugin/ruby/autocmds.rb
|
169
195
|
- spec/acceptance/runtime/rplugin/ruby/commands.rb
|
170
196
|
- spec/acceptance/runtime/rplugin/ruby/functions.rb
|
@@ -180,16 +206,15 @@ files:
|
|
180
206
|
- spec/neovim/api_spec.rb
|
181
207
|
- spec/neovim/buffer_spec.rb
|
182
208
|
- spec/neovim/client_spec.rb
|
209
|
+
- spec/neovim/connection_spec.rb
|
183
210
|
- spec/neovim/current_spec.rb
|
184
|
-
- spec/neovim/event_loop/connection_spec.rb
|
185
|
-
- spec/neovim/event_loop/message_builder_spec.rb
|
186
|
-
- spec/neovim/event_loop/serializer_spec.rb
|
187
211
|
- spec/neovim/event_loop_spec.rb
|
188
212
|
- spec/neovim/executable_spec.rb
|
189
213
|
- spec/neovim/host/loader_spec.rb
|
190
214
|
- spec/neovim/host_spec.rb
|
191
215
|
- spec/neovim/line_range_spec.rb
|
192
216
|
- spec/neovim/logging_spec.rb
|
217
|
+
- spec/neovim/message_spec.rb
|
193
218
|
- spec/neovim/plugin_spec.rb
|
194
219
|
- spec/neovim/remote_object_spec.rb
|
195
220
|
- spec/neovim/ruby_provider/buffer_ext_spec.rb
|
@@ -211,7 +236,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
211
236
|
requirements:
|
212
237
|
- - ">="
|
213
238
|
- !ruby/object:Gem::Version
|
214
|
-
version:
|
239
|
+
version: 2.2.0
|
215
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
241
|
requirements:
|
217
242
|
- - ">="
|
@@ -219,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
244
|
version: '0'
|
220
245
|
requirements: []
|
221
246
|
rubyforge_project:
|
222
|
-
rubygems_version: 2.
|
247
|
+
rubygems_version: 2.7.3
|
223
248
|
signing_key:
|
224
249
|
specification_version: 4
|
225
250
|
summary: A Ruby client for Neovim
|
@@ -242,7 +267,6 @@ test_files:
|
|
242
267
|
- spec/acceptance/rubyfile/set_pwd_before.rb
|
243
268
|
- spec/acceptance/rubyfile_spec.vim
|
244
269
|
- spec/acceptance/runtime/init.vim
|
245
|
-
- spec/acceptance/runtime/rplugin.vim
|
246
270
|
- spec/acceptance/runtime/rplugin/ruby/autocmds.rb
|
247
271
|
- spec/acceptance/runtime/rplugin/ruby/commands.rb
|
248
272
|
- spec/acceptance/runtime/rplugin/ruby/functions.rb
|
@@ -258,16 +282,15 @@ test_files:
|
|
258
282
|
- spec/neovim/api_spec.rb
|
259
283
|
- spec/neovim/buffer_spec.rb
|
260
284
|
- spec/neovim/client_spec.rb
|
285
|
+
- spec/neovim/connection_spec.rb
|
261
286
|
- spec/neovim/current_spec.rb
|
262
|
-
- spec/neovim/event_loop/connection_spec.rb
|
263
|
-
- spec/neovim/event_loop/message_builder_spec.rb
|
264
|
-
- spec/neovim/event_loop/serializer_spec.rb
|
265
287
|
- spec/neovim/event_loop_spec.rb
|
266
288
|
- spec/neovim/executable_spec.rb
|
267
289
|
- spec/neovim/host/loader_spec.rb
|
268
290
|
- spec/neovim/host_spec.rb
|
269
291
|
- spec/neovim/line_range_spec.rb
|
270
292
|
- spec/neovim/logging_spec.rb
|
293
|
+
- spec/neovim/message_spec.rb
|
271
294
|
- spec/neovim/plugin_spec.rb
|
272
295
|
- spec/neovim/remote_object_spec.rb
|
273
296
|
- spec/neovim/ruby_provider/buffer_ext_spec.rb
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require "neovim/logging"
|
2
|
-
require "socket"
|
3
|
-
|
4
|
-
module Neovim
|
5
|
-
class EventLoop
|
6
|
-
# The lowest level interface to reading from and writing to +nvim+.
|
7
|
-
#
|
8
|
-
# @api private
|
9
|
-
class Connection
|
10
|
-
include Logging
|
11
|
-
|
12
|
-
def self.tcp(host, port)
|
13
|
-
socket = Socket.tcp(host, port)
|
14
|
-
new(socket, socket)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.unix(path)
|
18
|
-
socket = Socket.unix(path)
|
19
|
-
new(socket, socket)
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.child(_argv)
|
23
|
-
argv = _argv.include?("--embed") ? _argv : _argv + ["--embed"]
|
24
|
-
|
25
|
-
io = ::IO.popen(argv, "rb+").tap do |_io|
|
26
|
-
Process.detach(_io.pid)
|
27
|
-
end
|
28
|
-
|
29
|
-
new(io, io)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.stdio
|
33
|
-
new(STDIN, STDOUT)
|
34
|
-
end
|
35
|
-
|
36
|
-
def initialize(rd, wr)
|
37
|
-
@rd, @wr = [rd, wr].map(&:binmode)
|
38
|
-
@running = false
|
39
|
-
end
|
40
|
-
|
41
|
-
# Write data to the underlying +IO+. This will block until all the
|
42
|
-
# data has been written.
|
43
|
-
def write(data)
|
44
|
-
written = 0
|
45
|
-
total = data.bytesize
|
46
|
-
log(:debug) { {:bytes => total} }
|
47
|
-
|
48
|
-
begin
|
49
|
-
while written < total
|
50
|
-
written += @wr.write_nonblock(data[written..-1])
|
51
|
-
end
|
52
|
-
rescue ::IO::WaitWritable
|
53
|
-
::IO.select(nil, [@wr], nil, 1)
|
54
|
-
retry
|
55
|
-
ensure
|
56
|
-
@wr.flush
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def read
|
61
|
-
@rd.readpartial(1024 * 16).tap do |bytes|
|
62
|
-
log(:debug) { {:bytes => bytes.bytesize} }
|
63
|
-
yield bytes
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Close underlying +IO+s.
|
68
|
-
def close
|
69
|
-
[@rd, @wr].each do |io|
|
70
|
-
begin
|
71
|
-
io.close
|
72
|
-
rescue ::IOError
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,127 +0,0 @@
|
|
1
|
-
require "neovim/logging"
|
2
|
-
|
3
|
-
module Neovim
|
4
|
-
class EventLoop
|
5
|
-
# Handles formatting RPC messages and registering response callbacks for
|
6
|
-
# requests.
|
7
|
-
#
|
8
|
-
# @api private
|
9
|
-
class MessageBuilder
|
10
|
-
module StructToH
|
11
|
-
def to_h
|
12
|
-
each_pair.inject({}) { |acc, (k, v)| acc.merge(k => v) }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class Request < Struct.new(:id, :method_name, :arguments)
|
17
|
-
include StructToH
|
18
|
-
|
19
|
-
def sync?
|
20
|
-
true
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_h
|
24
|
-
super.merge(:type => :request)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Notification < Struct.new(:method_name, :arguments)
|
29
|
-
include StructToH
|
30
|
-
|
31
|
-
def sync?
|
32
|
-
false
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_h
|
36
|
-
super.merge(:type => :notification)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Response < Struct.new(:request_id, :value, :error)
|
41
|
-
include StructToH
|
42
|
-
|
43
|
-
def value!
|
44
|
-
error ? raise(error) : value
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_h
|
48
|
-
super.merge(:type => :response)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
include Logging
|
53
|
-
|
54
|
-
def initialize
|
55
|
-
@request_id = 0
|
56
|
-
@pending_requests = {}
|
57
|
-
end
|
58
|
-
|
59
|
-
def write(type, *write_args)
|
60
|
-
case type
|
61
|
-
when :request
|
62
|
-
method, args, response_handler = write_args
|
63
|
-
|
64
|
-
@request_id += 1
|
65
|
-
@pending_requests[@request_id] = response_handler
|
66
|
-
|
67
|
-
log(:debug) do
|
68
|
-
{
|
69
|
-
:type => type,
|
70
|
-
:request_id => @request_id,
|
71
|
-
:method_name => method,
|
72
|
-
:arguments => args,
|
73
|
-
}
|
74
|
-
end
|
75
|
-
|
76
|
-
yield [0, @request_id, method, args]
|
77
|
-
when :response
|
78
|
-
reqid, value, error = write_args
|
79
|
-
|
80
|
-
log(:debug) do
|
81
|
-
{
|
82
|
-
:type => type,
|
83
|
-
:request_id => reqid,
|
84
|
-
:value => value,
|
85
|
-
:error => error,
|
86
|
-
}
|
87
|
-
end
|
88
|
-
|
89
|
-
yield [1, reqid, error, value]
|
90
|
-
when :notification
|
91
|
-
method, args = write_args
|
92
|
-
|
93
|
-
log(:debug) do
|
94
|
-
{
|
95
|
-
:type => type,
|
96
|
-
:method_name => method,
|
97
|
-
:arguments => args,
|
98
|
-
}
|
99
|
-
end
|
100
|
-
|
101
|
-
yield [2, method, args]
|
102
|
-
else
|
103
|
-
raise "Unknown RPC message type #{type}"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def read((kind, *payload))
|
108
|
-
case kind
|
109
|
-
when 0
|
110
|
-
message = Request.new(*payload)
|
111
|
-
log(:debug) { message.to_h }
|
112
|
-
yield message
|
113
|
-
when 2
|
114
|
-
message = Notification.new(*payload)
|
115
|
-
log(:debug) { message.to_h }
|
116
|
-
yield message
|
117
|
-
when 1
|
118
|
-
reqid, (_, error), result = payload
|
119
|
-
handler = @pending_requests.delete(reqid) || Proc.new {}
|
120
|
-
message = Response.new(reqid, result, error)
|
121
|
-
log(:debug) { message.to_h }
|
122
|
-
handler.call(message)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require "neovim/logging"
|
2
|
-
require "msgpack"
|
3
|
-
|
4
|
-
module Neovim
|
5
|
-
class EventLoop
|
6
|
-
# Handles serializing RPC messages to and from MessagePack
|
7
|
-
#
|
8
|
-
# @api private
|
9
|
-
class Serializer
|
10
|
-
include Logging
|
11
|
-
|
12
|
-
def initialize(unpacker = MessagePack::Unpacker.new)
|
13
|
-
@unpacker = unpacker
|
14
|
-
end
|
15
|
-
|
16
|
-
# Serialize an RPC message
|
17
|
-
def write(obj)
|
18
|
-
log(:debug) { {:object => obj} }
|
19
|
-
yield MessagePack.pack(obj)
|
20
|
-
end
|
21
|
-
|
22
|
-
def read(bytes)
|
23
|
-
@unpacker.feed_each(bytes) do |obj|
|
24
|
-
log(:debug) { {:object => obj} }
|
25
|
-
yield obj
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def register_type(id, &block)
|
30
|
-
@unpacker.register_type(id) do |data|
|
31
|
-
index = MessagePack.unpack(data)
|
32
|
-
block.call(index)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
" python3 plugins
|
2
|
-
|
3
|
-
|
4
|
-
" ruby plugins
|
5
|
-
call remote#host#RegisterPlugin('ruby', './runtime/rplugin/ruby/autocmds.rb', [
|
6
|
-
\ {'sync': v:false, 'name': 'BufEnter', 'type': 'autocmd', 'opts': {'pattern': '*.rb'}},
|
7
|
-
\ {'sync': v:false, 'name': 'BufEnter', 'type': 'autocmd', 'opts': {'pattern': '*.c', 'eval': 'g:to_eval'}},
|
8
|
-
\ ])
|
9
|
-
call remote#host#RegisterPlugin('ruby', './runtime/rplugin/ruby/commands.rb', [
|
10
|
-
\ {'sync': v:false, 'name': 'RPluginCommandNargs0', 'type': 'command', 'opts': {}},
|
11
|
-
\ {'sync': v:false, 'name': 'RPluginCommandNargs1', 'type': 'command', 'opts': {'nargs': 1}},
|
12
|
-
\ {'sync': v:false, 'name': 'RPluginCommandNargsN', 'type': 'command', 'opts': {'nargs': '*'}},
|
13
|
-
\ {'sync': v:false, 'name': 'RPluginCommandNargsQ', 'type': 'command', 'opts': {'nargs': '?'}},
|
14
|
-
\ {'sync': v:false, 'name': 'RPluginCommandNargsP', 'type': 'command', 'opts': {'nargs': '+'}},
|
15
|
-
\ {'sync': v:false, 'name': 'RPluginCommandRange', 'type': 'command', 'opts': {'range': ''}},
|
16
|
-
\ {'sync': v:false, 'name': 'RPluginCommandRangeP', 'type': 'command', 'opts': {'range': '%'}},
|
17
|
-
\ {'sync': v:false, 'name': 'RPluginCommandRangeN', 'type': 'command', 'opts': {'range': '1'}},
|
18
|
-
\ {'sync': v:false, 'name': 'RPluginCommandCountN', 'type': 'command', 'opts': {'count': 1}},
|
19
|
-
\ {'sync': v:false, 'name': 'RPluginCommandBang', 'type': 'command', 'opts': {'bang': ''}},
|
20
|
-
\ {'sync': v:false, 'name': 'RPluginCommandRegister', 'type': 'command', 'opts': {'register': ''}},
|
21
|
-
\ {'sync': v:false, 'name': 'RPluginCommandCompletion', 'type': 'command', 'opts': {'complete': 'buffer'}},
|
22
|
-
\ {'sync': v:false, 'name': 'RPluginCommandEval', 'type': 'command', 'opts': {'eval': 'g:to_eval'}},
|
23
|
-
\ {'sync': v:true, 'name': 'RPluginCommandSync', 'type': 'command', 'opts': {}},
|
24
|
-
\ {'sync': v:true, 'name': 'RPluginCommandRecursive', 'type': 'command', 'opts': {'nargs': 1}},
|
25
|
-
\ ])
|
26
|
-
call remote#host#RegisterPlugin('ruby', './runtime/rplugin/ruby/functions.rb', [
|
27
|
-
\ {'sync': v:false, 'name': 'RPluginFunctionArgs', 'type': 'function', 'opts': {}},
|
28
|
-
\ {'sync': v:false, 'name': 'RPluginFunctionRange', 'type': 'function', 'opts': {'range': ''}},
|
29
|
-
\ {'sync': v:false, 'name': 'RPluginFunctionEval', 'type': 'function', 'opts': {'eval': 'g:to_eval'}},
|
30
|
-
\ {'sync': v:true, 'name': 'RPluginFunctionSync', 'type': 'function', 'opts': {}},
|
31
|
-
\ {'sync': v:true, 'name': 'RPluginFunctionRecursive', 'type': 'function', 'opts': {'nargs': 1}},
|
32
|
-
\ ])
|
33
|
-
|
34
|
-
|
35
|
-
" python plugins
|
36
|
-
|
37
|
-
|
@@ -1,89 +0,0 @@
|
|
1
|
-
require "helper"
|
2
|
-
|
3
|
-
module Neovim
|
4
|
-
class EventLoop
|
5
|
-
RSpec.describe Connection do
|
6
|
-
let(:nil_io) { StringIO.new }
|
7
|
-
|
8
|
-
describe "#write" do
|
9
|
-
it "writes to the underlying file descriptor" do
|
10
|
-
rd, wr = IO.pipe
|
11
|
-
connection = Connection.new(nil_io, wr)
|
12
|
-
connection.write("some data")
|
13
|
-
wr.close
|
14
|
-
|
15
|
-
expect(rd.read).to eq("some data")
|
16
|
-
end
|
17
|
-
|
18
|
-
it "writes large amounts of data" do
|
19
|
-
port = Support.tcp_port
|
20
|
-
|
21
|
-
server_thr = Thread.new do
|
22
|
-
read_result = ""
|
23
|
-
|
24
|
-
TCPServer.open("127.0.0.1", port) do |server|
|
25
|
-
client = server.accept
|
26
|
-
|
27
|
-
loop do
|
28
|
-
begin
|
29
|
-
read_result << client.readpartial(1024 * 16)
|
30
|
-
rescue EOFError
|
31
|
-
break
|
32
|
-
end
|
33
|
-
end
|
34
|
-
client.close
|
35
|
-
end
|
36
|
-
|
37
|
-
read_result
|
38
|
-
end
|
39
|
-
|
40
|
-
begin
|
41
|
-
socket = Socket.tcp("127.0.0.1", port)
|
42
|
-
rescue Errno::ECONNREFUSED
|
43
|
-
retry
|
44
|
-
end
|
45
|
-
|
46
|
-
big_data = Array.new(1024 * 16) { SecureRandom.hex(4) }.join
|
47
|
-
connection = Connection.new(nil_io, socket)
|
48
|
-
|
49
|
-
connection.write(big_data)
|
50
|
-
socket.close
|
51
|
-
expect(server_thr.value).to eq(big_data)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe "#read" do
|
56
|
-
it "yields data from the underlying file descriptor" do
|
57
|
-
rd, wr = IO.pipe
|
58
|
-
wr.write("some data")
|
59
|
-
wr.close
|
60
|
-
|
61
|
-
connection = Connection.new(rd, nil_io)
|
62
|
-
|
63
|
-
expect do |y|
|
64
|
-
connection.read(&y)
|
65
|
-
end.to yield_with_args("some data")
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe "#close" do
|
70
|
-
it "closes IO handles" do
|
71
|
-
rd, wr = ::IO.pipe
|
72
|
-
Connection.new(rd, wr).close
|
73
|
-
|
74
|
-
expect(rd).to be_closed
|
75
|
-
expect(wr).to be_closed
|
76
|
-
end
|
77
|
-
|
78
|
-
it "kills spawned processes" do
|
79
|
-
io = ::IO.popen("cat", "rb+")
|
80
|
-
pid = io.pid
|
81
|
-
expect(pid).to respond_to(:to_int)
|
82
|
-
|
83
|
-
Connection.new(io, nil_io).close
|
84
|
-
expect { Process.kill(0, pid) }.to raise_error(Errno::ESRCH)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|