From cbc1e253bd51fc8465a166f67c806fbe1521730f Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Tue, 5 Nov 2024 18:23:38 -0500 Subject: [PATCH 1/4] Use Minitest instead of ActiveSupport for testing --- Gemfile | 1 + Gemfile.lock | 2 + Rakefile | 10 +++- gemfiles/Gemfile-rails-main | 1 + test/ruby_lsp_rails/addon_test.rb | 2 +- test/ruby_lsp_rails/code_lens_test.rb | 4 +- test/ruby_lsp_rails/definition_test.rb | 2 +- test/ruby_lsp_rails/document_symbol_test.rb | 2 +- test/ruby_lsp_rails/hover_test.rb | 2 +- .../indexing_enhancement_test.rb | 2 +- test/ruby_lsp_rails/launch_test.rb | 2 +- test/ruby_lsp_rails/runner_client_test.rb | 12 +++-- test/ruby_lsp_rails/server_test.rb | 6 +-- .../support/location_builder_test.rb | 2 +- test/ruby_lsp_rails_test.rb | 2 +- test/test_helper.rb | 46 ++++++++++++++----- test/test_helper_server.rb | 11 +++++ 17 files changed, 78 insertions(+), 31 deletions(-) create mode 100644 test/test_helper_server.rb diff --git a/Gemfile b/Gemfile index cd3451b9..81d6374f 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,7 @@ gem "sorbet-static-and-runtime", platforms: :ruby gem "tapioca", "~> 0.13", require: false, platforms: :ruby gem "psych", "~> 5.1", require: false gem "rails", "8.0.0.beta1" +gem "test_declarative" platforms :mingw, :x64_mingw, :mswin, :jruby do gem "tzinfo" diff --git a/Gemfile.lock b/Gemfile.lock index 65b2d258..d73cba7f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -250,6 +250,7 @@ GEM spoom (>= 1.2.0) thor (>= 1.2.0) yard-sorbet + test_declarative (0.0.6) thor (1.3.2) timeout (0.4.1) tzinfo (2.0.6) @@ -289,6 +290,7 @@ DEPENDENCIES sorbet-static-and-runtime sqlite3 tapioca (~> 0.13) + test_declarative tzinfo tzinfo-data diff --git a/Rakefile b/Rakefile index e766e653..0e187347 100644 --- a/Rakefile +++ b/Rakefile @@ -13,7 +13,13 @@ require "rake/testtask" Rake::TestTask.new(:test) do |t| t.libs << "test" t.libs << "lib" - t.test_files = FileList["test/**/*_test.rb"] + t.test_files = FileList["test/**/*_test.rb"] - ["test/ruby_lsp_rails/server_test.rb"] end -task default: [:"db:setup", :test] +Rake::TestTask.new("test:server") do |t| + t.libs << "test" + t.libs << "lib" + t.test_files = ["test/ruby_lsp_rails/server_test.rb"] +end + +task default: [:"db:setup", :test, "test:server"] diff --git a/gemfiles/Gemfile-rails-main b/gemfiles/Gemfile-rails-main index 2a144069..c40fab82 100644 --- a/gemfiles/Gemfile-rails-main +++ b/gemfiles/Gemfile-rails-main @@ -19,6 +19,7 @@ gem "sorbet-static-and-runtime", platforms: :ruby gem "tapioca", "~> 0.11", require: false, platforms: :ruby gem "psych", "~> 5.1", require: false gem "rails", github: "rails/rails", branch: "main" +gem "test_declarative" platforms :mingw, :x64_mingw, :mswin, :jruby do gem "tzinfo" diff --git a/test/ruby_lsp_rails/addon_test.rb b/test/ruby_lsp_rails/addon_test.rb index 63213552..2ba1bf74 100644 --- a/test/ruby_lsp_rails/addon_test.rb +++ b/test/ruby_lsp_rails/addon_test.rb @@ -5,7 +5,7 @@ module RubyLsp module Rails - class AddonTest < ActiveSupport::TestCase + class AddonTest < Minitest::Test test "name returns add-on name" do addon = Addon.new assert_equal("Ruby LSP Rails", addon.name) diff --git a/test/ruby_lsp_rails/code_lens_test.rb b/test/ruby_lsp_rails/code_lens_test.rb index 30a769d2..2a1ede75 100644 --- a/test/ruby_lsp_rails/code_lens_test.rb +++ b/test/ruby_lsp_rails/code_lens_test.rb @@ -5,8 +5,8 @@ module RubyLsp module Rails - class CodeLensTest < ActiveSupport::TestCase - setup do + class CodeLensTest < Minitest::Test + def setup GlobalState.any_instance.stubs(:test_library).returns("rails") @ruby = Gem.win_platform? ? "ruby.exe" : "ruby" end diff --git a/test/ruby_lsp_rails/definition_test.rb b/test/ruby_lsp_rails/definition_test.rb index 581cb10a..26da6d7f 100644 --- a/test/ruby_lsp_rails/definition_test.rb +++ b/test/ruby_lsp_rails/definition_test.rb @@ -5,7 +5,7 @@ module RubyLsp module Rails - class DefinitionTest < ActiveSupport::TestCase + class DefinitionTest < Minitest::Test test "recognizes model callback with multiple symbol arguments" do response = generate_definitions_for_source(<<~RUBY, { line: 3, character: 18 }) # typed: false diff --git a/test/ruby_lsp_rails/document_symbol_test.rb b/test/ruby_lsp_rails/document_symbol_test.rb index 9896519f..2172878b 100644 --- a/test/ruby_lsp_rails/document_symbol_test.rb +++ b/test/ruby_lsp_rails/document_symbol_test.rb @@ -5,7 +5,7 @@ module RubyLsp module Rails - class DocumentSymbolTest < ActiveSupport::TestCase + class DocumentSymbolTest < Minitest::Test test "recognizes Rails Active Support test cases" do response = generate_document_symbols_for_source(<<~RUBY) class Test < ActiveSupport::TestCase diff --git a/test/ruby_lsp_rails/hover_test.rb b/test/ruby_lsp_rails/hover_test.rb index 90861fec..97d06181 100644 --- a/test/ruby_lsp_rails/hover_test.rb +++ b/test/ruby_lsp_rails/hover_test.rb @@ -5,7 +5,7 @@ module RubyLsp module Rails - class HoverTest < ActiveSupport::TestCase + class HoverTest < Minitest::Test test "hook returns model column information" do expected_response = { schema_file: "#{dummy_root}/db/schema.rb", diff --git a/test/ruby_lsp_rails/indexing_enhancement_test.rb b/test/ruby_lsp_rails/indexing_enhancement_test.rb index b6c7b66b..76210054 100644 --- a/test/ruby_lsp_rails/indexing_enhancement_test.rb +++ b/test/ruby_lsp_rails/indexing_enhancement_test.rb @@ -5,7 +5,7 @@ module RubyLsp module Rails - class IndexingEnhancementTest < ActiveSupport::TestCase + class IndexingEnhancementTest < Minitest::Test class << self # For these tests, it's convenient to have the index fully populated with Rails information, but we don't have # to reindex on every single example or that will be too slow diff --git a/test/ruby_lsp_rails/launch_test.rb b/test/ruby_lsp_rails/launch_test.rb index 32b833ce..2b745b67 100644 --- a/test/ruby_lsp_rails/launch_test.rb +++ b/test/ruby_lsp_rails/launch_test.rb @@ -5,7 +5,7 @@ module RubyLsp module Rails - class LaunchTest < ActiveSupport::TestCase + class LaunchTest < Minitest::Test test "launching the client succeeds" do outgoing_queue = Thread::Queue.new diff --git a/test/ruby_lsp_rails/runner_client_test.rb b/test/ruby_lsp_rails/runner_client_test.rb index 20720593..5b69c8a3 100644 --- a/test/ruby_lsp_rails/runner_client_test.rb +++ b/test/ruby_lsp_rails/runner_client_test.rb @@ -6,13 +6,13 @@ module RubyLsp module Rails - class RunnerClientTest < ActiveSupport::TestCase - setup do + class RunnerClientTest < Minitest::Test + def setup @outgoing_queue = Thread::Queue.new @client = T.let(RunnerClient.new(@outgoing_queue), RunnerClient) end - teardown do + def teardown @client.shutdown # On Windows, the server process sometimes takes a lot longer to shutdown and may end up getting force killed, @@ -156,8 +156,10 @@ def execute(request, params) end end - class NullClientTest < ActiveSupport::TestCase - setup { @client = NullClient.new } + class NullClientTest < Minitest::Test + def setup + @client = NullClient.new + end test "#shutdown is a no-op" do assert_nothing_raised { @client.shutdown } diff --git a/test/ruby_lsp_rails/server_test.rb b/test/ruby_lsp_rails/server_test.rb index 55fbc7ab..691bcc1c 100644 --- a/test/ruby_lsp_rails/server_test.rb +++ b/test/ruby_lsp_rails/server_test.rb @@ -1,11 +1,11 @@ # typed: true # frozen_string_literal: true -require "test_helper" +require "test_helper_server" require "ruby_lsp/ruby_lsp_rails/server" -class ServerTest < ActiveSupport::TestCase - setup do +class ServerTest < ActiveSupport::TestCase # Minitest::Test + def setup @stdout = StringIO.new @server = RubyLsp::Rails::Server.new(stdout: @stdout, override_default_output_device: false) end diff --git a/test/ruby_lsp_rails/support/location_builder_test.rb b/test/ruby_lsp_rails/support/location_builder_test.rb index 4e3f3e25..838dc88a 100644 --- a/test/ruby_lsp_rails/support/location_builder_test.rb +++ b/test/ruby_lsp_rails/support/location_builder_test.rb @@ -6,7 +6,7 @@ module RubyLsp module Rails module Support - class LocationBuilderTest < ActiveSupport::TestCase + class LocationBuilderTest < Minitest::Test test "line_location_from_s raises argument error if invalid string given" do assert_raises(ArgumentError) { LocationBuilder.line_location_from_s("banana") } end diff --git a/test/ruby_lsp_rails_test.rb b/test/ruby_lsp_rails_test.rb index a056a71e..b6960c0c 100644 --- a/test/ruby_lsp_rails_test.rb +++ b/test/ruby_lsp_rails_test.rb @@ -4,7 +4,7 @@ require "test_helper" module RubyLsp - class RailsTest < ActiveSupport::TestCase + class RailsTest < Minitest::Test test "it has a version number" do assert RubyLsp::Rails::VERSION end diff --git a/test/test_helper.rb b/test/test_helper.rb index ca2195c5..ae981502 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,16 +1,10 @@ # typed: true # frozen_string_literal: true -# Configure Rails Environment -ENV["RAILS_ENV"] = "test" - -require_relative "../test/dummy/config/environment" -ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)] -ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__) -require "sorbet-runtime" -require "rails/test_help" -require "mocha/minitest" require "ruby_lsp/internal" +require "minitest/autorun" +require "test_declarative" +require "mocha/minitest" require "ruby_lsp/test_helper" require "ruby_lsp/ruby_lsp_rails/addon" @@ -26,8 +20,8 @@ # Tapioca (and thus Spoom) is not available on Windows end -module ActiveSupport - class TestCase +module Minitest + class Test extend T::Sig include RubyLsp::TestHelper @@ -63,5 +57,35 @@ def pop_message(outgoing_queue, &block) message = outgoing_queue.pop until block.call(message) message end + + # Copied from Rails + def assert_nothing_raised(*args) + msg = if Module === args.last + nil + else + args.pop + end + begin + line = __LINE__ + yield + rescue MiniTest::Skip + raise + rescue Exception => e # rubocop:disable Lint/RescueException + bt = e.backtrace + as = e.instance_of?(MiniTest::Assertion) + if as + ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in / + bt.reject! { |ln| ans =~ ln } + end + if (args.empty? && !as) || + args.any? { |a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a } + msg = message(msg) { "Exception raised:\n<#{mu_pp(e)}>" } + raise MiniTest::Assertion, msg.call, bt + else + raise + end + end + nil + end end end diff --git a/test/test_helper_server.rb b/test/test_helper_server.rb new file mode 100644 index 00000000..fd7129cb --- /dev/null +++ b/test/test_helper_server.rb @@ -0,0 +1,11 @@ +# typed: true +# frozen_string_literal: true + +# Configure Rails Environment +ENV["RAILS_ENV"] = "test" + +require "test_helper" + +require_relative "../test/dummy/config/environment" +ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)] +ActiveRecord::Migrator.migrations_paths << File.expand_path("../db/migrate", __dir__) From 21258a92ea146e94d862461ca1de0d9bb8f19a7d Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:30:37 -0500 Subject: [PATCH 2/4] Use assert_nothing_raised from Rails --- test/test_helper.rb | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index ae981502..9590856f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -7,6 +7,7 @@ require "mocha/minitest" require "ruby_lsp/test_helper" require "ruby_lsp/ruby_lsp_rails/addon" +require "active_support/testing/assertions" # for assert_nothing_raised if defined?(DEBUGGER__) DEBUGGER__::CONFIG[:skip_path] = @@ -24,6 +25,7 @@ module Minitest class Test extend T::Sig include RubyLsp::TestHelper + include ActiveSupport::Testing::Assertions # for assert_nothing_raised def dummy_root File.expand_path("#{__dir__}/dummy") @@ -57,35 +59,5 @@ def pop_message(outgoing_queue, &block) message = outgoing_queue.pop until block.call(message) message end - - # Copied from Rails - def assert_nothing_raised(*args) - msg = if Module === args.last - nil - else - args.pop - end - begin - line = __LINE__ - yield - rescue MiniTest::Skip - raise - rescue Exception => e # rubocop:disable Lint/RescueException - bt = e.backtrace - as = e.instance_of?(MiniTest::Assertion) - if as - ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in / - bt.reject! { |ln| ans =~ ln } - end - if (args.empty? && !as) || - args.any? { |a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a } - msg = message(msg) { "Exception raised:\n<#{mu_pp(e)}>" } - raise MiniTest::Assertion, msg.call, bt - else - raise - end - end - nil - end end end From 444212e75ce014ed1e031781d846e41641ca68df Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:33:36 -0500 Subject: [PATCH 3/4] Remove commented code --- test/ruby_lsp_rails/server_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ruby_lsp_rails/server_test.rb b/test/ruby_lsp_rails/server_test.rb index 691bcc1c..e29461ea 100644 --- a/test/ruby_lsp_rails/server_test.rb +++ b/test/ruby_lsp_rails/server_test.rb @@ -4,7 +4,7 @@ require "test_helper_server" require "ruby_lsp/ruby_lsp_rails/server" -class ServerTest < ActiveSupport::TestCase # Minitest::Test +class ServerTest < ActiveSupport::TestCase def setup @stdout = StringIO.new @server = RubyLsp::Rails::Server.new(stdout: @stdout, override_default_output_device: false) From e94c87e3eecdac34fe21a62b48f9197e1fae8a55 Mon Sep 17 00:00:00 2001 From: Andy Waite <13400+andyw8@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:39:27 -0500 Subject: [PATCH 4/4] Fix type-checking --- test/ruby_lsp_rails/runner_client_test.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/ruby_lsp_rails/runner_client_test.rb b/test/ruby_lsp_rails/runner_client_test.rb index 5b69c8a3..a2f0ffc5 100644 --- a/test/ruby_lsp_rails/runner_client_test.rb +++ b/test/ruby_lsp_rails/runner_client_test.rb @@ -9,11 +9,11 @@ module Rails class RunnerClientTest < Minitest::Test def setup @outgoing_queue = Thread::Queue.new - @client = T.let(RunnerClient.new(@outgoing_queue), RunnerClient) + @client = T.let(RunnerClient.new(@outgoing_queue), T.nilable(RunnerClient)) end def teardown - @client.shutdown + T.must(@client).shutdown # On Windows, the server process sometimes takes a lot longer to shutdown and may end up getting force killed, # which makes this assertion flaky @@ -35,13 +35,13 @@ def teardown ["country_id", "integer", nil, false], ["active", "boolean", "1", false], ] - response = T.must(@client.model("User")) + response = T.must(T.must(@client).model("User")) assert_equal(columns, response.fetch(:columns)) assert_match(%r{db/schema\.rb$}, response.fetch(:schema_file)) end test "returns nil if the request returns a nil response" do - assert_nil @client.model("ApplicationRecord") # ApplicationRecord is abstract + assert_nil T.must(@client).model("ApplicationRecord") # ApplicationRecord is abstract end test "falls back to null client when bin/rails is not found" do @@ -106,7 +106,7 @@ def teardown request_name: "do_something", id: 5, ) - @client.delegate_notification(server_addon_name: "My Add-on", request_name: "do_something", id: 5) + T.must(@client).delegate_notification(server_addon_name: "My Add-on", request_name: "do_something", id: 5) end test "delegate request" do @@ -116,7 +116,7 @@ def teardown request_name: "do_something", id: 5, ) - @client.delegate_request(server_addon_name: "My Add-on", request_name: "do_something", id: 5) + T.must(@client).delegate_request(server_addon_name: "My Add-on", request_name: "do_something", id: 5) end test "server add-ons can log messages with the editor" do @@ -133,8 +133,8 @@ def execute(request, params) end RUBY - @client.register_server_addon(File.expand_path("server_addon.rb")) - @client.delegate_notification(server_addon_name: "Tapioca", request_name: "dsl") + T.must(@client).register_server_addon(File.expand_path("server_addon.rb")) + T.must(@client).delegate_notification(server_addon_name: "Tapioca", request_name: "dsl") # Started booting server pop_log_notification(@outgoing_queue, RubyLsp::Constant::MessageType::LOG)