neovim 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/CHANGELOG.md +9 -3
- data/CODE_OF_CONDUCT.md +46 -0
- data/README.md +2 -2
- data/Rakefile +6 -6
- data/lib/neovim.rb +8 -7
- data/lib/neovim/api.rb +87 -0
- data/lib/neovim/buffer.rb +7 -1
- data/lib/neovim/client.rb +32 -6
- data/lib/neovim/event_loop.rb +114 -0
- data/lib/neovim/event_loop/connection.rb +78 -0
- data/lib/neovim/event_loop/message_builder.rb +127 -0
- data/lib/neovim/event_loop/serializer.rb +37 -0
- data/lib/neovim/host.rb +28 -28
- data/lib/neovim/logging.rb +41 -19
- data/lib/neovim/plugin/dsl.rb +6 -6
- data/lib/neovim/remote_object.rb +2 -2
- data/lib/neovim/ruby_provider.rb +8 -6
- data/lib/neovim/ruby_provider/vim.rb +2 -2
- data/lib/neovim/session.rb +42 -79
- data/lib/neovim/tabpage.rb +1 -1
- data/lib/neovim/version.rb +1 -1
- data/lib/neovim/window.rb +1 -1
- data/script/dump_api +4 -2
- data/script/generate_docs +2 -1
- data/spec/{integration → acceptance}/rplugin_autocmd_spec.vim +1 -1
- data/spec/{integration → acceptance}/rplugin_command_spec.vim +6 -2
- data/spec/{integration → acceptance}/rplugin_function_spec.vim +5 -2
- data/spec/{integration → acceptance}/ruby_spec.vim +18 -0
- data/spec/{integration → acceptance}/rubydo_spec.vim +0 -0
- data/spec/{integration → acceptance}/rubyfile/call_foo.rb +0 -0
- data/spec/{integration → acceptance}/rubyfile/curbuf_ivar_get.rb +0 -0
- data/spec/{integration → acceptance}/rubyfile/curbuf_ivar_set.rb +0 -0
- data/spec/{integration → acceptance}/rubyfile/define_foo.rb +0 -0
- data/spec/acceptance/rubyfile/nested.rb +1 -0
- data/spec/acceptance/rubyfile/nested_inner.rb +1 -0
- data/spec/{integration → acceptance}/rubyfile/raise_standard_error.rb +0 -0
- data/spec/{integration → acceptance}/rubyfile/raise_syntax_error.rb +0 -0
- data/spec/acceptance/rubyfile/ruby_interface.rb +8 -0
- data/spec/{integration → acceptance}/rubyfile/set_pwd_after.rb +0 -0
- data/spec/{integration → acceptance}/rubyfile/set_pwd_before.rb +0 -0
- data/spec/{integration → acceptance}/rubyfile_spec.vim +9 -0
- data/spec/acceptance/runtime/init.vim +8 -0
- data/spec/acceptance/runtime/rplugin.vim +37 -0
- data/spec/{integration → acceptance}/runtime/rplugin/ruby/autocmds.rb +1 -1
- data/spec/{integration → acceptance}/runtime/rplugin/ruby/commands.rb +9 -1
- data/spec/{integration → acceptance}/runtime/rplugin/ruby/functions.rb +9 -1
- data/spec/{integration → acceptance}/runtime/vader.vim/autoload/vader.vim +0 -0
- data/spec/{integration → acceptance}/runtime/vader.vim/autoload/vader/assert.vim +0 -0
- data/spec/{integration → acceptance}/runtime/vader.vim/autoload/vader/helper.vim +0 -0
- data/spec/{integration → acceptance}/runtime/vader.vim/autoload/vader/parser.vim +0 -0
- data/spec/{integration → acceptance}/runtime/vader.vim/autoload/vader/syntax.vim +0 -0
- data/spec/{integration → acceptance}/runtime/vader.vim/autoload/vader/window.vim +0 -0
- data/spec/{integration → acceptance}/runtime/vader.vim/plugin/vader.vim +0 -0
- data/spec/acceptance_spec.rb +74 -0
- data/spec/helper.rb +2 -32
- data/spec/neovim/api_spec.rb +59 -0
- data/spec/neovim/buffer_spec.rb +161 -2
- data/spec/neovim/client_spec.rb +18 -4
- data/spec/neovim/event_loop/connection_spec.rb +63 -0
- data/spec/neovim/event_loop/message_builder_spec.rb +105 -0
- data/spec/neovim/event_loop/serializer_spec.rb +63 -0
- data/spec/neovim/event_loop_spec.rb +81 -0
- data/spec/neovim/host/loader_spec.rb +0 -1
- data/spec/neovim/host_spec.rb +130 -161
- data/spec/neovim/logging_spec.rb +77 -5
- data/spec/neovim/session_spec.rb +54 -127
- data/spec/neovim/window_spec.rb +46 -0
- metadata +81 -81
- data/lib/neovim/session/api.rb +0 -95
- data/lib/neovim/session/event_loop.rb +0 -100
- data/lib/neovim/session/notification.rb +0 -19
- data/lib/neovim/session/request.rb +0 -31
- data/lib/neovim/session/rpc.rb +0 -95
- data/lib/neovim/session/serializer.rb +0 -62
- data/spec/integration/ruby_buffer_spec.rb +0 -151
- data/spec/integration/ruby_vim_spec.rb +0 -27
- data/spec/integration/ruby_window_spec.rb +0 -56
- data/spec/integration/runtime/init.vim +0 -9
- data/spec/integration_spec.rb +0 -119
- data/spec/neovim/session/api_spec.rb +0 -70
- data/spec/neovim/session/event_loop_spec.rb +0 -152
- data/spec/neovim/session/notification_spec.rb +0 -20
- data/spec/neovim/session/request_spec.rb +0 -36
- data/spec/neovim/session/rpc_spec.rb +0 -120
- data/spec/neovim/session/serializer_spec.rb +0 -62
data/spec/neovim/client_spec.rb
CHANGED
@@ -5,10 +5,24 @@ module Neovim
|
|
5
5
|
let(:client) { Neovim.attach_child(Support.child_argv) }
|
6
6
|
after { client.shutdown }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
describe "#set_option" do
|
9
|
+
it "sets an option from two arguments" do
|
10
|
+
expect {
|
11
|
+
client.set_option("makeprg", "rake")
|
12
|
+
}.to change { client.evaluate("&makeprg") }.to("rake")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "sets an option from a string" do
|
16
|
+
expect {
|
17
|
+
client.set_option("timeoutlen=0")
|
18
|
+
}.to change { client.evaluate("&timeoutlen") }.to(0)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sets a boolean option" do
|
22
|
+
expect {
|
23
|
+
client.set_option("expandtab")
|
24
|
+
}.to change { client.evaluate("&expandtab") }.to(1)
|
25
|
+
end
|
12
26
|
end
|
13
27
|
|
14
28
|
describe "#respond_to?" do
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
class EventLoop
|
5
|
+
RSpec.describe Connection do
|
6
|
+
describe "#write" do
|
7
|
+
it "writes to the underlying file descriptor" do
|
8
|
+
rd, wr = IO.pipe
|
9
|
+
connection = Connection.new(nil, wr)
|
10
|
+
connection.write("some data")
|
11
|
+
wr.close
|
12
|
+
|
13
|
+
expect(rd.read).to eq("some data")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "writes large amounts of data" do
|
17
|
+
File.open(Support.file_path("io"), "w+") do |io|
|
18
|
+
connection = Connection.new(nil, io)
|
19
|
+
big_data = Array.new(1024 * 16) { SecureRandom.hex(4) }.join
|
20
|
+
|
21
|
+
connection = Connection.new(nil, io)
|
22
|
+
connection.write(big_data)
|
23
|
+
|
24
|
+
expect(File.read(io.path)).to eq(big_data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#read" do
|
30
|
+
it "yields data from the underlying file descriptor" do
|
31
|
+
rd, wr = IO.pipe
|
32
|
+
wr.write("some data")
|
33
|
+
wr.close
|
34
|
+
|
35
|
+
connection = Connection.new(rd, nil)
|
36
|
+
|
37
|
+
expect do |y|
|
38
|
+
connection.read(&y)
|
39
|
+
end.to yield_with_args("some data")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#close" do
|
44
|
+
it "closes IO handles" do
|
45
|
+
rd, wr = ::IO.pipe
|
46
|
+
Connection.new(rd, wr).close
|
47
|
+
|
48
|
+
expect(rd).to be_closed
|
49
|
+
expect(wr).to be_closed
|
50
|
+
end
|
51
|
+
|
52
|
+
it "kills spawned processes" do
|
53
|
+
io = ::IO.popen("cat", "rb+")
|
54
|
+
pid = io.pid
|
55
|
+
expect(pid).to respond_to(:to_int)
|
56
|
+
|
57
|
+
Connection.new(io).close
|
58
|
+
expect { Process.kill(0, pid) }.to raise_error(Errno::ESRCH)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
class EventLoop
|
5
|
+
RSpec.describe MessageBuilder do
|
6
|
+
let(:message_builder) { MessageBuilder.new }
|
7
|
+
|
8
|
+
describe "#write" do
|
9
|
+
context "requests" do
|
10
|
+
it "yields a valid request message" do
|
11
|
+
expect do |y|
|
12
|
+
message_builder.write(:request, :method, [1, 2], Proc.new {}, &y)
|
13
|
+
end.to yield_with_args([0, 1, :method, [1, 2]])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "increments the request id" do
|
17
|
+
expect do |y|
|
18
|
+
message_builder.write(:request, :method, [], Proc.new {}, &y)
|
19
|
+
message_builder.write(:request, :method, [], Proc.new {}, &y)
|
20
|
+
end.to yield_successive_args(
|
21
|
+
[0, 1, :method, []],
|
22
|
+
[0, 2, :method, []]
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "responses" do
|
28
|
+
it "yields a valid response message" do
|
29
|
+
expect do |y|
|
30
|
+
message_builder.write(:response, 2, :value, "error msg", &y)
|
31
|
+
end.to yield_with_args([1, 2, "error msg", :value])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "notifications" do
|
36
|
+
it "yields a valid notification message" do
|
37
|
+
expect do |y|
|
38
|
+
message_builder.write(:notification, :method, [1, 2], &y)
|
39
|
+
end.to yield_with_args([2, :method, [1, 2]])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#read" do
|
45
|
+
context "requests" do
|
46
|
+
it "yields a request object" do
|
47
|
+
request = nil
|
48
|
+
message_builder.read([0, 1, :method, [1, 2]]) do |req|
|
49
|
+
request = req
|
50
|
+
end
|
51
|
+
|
52
|
+
expect(request.sync?).to eq(true)
|
53
|
+
expect(request.id).to eq(1)
|
54
|
+
expect(request.method_name).to eq(:method)
|
55
|
+
expect(request.arguments).to eq([1, 2])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "responses" do
|
60
|
+
it "calls the registered handler with a success response" do
|
61
|
+
response = nil
|
62
|
+
handler = Proc.new { |res| response = res }
|
63
|
+
|
64
|
+
message_builder.write(:request, :method, [1, 2], handler) {}
|
65
|
+
message_builder.read([1, 1, [nil, nil], :result])
|
66
|
+
|
67
|
+
expect(response.request_id).to eq(1)
|
68
|
+
expect(response.value).to eq(:result)
|
69
|
+
expect(response.value!).to eq(:result)
|
70
|
+
expect(response.error).to eq(nil)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "calls the registered handler with an error response" do
|
74
|
+
response = nil
|
75
|
+
|
76
|
+
handler = Proc.new do |res|
|
77
|
+
response = res
|
78
|
+
end
|
79
|
+
|
80
|
+
message_builder.write(:request, :method, [1, 2], handler) {}
|
81
|
+
message_builder.read([1, 1, [:some_err, "BOOM"], nil])
|
82
|
+
|
83
|
+
expect(response.request_id).to eq(1)
|
84
|
+
expect(response.error).to eq("BOOM")
|
85
|
+
expect(response.value).to eq(nil)
|
86
|
+
expect { response.value! }.to raise_error("BOOM")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "notifications" do
|
91
|
+
it "yields a notification object" do
|
92
|
+
notification = nil
|
93
|
+
message_builder.read([2, :method, [1, 2]]) do |ntf|
|
94
|
+
notification = ntf
|
95
|
+
end
|
96
|
+
|
97
|
+
expect(notification.sync?).to eq(false)
|
98
|
+
expect(notification.method_name).to eq(:method)
|
99
|
+
expect(notification.arguments).to eq([1, 2])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
class EventLoop
|
5
|
+
RSpec.describe Serializer do
|
6
|
+
let(:serializer) { Serializer.new }
|
7
|
+
|
8
|
+
describe "write" do
|
9
|
+
it "yields msgpack" do
|
10
|
+
expect do |y|
|
11
|
+
serializer.write([1, :foo], &y)
|
12
|
+
end.to yield_with_args(MessagePack.pack([1, :foo]))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "read" do
|
17
|
+
it "yields an unpacked object" do
|
18
|
+
expect do |y|
|
19
|
+
serializer.read(MessagePack.pack([1, :foo]), &y)
|
20
|
+
end.to yield_with_args([1, "foo"])
|
21
|
+
end
|
22
|
+
|
23
|
+
it "accumulates chunks of data and yields a single object" do
|
24
|
+
object = Array.new(16) { SecureRandom.hex(4) }
|
25
|
+
msgpack = MessagePack.pack(object)
|
26
|
+
|
27
|
+
expect do |y|
|
28
|
+
msgpack.chars.each_slice(10) do |chunk|
|
29
|
+
serializer.read(chunk.join, &y)
|
30
|
+
end
|
31
|
+
end.to yield_with_args(object)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#register_type" do
|
36
|
+
it "registers a msgpack ext type" do
|
37
|
+
ext_class = Struct.new(:id) do
|
38
|
+
def self.from_msgpack_ext(data)
|
39
|
+
new(data.unpack('N')[0])
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_msgpack_ext
|
43
|
+
[self.id].pack('C')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
serializer.register_type(42) do |id|
|
48
|
+
ext_class.new(id)
|
49
|
+
end
|
50
|
+
|
51
|
+
factory = MessagePack::Factory.new
|
52
|
+
factory.register_type(42, ext_class)
|
53
|
+
obj = ext_class.new(1)
|
54
|
+
msgpack = factory.packer.write(obj).flush.to_str
|
55
|
+
|
56
|
+
expect do |y|
|
57
|
+
serializer.read(msgpack, &y)
|
58
|
+
end.to yield_with_args(obj)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
module Neovim
|
4
|
+
RSpec.describe EventLoop do
|
5
|
+
let!(:push_pipe) { IO.pipe }
|
6
|
+
let!(:pull_pipe) { IO.pipe }
|
7
|
+
|
8
|
+
let(:client_rd) { push_pipe[0] }
|
9
|
+
let(:client_wr) { pull_pipe[1] }
|
10
|
+
let(:server_rd) { pull_pipe[0] }
|
11
|
+
let(:server_wr) { push_pipe[1] }
|
12
|
+
|
13
|
+
let(:connection) { EventLoop::Connection.new(client_rd, client_wr) }
|
14
|
+
let(:event_loop) { EventLoop.new(connection) }
|
15
|
+
|
16
|
+
describe "#run" do
|
17
|
+
it "reads requests" do
|
18
|
+
server_wr.write(MessagePack.pack([0, 1, :foo_method, []]))
|
19
|
+
server_wr.flush
|
20
|
+
|
21
|
+
request = nil
|
22
|
+
event_loop.run do |req|
|
23
|
+
request = req
|
24
|
+
event_loop.stop
|
25
|
+
end
|
26
|
+
expect(request.method_name).to eq("foo_method")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "writes requests" do
|
30
|
+
response = nil
|
31
|
+
|
32
|
+
event_loop.request(:foo_method) do |res|
|
33
|
+
response = res
|
34
|
+
event_loop.stop
|
35
|
+
end
|
36
|
+
|
37
|
+
server_wr.write(MessagePack.pack([1, 1, nil, :value]))
|
38
|
+
server_wr.flush
|
39
|
+
|
40
|
+
event_loop.run
|
41
|
+
expect(response.value!).to eq("value")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "writes responses" do
|
45
|
+
event_loop.respond(1, :foo_response, nil)
|
46
|
+
|
47
|
+
server_wr.write(MessagePack.pack([2, :noop, []]))
|
48
|
+
server_wr.flush
|
49
|
+
|
50
|
+
event_loop.run { event_loop.stop }
|
51
|
+
expect(server_rd.readpartial(1024)).to eq(
|
52
|
+
MessagePack.pack([1, 1, nil, :foo_response])
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "reads notifications" do
|
57
|
+
server_wr.write(MessagePack.pack([2, :foo_notification, []]))
|
58
|
+
server_wr.flush
|
59
|
+
|
60
|
+
notification = nil
|
61
|
+
event_loop.run do |ntf|
|
62
|
+
notification = ntf
|
63
|
+
event_loop.stop
|
64
|
+
end
|
65
|
+
expect(notification.method_name).to eq("foo_notification")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "writes notifications" do
|
69
|
+
event_loop.notify(:foo_notification)
|
70
|
+
|
71
|
+
server_wr.write(MessagePack.pack([2, :noop, []]))
|
72
|
+
server_wr.flush
|
73
|
+
|
74
|
+
event_loop.run { event_loop.stop }
|
75
|
+
expect(server_rd.readpartial(1024)).to eq(
|
76
|
+
MessagePack.pack([2, :foo_notification, []])
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/spec/neovim/host_spec.rb
CHANGED
@@ -3,175 +3,144 @@ require "neovim/host"
|
|
3
3
|
|
4
4
|
module Neovim
|
5
5
|
RSpec.describe Host do
|
6
|
-
let(:session) { instance_double(Session) }
|
7
|
-
let(:client) { instance_double(Client) }
|
8
|
-
let(:host) { Host.new(session, client) }
|
9
|
-
|
10
6
|
describe ".run" do
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
it "rescues session exceptions", :silence_warnings do
|
38
|
-
expect(session).to receive(:run).and_raise("BOOM")
|
39
|
-
expect { host.run }.not_to raise_error
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe "#handlers" do
|
44
|
-
it "has a default poll handler" do
|
45
|
-
expect(host.handlers["poll"]).to respond_to(:call)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe "#specs" do
|
50
|
-
it "has default specs" do
|
51
|
-
expect(host.specs).to eq({})
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe "#register" do
|
56
|
-
it "adds specs" do
|
57
|
-
plugin = Plugin.from_config_block("source") do |plug|
|
58
|
-
plug.command(:Foo)
|
7
|
+
let!(:push_pipe) { IO.pipe }
|
8
|
+
let!(:pull_pipe) { IO.pipe }
|
9
|
+
|
10
|
+
let(:host_rd) { push_pipe[0] }
|
11
|
+
let(:host_wr) { pull_pipe[1] }
|
12
|
+
let(:nvim_rd) { pull_pipe[0] }
|
13
|
+
let(:nvim_wr) { push_pipe[1] }
|
14
|
+
|
15
|
+
let(:plugin_path) do
|
16
|
+
Support.file_path("my_plugin").tap do |path|
|
17
|
+
File.write(path, <<-PLUGIN)
|
18
|
+
Neovim.plugin do |plug|
|
19
|
+
plug.command(:StrWidth, :nargs => 1, :sync => true) do |client, arg|
|
20
|
+
arg.bytesize
|
21
|
+
end
|
22
|
+
|
23
|
+
plug.command(:Boom, :sync => true) do |client|
|
24
|
+
raise "BOOM"
|
25
|
+
end
|
26
|
+
|
27
|
+
plug.command(:BoomAsync) do |client|
|
28
|
+
raise "BOOM ASYNC"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
PLUGIN
|
59
32
|
end
|
60
|
-
|
61
|
-
expect {
|
62
|
-
host.register(plugin)
|
63
|
-
}.to change { host.specs }.from({}).to("source" => plugin.specs)
|
64
33
|
end
|
65
34
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
35
|
+
let!(:host_thread) do
|
36
|
+
connection = EventLoop::Connection.new(host_rd, host_wr)
|
37
|
+
event_loop = EventLoop.new(connection)
|
70
38
|
|
71
|
-
|
72
|
-
|
73
|
-
}.to change {
|
74
|
-
host.handlers["source:command:Foo"]
|
75
|
-
}.from(nil).to(kind_of(Proc))
|
76
|
-
end
|
77
|
-
|
78
|
-
it "yields a client to the plugin setup blocks" do
|
79
|
-
yielded = []
|
80
|
-
|
81
|
-
plugin = Plugin.from_config_block("source") do |plug|
|
82
|
-
plug.__send__(:setup) do |client|
|
83
|
-
yielded << client
|
84
|
-
end
|
85
|
-
|
86
|
-
plug.__send__(:setup) do |_|
|
87
|
-
yielded << :other
|
88
|
-
end
|
39
|
+
Thread.new do
|
40
|
+
Host.run([plugin_path], event_loop)
|
89
41
|
end
|
90
|
-
|
91
|
-
expect {
|
92
|
-
host.register(plugin)
|
93
|
-
}.to change { yielded }.from([]).to([client, :other])
|
94
42
|
end
|
95
43
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
message =
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
44
|
+
before do
|
45
|
+
_, reqid, method = MessagePack.unpack(nvim_rd.readpartial(1024))
|
46
|
+
expect(method).to eq("nvim_get_api_info")
|
47
|
+
|
48
|
+
session = Session.new(EventLoop.child(Support.child_argv))
|
49
|
+
api_info = session.request(:nvim_get_api_info)
|
50
|
+
session.shutdown
|
51
|
+
|
52
|
+
nvim_wr.write(MessagePack.pack([1, reqid, nil, api_info]))
|
53
|
+
nvim_wr.flush
|
54
|
+
end
|
55
|
+
|
56
|
+
after do
|
57
|
+
host_thread.kill
|
58
|
+
host_thread.join
|
59
|
+
end
|
60
|
+
|
61
|
+
it "responds 'ok' to the 'poll' request" do
|
62
|
+
message = MessagePack.pack([0, 0, :poll, []])
|
63
|
+
nvim_wr.write(message)
|
64
|
+
nvim_wr.flush
|
65
|
+
|
66
|
+
response = MessagePack.unpack(nvim_rd.readpartial(1024))
|
67
|
+
expect(response).to eq([1, 0, nil, "ok"])
|
68
|
+
end
|
69
|
+
|
70
|
+
it "responds with specs to the 'specs' request" do
|
71
|
+
message = MessagePack.pack([0, 0, :specs, [plugin_path]])
|
72
|
+
nvim_wr.write(message)
|
73
|
+
nvim_wr.flush
|
74
|
+
|
75
|
+
response = MessagePack.unpack(nvim_rd.readpartial(1024))
|
76
|
+
expect(response).to eq(
|
77
|
+
[
|
78
|
+
1,
|
79
|
+
0,
|
80
|
+
nil,
|
81
|
+
[
|
82
|
+
{
|
83
|
+
"type" => "command",
|
84
|
+
"name" => "StrWidth",
|
85
|
+
"sync" => true,
|
86
|
+
"opts" => {"nargs" => 1},
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"type" => "command",
|
90
|
+
"name" => "Boom",
|
91
|
+
"sync" => true,
|
92
|
+
"opts" => {},
|
93
|
+
},
|
94
|
+
{
|
95
|
+
"type" => "command",
|
96
|
+
"name" => "BoomAsync",
|
97
|
+
"sync" => false,
|
98
|
+
"opts" => {},
|
99
|
+
},
|
100
|
+
],
|
101
|
+
],
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "delegates to plugin handlers" do
|
106
|
+
message = MessagePack.pack([0, 0, "#{plugin_path}:command:StrWidth", ["hi"]])
|
107
|
+
nvim_wr.write(message)
|
108
|
+
nvim_wr.flush
|
109
|
+
|
110
|
+
response = MessagePack.unpack(nvim_rd.readpartial(1024))
|
111
|
+
expect(response).to eq([1, 0, nil, 2])
|
112
|
+
end
|
113
|
+
|
114
|
+
it "handles exceptions in sync plugin handlers" do
|
115
|
+
message = MessagePack.pack([0, 0, "#{plugin_path}:command:Boom", ["hi"]])
|
116
|
+
nvim_wr.write(message)
|
117
|
+
nvim_wr.flush
|
118
|
+
|
119
|
+
response = MessagePack.unpack(nvim_rd.readpartial(1024))
|
120
|
+
expect(response).to eq([1, 0, "BOOM", nil])
|
121
|
+
end
|
122
|
+
|
123
|
+
it "handles exceptions in async plugin handlers" do
|
124
|
+
message = MessagePack.pack([2, "#{plugin_path}:command:BoomAsync", ["hi"]])
|
125
|
+
nvim_wr.write(message)
|
126
|
+
nvim_wr.flush
|
127
|
+
|
128
|
+
message = MessagePack.unpack(nvim_rd.readpartial(1024))
|
129
|
+
expect(message).to match_array(
|
130
|
+
[
|
131
|
+
0, duck_type(:to_int), "nvim_err_writeln",
|
132
|
+
[/my_plugin:command:BoomAsync: \(RuntimeError\) BOOM ASYNC/]
|
133
|
+
]
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "handles unknown requests" do
|
138
|
+
message = MessagePack.pack([0, 0, "foobar", []])
|
139
|
+
nvim_wr.write(message)
|
140
|
+
nvim_wr.flush
|
141
|
+
|
142
|
+
response = MessagePack.unpack(nvim_rd.readpartial(1024))
|
143
|
+
expect(response).to eq([1, 0, "Unknown request foobar", nil])
|
175
144
|
end
|
176
145
|
end
|
177
146
|
end
|