Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lib/ruby_lsp/ruby_lsp_rails/addon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ def rails_runner_client
@addon_mutex.synchronize { @rails_runner_client }
end

# Blocks until the add-on finished booting the Rails runner client, successfully or not. After this method
# returns, `rails_runner_client` is in its final state: a working client or a NullClient if booting failed
#: -> void
def join_boot_thread
@boot_thread.join
end

# @override
#: (GlobalState global_state, Thread::Queue outgoing_queue) -> void
def activate(global_state, outgoing_queue)
Expand All @@ -77,7 +84,7 @@ def activate(global_state, outgoing_queue)
# @override
#: -> void
def deactivate
@boot_thread.join
join_boot_thread
@rails_runner_client.shutdown
end

Expand Down
7 changes: 5 additions & 2 deletions lib/ruby_lsp/ruby_lsp_rails/runner_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ class RunnerClient
class << self
#: (Thread::Queue outgoing_queue, RubyLsp::GlobalState global_state) -> RunnerClient
def create_client(outgoing_queue, global_state)
if File.exist?("bin/rails")
workspace_path = global_state.workspace_path

if File.exist?(File.join(workspace_path, "bin", "rails"))
Comment thread
soutaro marked this conversation as resolved.
new(outgoing_queue, global_state)
else
unless outgoing_queue.closed?
outgoing_queue << RubyLsp::Notification.window_log_message(
<<~MESSAGE.chomp,
Ruby LSP Rails failed to locate bin/rails in the current directory: #{Dir.pwd}
Ruby LSP Rails failed to locate bin/rails in the workspace: #{workspace_path}
Server dependent features will not be available
MESSAGE
type: RubyLsp::Constant::MessageType::WARNING,
Expand Down Expand Up @@ -64,6 +66,7 @@ def initialize(outgoing_queue, global_state)
"#{__dir__}/server.rb",
"start",
server_relevant_capabilities(global_state),
{ chdir: global_state.workspace_path },
)
end

Expand Down
2 changes: 1 addition & 1 deletion test/ruby_lsp_rails/code_lens_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def index

def generate_code_lens_for_source(source, file: "/fake.rb")
with_server(source, URI(file)) do |server, uri|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message(
id: 1,
Expand Down
2 changes: 1 addition & 1 deletion test/ruby_lsp_rails/completion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class CompletionTest < ActiveSupport::TestCase

def generate_completions_for_source(source, position)
with_server(source) do |server, uri|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message(
id: 1,
Expand Down
2 changes: 1 addition & 1 deletion test/ruby_lsp_rails/definition_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ class Bar::UsersController

def generate_definitions_for_source(source, position)
with_server(source) do |server, uri|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message(
id: 1,
Expand Down
12 changes: 6 additions & 6 deletions test/ruby_lsp_rails/rails_test_style_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class SpecialCharsTest < ActiveSupport::TestCase
Dir.stubs(:glob).returns(test_paths)

with_server do |server|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message({
id: 1,
Expand Down Expand Up @@ -181,7 +181,7 @@ class SpecialCharsTest < ActiveSupport::TestCase

test "resolve test command group test" do
with_server do |server|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message({
id: 1,
Expand Down Expand Up @@ -230,7 +230,7 @@ class SpecialCharsTest < ActiveSupport::TestCase

test "resolve test escapes file paths in groups" do
with_server do |server|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message({
id: 1,
Expand Down Expand Up @@ -264,7 +264,7 @@ class SpecialCharsTest < ActiveSupport::TestCase

test "resolve test escapes single file paths" do
with_server do |server|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message({
id: 1,
Expand Down Expand Up @@ -298,7 +298,7 @@ class SpecialCharsTest < ActiveSupport::TestCase
Dir.stubs(:glob).returns([test_path])

with_server do |server|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message({
id: 1,
Expand Down Expand Up @@ -328,7 +328,7 @@ class SpecialCharsTest < ActiveSupport::TestCase

test "resolve test escapes file paths for specific examples" do
with_server do |server|
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
wait_for_rails_runner_client_boot

server.process_message({
id: 1,
Expand Down
21 changes: 20 additions & 1 deletion test/ruby_lsp_rails/runner_client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# frozen_string_literal: true

require "test_helper"
require "tmpdir"
require "ruby_lsp/ruby_lsp_rails/runner_client"

module RubyLsp
Expand Down Expand Up @@ -101,13 +102,31 @@ class RunnerClientTest < ActiveSupport::TestCase
log = pop_log_notification(outgoing_queue, RubyLsp::Constant::MessageType::WARNING)

assert_instance_of(RubyLsp::Notification, log)
assert_match("Ruby LSP Rails failed to locate bin/rails in the current directory", log.params.message)
assert_match("Ruby LSP Rails failed to locate bin/rails in the workspace", log.params.message)
ensure
outgoing_queue.close
FileUtils.mv("bin/rails_backup", "bin/rails")
end
end

test "creates a client when the current working directory is not the workspace" do
outgoing_queue = Thread::Queue.new

client = Dir.mktmpdir do |dir|
Dir.chdir(dir) { RunnerClient.create_client(outgoing_queue, @global_state) }
end

begin
refute_instance_of(NullClient, client)

response = client.model("User") #: as !nil
assert(response.key?(:columns))
ensure
client.shutdown
outgoing_queue.close
end
end

test "failing to spawn server creates a null client" do
FileUtils.mv("test/dummy/config/application.rb", "test/dummy/config/application.rb.bak")

Expand Down
10 changes: 10 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,15 @@ class TestCase
def dummy_root
File.expand_path("#{__dir__}/dummy")
end

# Waits until the Rails add-on finished booting the runner client and fails the test immediately if it fell back
# to a NullClient, instead of hanging forever waiting for a real client that will never arrive
def wait_for_rails_runner_client_boot
addon = RubyLsp::Addon.addons.first #: as RubyLsp::Rails::Addon
addon.join_boot_thread

client = addon.rails_runner_client
refute_instance_of(RubyLsp::Rails::NullClient, client, "Expected the Rails runner client to boot successfully")
end
end
end
Loading