Skip to content

Commit

Permalink
Go back to previous testing approach
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Oct 28, 2024
1 parent c8ab93b commit 1336ce7
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 25 deletions.
6 changes: 5 additions & 1 deletion exe/ruby-lsp-launcher
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ locked_bundler_version_file = File.join(".ruby-lsp", "locked_bundler_version")
# Compose the Ruby LSP bundle in a forked process so that we can require gems without polluting the main process
# `$LOAD_PATH` and `Gem.loaded_specs`. Windows doesn't support forking, so we need a separate path to support it
pid = if Gem.win_platform?
load_path = $LOAD_PATH.map do |path|
"-I#{path}"
end.join(" ")

Process.spawn(
Gem.ruby,
load_path,
File.expand_path("../lib/ruby_lsp/scripts/compose_bundle_windows.rb", __dir__),
raw_initialize,
)
else
fork do
Gem.activate_bin_path("ruby-lsp", "ruby-lsp")
require_relative "../lib/ruby_lsp/scripts/compose_bundle"
compose(raw_initialize)
end
Expand Down
1 change: 0 additions & 1 deletion lib/ruby_lsp/scripts/compose_bundle_windows.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# frozen_string_literal: true

$LOAD_PATH.unshift(File.expand_path("../../../lib", __dir__))
Gem.activate_bin_path("ruby-lsp", "ruby-lsp")
require_relative "compose_bundle"

# When this is invoked on Windows, we pass the raw initialize as an argument to this script. On other platforms, we
Expand Down
55 changes: 32 additions & 23 deletions test/integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ def test_avoids_bundler_version_if_local_bin_is_in_path
end

def test_launch_mode_with_no_gemfile
skip("CI only") unless ENV["CI"]

in_temp_dir do |dir|
Bundler.with_unbundled_env do
launch(dir)
Expand All @@ -92,6 +94,8 @@ def test_launch_mode_with_no_gemfile
end

def test_launch_mode_with_missing_lockfile
skip("CI only") unless ENV["CI"]

in_temp_dir do |dir|
File.write(File.join(dir, "Gemfile"), <<~RUBY)
source "https://rubygems.org"
Expand All @@ -105,6 +109,8 @@ def test_launch_mode_with_missing_lockfile
end

def test_launch_mode_with_full_bundle
skip("CI only") unless ENV["CI"]

in_temp_dir do |dir|
File.write(File.join(dir, "Gemfile"), <<~RUBY)
source "https://rubygems.org"
Expand Down Expand Up @@ -136,6 +142,8 @@ def test_launch_mode_with_full_bundle
end

def test_launch_mode_with_no_gemfile_and_bundle_path
skip("CI only") unless ENV["CI"]

in_temp_dir do |dir|
Bundler.with_unbundled_env do
system("bundle config --local path #{File.join("vendor", "bundle")}")
Expand All @@ -148,42 +156,43 @@ def test_launch_mode_with_no_gemfile_and_bundle_path
private

def launch(workspace_path)
stdin, stdout, stderr, wait_thr = Open3.popen3(Gem.ruby, File.join(@root, "exe", "ruby-lsp-launcher"))
stdin.sync = true
stdin.binmode
stdout.sync = true
stdout.binmode
stderr.sync = true
stderr.binmode

send_message(stdin, {
initialize_request = {
id: 1,
method: "initialize",
params: {
initializationOptions: {},
capabilities: { general: { positionEncodings: ["utf-8"] } },
workspaceFolders: [{ uri: URI::Generic.from_path(path: workspace_path).to_s }],
},
})
send_message(stdin, { id: 2, method: "shutdown" })
send_message(stdin, { method: "exit" })

# Wait until the process exits
wait_thr.join
}.to_json

$stdin.expects(:gets).with("\r\n\r\n").once.returns("Content-Length: #{initialize_request.bytesize}")
$stdin.expects(:read).with(initialize_request.bytesize).once.returns(initialize_request)

# Make `new` return a mock that raises so that we don't print to stdout and stop immediately after boot
server_object = mock("server")
server_object.expects(:start).once.raises(StandardError.new("stop"))
RubyLsp::Server.expects(:new).returns(server_object)

# We load the launcher binary in the same process as the tests are running. We cannot try to re-activate a different
# Bundler version, because that throws an error
if File.exist?(File.join(workspace_path, "Gemfile.lock"))
spec_mock = mock("specification")
spec_mock.expects(:activate).once
Gem::Specification.expects(:find_by_name).with do |name, version|
name == "bundler" && !version.empty?
end.returns(spec_mock)
end

# If the child process failed, it is really difficult to diagnose what's happening unless we read what was printed
# to stderr
unless T.unsafe(wait_thr.value).success?
require "timeout"
# Verify that we are setting up the bundle, but there's no actual need to do it
Bundler.expects(:setup).once

Timeout.timeout(5) do
flunk("Process failed\n#{stderr.read}")
end
assert_raises(StandardError) do
load(File.expand_path("../exe/ruby-lsp-launcher", __dir__))
end

assert_path_exists(File.join(workspace_path, ".ruby-lsp", "bundle_gemfile"))
assert_path_exists(File.join(workspace_path, ".ruby-lsp", "Gemfile"))
assert_path_exists(File.join(workspace_path, ".ruby-lsp", "Gemfile.lock"))
refute_path_exists(File.join(workspace_path, ".ruby-lsp", "install_error"))
end

Expand Down

0 comments on commit 1336ce7

Please sign in to comment.