neovim 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|