From e50b9abb4b857a088ab5b3e4a1cf3e0a170d7656 Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Wed, 23 Oct 2024 15:01:29 -0400 Subject: [PATCH] Add launch mode integration tests --- lib/ruby_lsp/global_state.rb | 4 +- lib/ruby_lsp/server.rb | 2 +- project-words | 4 ++ test/integration_test.rb | 103 ++++++++++++++++++++++++++++++++++- 4 files changed, 108 insertions(+), 5 deletions(-) diff --git a/lib/ruby_lsp/global_state.rb b/lib/ruby_lsp/global_state.rb index 2478dbe80..9f2a32217 100644 --- a/lib/ruby_lsp/global_state.rb +++ b/lib/ruby_lsp/global_state.rb @@ -231,7 +231,9 @@ def dot_rubocop_yml_present sig { returns(T::Array[String]) } def gather_direct_dependencies Bundler.with_original_env { Bundler.default_gemfile } - Bundler.locked_gems.dependencies.keys + gemspec_dependencies + + dependencies = Bundler.locked_gems&.dependencies&.keys || [] + dependencies + gemspec_dependencies rescue Bundler::GemfileNotFound [] end diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 5ff0d53a0..9fe2172ff 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1043,7 +1043,7 @@ def workspace_dependencies(message) } end end - rescue Bundler::GemfileNotFound + rescue Bundler::GemfileNotFound, Bundler::GitError [] end diff --git a/project-words b/project-words index 52fa38f32..4fba1773b 100644 --- a/project-words +++ b/project-words @@ -4,10 +4,12 @@ autoloaded autorun bigdecimal bindir +binmode binread Bizt Bizw bufnr +bytesize byteslice codepoint codepoints @@ -18,6 +20,7 @@ dont eglot Eglot eruby +exitstatus EXTGLOB FIXEDENCODING Floo @@ -46,6 +49,7 @@ nargs nodoc noreturn nvim +popen qtlzwssomeking quickfixes quxx diff --git a/test/integration_test.rb b/test/integration_test.rb index 4ae7ae003..dbb7985dc 100644 --- a/test/integration_test.rb +++ b/test/integration_test.rb @@ -2,13 +2,12 @@ # frozen_string_literal: true require "test_helper" +require "open3" class IntegrationTest < Minitest::Test - def setup + def test_ruby_lsp_doctor_works skip("CI only") unless ENV["CI"] - end - def test_ruby_lsp_doctor_works in_isolation do system("bundle exec ruby-lsp --doctor") assert_equal(0, $CHILD_STATUS) @@ -16,14 +15,112 @@ def test_ruby_lsp_doctor_works end def test_ruby_lsp_check_works + skip("CI only") unless ENV["CI"] + in_isolation do system("bundle exec ruby-lsp-check") assert_equal(0, $CHILD_STATUS) end end + def test_launch_mode_with_no_gemfile + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + Bundler.with_unbundled_env do + launch_and_shutdown(dir) + end + end + end + end + + def test_launch_mode_with_missing_lockfile + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + File.write(File.join(dir, "Gemfile"), <<~RUBY) + source "https://rubygems.org" + gem "stringio" + RUBY + + Bundler.with_unbundled_env do + launch_and_shutdown(dir) + end + end + end + end + + def test_launch_mode_with_full_bundle + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + File.write(File.join(dir, "Gemfile"), <<~RUBY) + source "https://rubygems.org" + gem "stringio" + RUBY + + lockfile_contents = <<~LOCKFILE + GEM + remote: https://rubygems.org/ + specs: + stringio (3.1.0) + + PLATFORMS + arm64-darwin-23 + ruby + + DEPENDENCIES + stringio + + BUNDLED WITH + 2.5.7 + LOCKFILE + File.write(File.join(dir, "Gemfile.lock"), lockfile_contents) + + Bundler.with_unbundled_env do + launch_and_shutdown(dir) + end + end + end + end + private + def launch_and_shutdown(workspace_path) + stdin, stdout, stderr, wait_thr = Open3.popen3("#{Bundler.root}/exe/ruby-lsp --use-launcher") + stdin.binmode + stdin.sync = true + stdout.binmode + stdout.sync = true + stderr.binmode + stderr.sync = true + + initialize_request = { + id: 1, + method: "initialize", + params: { + initializationOptions: {}, + capabilities: { general: { positionEncodings: ["utf-8"] } }, + workspaceFolders: [{ uri: URI::Generic.from_path(path: workspace_path).to_s }], + }, + }.to_json + stdin.write("Content-Length: #{initialize_request.bytesize}\r\n\r\n#{initialize_request}") + + shutdown_request = { + id: 2, + method: "shutdown", + }.to_json + stdin.write("Content-Length: #{shutdown_request.bytesize}\r\n\r\n#{shutdown_request}") + + exit_notification = { + method: "exit", + }.to_json + stdin.write("Content-Length: #{exit_notification.bytesize}\r\n\r\n#{exit_notification}") + + assert_equal(0, T.unsafe(wait_thr.value).exitstatus, "server crashed: #{stderr.read}") + + stdin.close + stdout.close + stderr.close + end + def in_isolation(&block) gem_path = Bundler.root Dir.mktmpdir do |dir|