Skip to content

Commit eb4c013

Browse files
committed
Update tests (not working yet)
1 parent 4e047db commit eb4c013

File tree

1 file changed

+91
-17
lines changed

1 file changed

+91
-17
lines changed

test/ruby_lsp_rails/server_test.rb

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,52 @@
66

77
class ServerTest < ActiveSupport::TestCase
88
setup do
9-
@server = RubyLsp::Rails::Server.new
9+
@mutex = T.let(Mutex.new, Mutex)
10+
11+
stdin, stdout, stderr, wait_thread = Bundler.with_original_env do
12+
path = "#{__dir__}/../../lib/ruby_lsp/ruby_lsp_rails/server.rb"
13+
Open3.popen3(
14+
"bundle",
15+
"exec",
16+
"rails",
17+
"runner",
18+
path,
19+
"start",
20+
)
21+
end
22+
23+
@stdin = T.let(stdin, IO)
24+
@stdout = T.let(stdout, IO)
25+
@stderr = T.let(stderr, IO)
26+
@wait_thread = T.let(wait_thread, Process::Waiter)
27+
end
28+
29+
teardown do
30+
if @wait_thread.alive?
31+
$stderr.puts("Ruby LSP Rails is force killing the server")
32+
sleep(0.5) # give the server a bit of time if we already issued a shutdown notification
33+
force_kill
34+
end
1035
end
1136

1237
test "returns nil if model doesn't exist" do
13-
response = @server.execute("model", { name: "Foo" })
38+
response = make_request("model", { name: "Foo" })
39+
# binding.break
1440
assert_nil(response.fetch(:result))
1541
end
1642

1743
test "returns nil if class is not a model" do
18-
response = @server.execute("model", { name: "Time" })
44+
response = make_request("model", { name: "Time" })
1945
assert_nil(response.fetch(:result))
2046
end
2147

2248
test "returns nil if class is an abstract model" do
23-
response = @server.execute("model", { name: "ApplicationRecord" })
49+
response = make_request("model", { name: "ApplicationRecord" })
2450
assert_nil(response.fetch(:result))
2551
end
2652

2753
test "returns nil if constant is not a class" do
28-
response = @server.execute("model", { name: "RUBY_VERSION" })
54+
response = make_request("model", { name: "RUBY_VERSION" })
2955
assert_nil(response.fetch(:result))
3056
end
3157

@@ -38,21 +64,21 @@ def <(other)
3864
end
3965
end
4066

41-
response = @server.execute("model", { name: "TestClassWithOverwrittenLessThan" })
67+
response = make_request("model", { name: "TestClassWithOverwrittenLessThan" })
4268
assert_nil(response.fetch(:result))
4369
end
4470

4571
test "handles older Rails version which don't have `schema_dump_path`" do
4672
ActiveRecord::Tasks::DatabaseTasks.send(:alias_method, :old_schema_dump_path, :schema_dump_path)
4773
ActiveRecord::Tasks::DatabaseTasks.undef_method(:schema_dump_path)
48-
response = @server.execute("model", { name: "User" })
74+
response = make_request("model", { name: "User" })
4975
assert_nil(response.fetch(:result)[:schema_file])
5076
ensure
5177
ActiveRecord::Tasks::DatabaseTasks.send(:alias_method, :schema_dump_path, :old_schema_dump_path)
5278
end
5379

5480
test "resolve association returns the location of the target class of a has_many association" do
55-
response = @server.execute(
81+
response = make_request(
5682
"association_target_location",
5783
{ model_name: "Organization", association_name: :memberships },
5884
)
@@ -61,7 +87,7 @@ def <(other)
6187
end
6288

6389
test "resolve association returns the location of the target class of a belongs_to association" do
64-
response = @server.execute(
90+
response = make_request(
6591
"association_target_location",
6692
{ model_name: "Membership", association_name: :organization },
6793
)
@@ -70,7 +96,7 @@ def <(other)
7096
end
7197

7298
test "resolve association returns the location of the target class of a has_one association" do
73-
response = @server.execute(
99+
response = make_request(
74100
"association_target_location",
75101
{ model_name: "User", association_name: :profile },
76102
)
@@ -79,7 +105,7 @@ def <(other)
79105
end
80106

81107
test "resolve association returns the location of the target class of a has_and_belongs_to_many association" do
82-
response = @server.execute(
108+
response = make_request(
83109
"association_target_location",
84110
{ model_name: "Profile", association_name: :labels },
85111
)
@@ -88,23 +114,23 @@ def <(other)
88114
end
89115

90116
test "resolve association handles invalid model name" do
91-
response = @server.execute(
117+
response = make_request(
92118
"association_target_location",
93119
{ model_name: "NotHere", association_name: :labels },
94120
)
95121
assert_nil(response.fetch(:result))
96122
end
97123

98124
test "resolve association handles invalid association name" do
99-
response = @server.execute(
125+
response = make_request(
100126
"association_target_location",
101127
{ model_name: "Membership", association_name: :labels },
102128
)
103129
assert_nil(response.fetch(:result))
104130
end
105131

106132
test "resolve association handles class_name option" do
107-
response = @server.execute(
133+
response = make_request(
108134
"association_target_location",
109135
{ model_name: "User", association_name: :location },
110136
)
@@ -113,18 +139,18 @@ def <(other)
113139
end
114140

115141
test "route location returns the location for a valid route" do
116-
response = @server.execute("route_location", { name: "user_path" })
142+
response = make_request("route_location", { name: "user_path" })
117143
location = response[:result][:location]
118144
assert_match %r{test/dummy/config/routes.rb:4$}, location
119145
end
120146

121147
test "route location returns nil for invalid routes" do
122-
response = @server.execute("route_location", { name: "invalid_path" })
148+
response = make_request("route_location", { name: "invalid_path" })
123149
assert_nil response[:result]
124150
end
125151

126152
test "route info" do
127-
response = @server.execute("route_info", { controller: "UsersController", action: "index" })
153+
response = make_request("route_info", { controller: "UsersController", action: "index" })
128154

129155
result = response[:result]
130156

@@ -152,4 +178,52 @@ def resolve_route_info(requirements)
152178
assert_empty(stdout)
153179
assert_equal("Hello\n", stderr)
154180
end
181+
182+
private
183+
184+
def make_request(request, params = nil)
185+
send_message(request, params)
186+
read_response
187+
end
188+
189+
def send_message(request, params = nil)
190+
message = { method: request }
191+
message[:params] = params if params
192+
json = message.to_json
193+
194+
@mutex.synchronize do
195+
@stdin.write("Content-Length: #{json.length}\r\n\r\n", json)
196+
end
197+
# rescue Errno::EPIPE
198+
# The server connection died
199+
end
200+
201+
def read_response
202+
raw_response = @mutex.synchronize do
203+
headers = @stdout.gets("\r\n\r\n")
204+
raise "IncompleteMessageError" unless headers
205+
206+
content_length = headers[/Content-Length: (\d+)/i, 1].to_i
207+
raise "EmptyMessageError" if content_length.zero?
208+
209+
@stdout.read(content_length)
210+
end
211+
212+
response = JSON.parse(T.must(raw_response), symbolize_names: true)
213+
214+
if response[:error]
215+
$stderr.puts("Ruby LSP Rails error: " + response[:error])
216+
return
217+
end
218+
219+
response.fetch(:result)
220+
# rescue Errno::EPIPE
221+
# The server connection died
222+
# nil
223+
end
224+
225+
def force_kill
226+
# Windows does not support the `TERM` signal, so we're forced to use `KILL` here
227+
Process.kill(T.must(Signal.list["KILL"]), @wait_thread.pid)
228+
end
155229
end

0 commit comments

Comments
 (0)