|
3 | 3 |
|
4 | 4 | require "test_helper"
|
5 | 5 | require "ruby_lsp/ruby_lsp_rails/server"
|
| 6 | +require "timeout" |
6 | 7 |
|
7 | 8 | class ServerTest < ActiveSupport::TestCase
|
8 | 9 | setup do
|
9 | 10 | @stdout = StringIO.new
|
10 | 11 | @stderr = StringIO.new
|
| 12 | + RubyLsp::Rails::ServerAddon.instance_variable_set(:@server_addon_classes, []) |
| 13 | + RubyLsp::Rails::ServerAddon.instance_variable_set(:@server_addons, {}) |
11 | 14 | @server = RubyLsp::Rails::Server.new(stdout: @stdout, stderr: @stderr, override_default_output_device: false)
|
12 | 15 | end
|
13 | 16 |
|
@@ -268,10 +271,94 @@ def print_it!
|
268 | 271 | $> = original_stdout
|
269 | 272 | end
|
270 | 273 |
|
| 274 | + test "forked processes are named based on caller" do |
| 275 | + skip("Fork is not supported on Windows") if Gem.win_platform? |
| 276 | + |
| 277 | + addon_path = File.expand_path("my_addon.rb") |
| 278 | + File.write(addon_path, <<~RUBY) |
| 279 | + class MyServerAddon < RubyLsp::Rails::ServerAddon |
| 280 | + def name |
| 281 | + "MyAddon" |
| 282 | + end |
| 283 | +
|
| 284 | + def execute(request, params) |
| 285 | + parent_process_title = `ps -p \#{Process.pid} -o comm=`.lines.last.strip |
| 286 | + file = "process_name.txt" |
| 287 | + pid = fork do |
| 288 | + # We can't directly send a message in these tests because we're using a StringIO as stdout instead of the |
| 289 | + # actual pipe, which means that the child process doesn't have access to the same object |
| 290 | + process_title = `ps -p \#{Process.pid} -o comm=`.lines.last.strip |
| 291 | + File.write(file, process_title) |
| 292 | + end |
| 293 | +
|
| 294 | + Process.wait(pid) |
| 295 | +
|
| 296 | + parent_process_title_changed = `ps -p \#{Process.pid} -o comm=`.lines.last.strip != parent_process_title |
| 297 | + send_message({ process_name: File.read(file), changed_parent_title: parent_process_title_changed }) |
| 298 | + File.delete(file) |
| 299 | + rescue => e |
| 300 | + send_message({ error: e.full_message }) |
| 301 | + end |
| 302 | + end |
| 303 | + RUBY |
| 304 | + |
| 305 | + begin |
| 306 | + @server.execute("server_addon/register", server_addon_path: addon_path) |
| 307 | + @server.execute("server_addon/delegate", server_addon_name: "MyAddon", request_name: "dsl") |
| 308 | + assert_equal(response, { process_name: "ruby-lsp-rails: #{addon_path}", changed_parent_title: false }) |
| 309 | + ensure |
| 310 | + FileUtils.rm(addon_path) |
| 311 | + end |
| 312 | + end |
| 313 | + |
| 314 | + test "forked processes with no block are named based on caller" do |
| 315 | + skip("Fork is not supported on Windows") if Gem.win_platform? |
| 316 | + |
| 317 | + addon_path = File.expand_path("my_other_addon.rb") |
| 318 | + File.write(addon_path, <<~RUBY) |
| 319 | + class MyOtherServerAddon < RubyLsp::Rails::ServerAddon |
| 320 | + def name |
| 321 | + "MyOtherAddon" |
| 322 | + end |
| 323 | +
|
| 324 | + def execute(request, params) |
| 325 | + parent_process_title = `ps -p \#{Process.pid} -o comm=`.lines.last.strip |
| 326 | + file = "other_process_name.txt" |
| 327 | + pid = fork |
| 328 | +
|
| 329 | + if pid |
| 330 | + Process.wait(pid) |
| 331 | + parent_process_title_changed = `ps -p \#{Process.pid} -o comm=`.lines.last.strip != parent_process_title |
| 332 | + send_message({ process_name: File.read(file), changed_parent_title: parent_process_title_changed }) |
| 333 | + File.delete(file) |
| 334 | + else |
| 335 | + process_title = `ps -p \#{Process.pid} -o comm=`.lines.last.strip |
| 336 | + File.write(file, process_title) |
| 337 | +
|
| 338 | + # Exit from the child process or else we're stuck in the infinite loop of the server |
| 339 | + exit! |
| 340 | + end |
| 341 | + rescue => e |
| 342 | + send_message({ error: e.full_message }) |
| 343 | + end |
| 344 | + end |
| 345 | + RUBY |
| 346 | + |
| 347 | + begin |
| 348 | + @server.execute("server_addon/register", server_addon_path: addon_path) |
| 349 | + @server.execute("server_addon/delegate", server_addon_name: "MyOtherAddon", request_name: "dsl") |
| 350 | + assert_equal(response, { process_name: "ruby-lsp-rails: #{addon_path}", changed_parent_title: false }) |
| 351 | + ensure |
| 352 | + FileUtils.rm(addon_path) |
| 353 | + end |
| 354 | + end |
| 355 | + |
271 | 356 | private
|
272 | 357 |
|
273 | 358 | def response
|
274 |
| - _headers, content = @stdout.string.split("\r\n\r\n") |
275 |
| - JSON.parse(content, symbolize_names: true) |
| 359 | + Timeout.timeout(2) do |
| 360 | + _headers, content = @stdout.string.split("\r\n\r\n") |
| 361 | + JSON.parse(content, symbolize_names: true) |
| 362 | + end |
276 | 363 | end
|
277 | 364 | end
|
0 commit comments