@@ -8,6 +8,8 @@ class ServerTest < ActiveSupport::TestCase
88 setup do
99 @stdout = StringIO . new
1010 @stderr = StringIO . new
11+ RubyLsp ::Rails ::ServerAddon . instance_variable_set ( :@server_addon_classes , [ ] )
12+ RubyLsp ::Rails ::ServerAddon . instance_variable_set ( :@server_addons , { } )
1113 @server = RubyLsp ::Rails ::Server . new ( stdout : @stdout , stderr : @stderr , override_default_output_device : false )
1214 end
1315
@@ -268,6 +270,84 @@ def print_it!
268270 $> = original_stdout
269271 end
270272
273+ test "forked processes are named based on caller" do
274+ skip ( "Fork is not supported on Windows" ) if Gem . win_platform?
275+
276+ addon_path = File . expand_path ( "my_addon.rb" )
277+ File . write ( addon_path , <<~RUBY )
278+ class MyServerAddon < RubyLsp::Rails::ServerAddon
279+ def name
280+ "MyAddon"
281+ end
282+
283+ def execute(request, params)
284+ parent_process_title = `ps -p \# {Process.pid} -o comm=`.lines.last.strip
285+ file = "process_name.txt"
286+ pid = fork do
287+ # We can't directly send a message in these tests because we're using a StringIO as stdout instead of the
288+ # actual pipe, which means that the child process doesn't have access to the same object
289+ process_title = `ps -p \# {Process.pid} -o comm=`.lines.last.strip
290+ File.write(file, process_title)
291+ end
292+
293+ Process.wait(pid)
294+
295+ parent_process_title_changed = `ps -p \# {Process.pid} -o comm=`.lines.last.strip != parent_process_title
296+ send_message({ process_name: File.read(file), changed_parent_title: parent_process_title_changed })
297+ File.delete(file)
298+ end
299+ end
300+ RUBY
301+
302+ begin
303+ @server . execute ( "server_addon/register" , server_addon_path : addon_path )
304+ @server . execute ( "server_addon/delegate" , server_addon_name : "MyAddon" , request_name : "dsl" )
305+ assert_equal ( response , { process_name : "ruby-lsp-rails: #{ addon_path } " , changed_parent_title : false } )
306+ ensure
307+ FileUtils . rm ( addon_path )
308+ end
309+ end
310+
311+ test "forked processes with no block are named based on caller" do
312+ skip ( "Fork is not supported on Windows" ) if Gem . win_platform?
313+
314+ addon_path = File . expand_path ( "my_other_addon.rb" )
315+ File . write ( addon_path , <<~RUBY )
316+ class MyOtherServerAddon < RubyLsp::Rails::ServerAddon
317+ def name
318+ "MyOtherAddon"
319+ end
320+
321+ def execute(request, params)
322+ parent_process_title = `ps -p \# {Process.pid} -o comm=`.lines.last.strip
323+ file = "other_process_name.txt"
324+ pid = fork
325+
326+ if pid
327+ Process.wait(pid)
328+ parent_process_title_changed = `ps -p \# {Process.pid} -o comm=`.lines.last.strip != parent_process_title
329+ send_message({ process_name: File.read(file), changed_parent_title: parent_process_title_changed })
330+ File.delete(file)
331+ else
332+ process_title = `ps -p \# {Process.pid} -o comm=`.lines.last.strip
333+ File.write(file, process_title)
334+
335+ # Exit from the child process or else we're stuck in the infinite loop of the server
336+ exit!
337+ end
338+ end
339+ end
340+ RUBY
341+
342+ begin
343+ @server . execute ( "server_addon/register" , server_addon_path : addon_path )
344+ @server . execute ( "server_addon/delegate" , server_addon_name : "MyOtherAddon" , request_name : "dsl" )
345+ assert_equal ( response , { process_name : "ruby-lsp-rails: #{ addon_path } " , changed_parent_title : false } )
346+ ensure
347+ FileUtils . rm ( addon_path )
348+ end
349+ end
350+
271351 private
272352
273353 def response
0 commit comments