Skip to content

Commit

Permalink
Add DSL integration tests for add-on
Browse files Browse the repository at this point in the history
  • Loading branch information
andyw8 committed Dec 19, 2024
1 parent 14c955d commit 9cfb25c
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
/coverage/
/doc/
/pkg/
/spec/dummy/log/
/spec/dummy/tmp/
/spec/examples.txt
/spec/reports/
/tmp/
Expand Down
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Sorbet/TrueSigil:
- "**/*.rake"
Exclude:
- "lib/ruby_lsp/tapioca/server_addon.rb"
- "spec/dummy/**/*.rb"

Style/CaseEquality:
Enabled: false
Expand Down
39 changes: 39 additions & 0 deletions spec/addon_spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# typed: true
# frozen_string_literal: true

require "spec_helper"

require "language_server-protocol"
require "ruby_lsp/utils"

module ActiveSupport
class TestCase
def pop_result(server)
result = server.pop_response
result = server.pop_response until result.is_a?(RubyLsp::Result) || result.is_a?(RubyLsp::Error)

refute_instance_of(
RubyLsp::Error,
result,
-> { "Failed to execute request #{T.cast(result, RubyLsp::Error).message}" },
)
T.cast(result, RubyLsp::Result)
end

def pop_log_notification(message_queue, type)
log = message_queue.pop
return log if log.params.type == type

log = message_queue.pop until log.params.type == type
log
end

def pop_message(outgoing_queue, &block)
message = outgoing_queue.pop
return message if block.call(message)

message = outgoing_queue.pop until block.call(message)
message
end
end
end
6 changes: 6 additions & 0 deletions spec/dummy/app/models/notify_user_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

class NotifyUserJob < ActiveJob::Base
def perform(user)
end
end
14 changes: 14 additions & 0 deletions spec/dummy/bin/rails
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# This command will automatically be run when you run "rails" with Rails gems
# installed from the root of your application.

ENGINE_ROOT = File.expand_path("..", __dir__)
APP_PATH = File.expand_path("../config/application", __dir__)

# Set up gems listed in the Gemfile.
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])

require "rails/engine/commands"
7 changes: 7 additions & 0 deletions spec/dummy/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# typed: strict
# frozen_string_literal: true

require_relative "config/environment"

run Rails.application
Rails.application.load_server
16 changes: 16 additions & 0 deletions spec/dummy/config/application.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", __dir__)

require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"])
$LOAD_PATH.unshift(File.expand_path("../../../lib", __dir__))

require "rails" # minimal, instead of "rails/all"
require "active_job/railtie"

Bundler.require(*Rails.groups)

module Dummy
class Application < Rails::Application
end
end
5 changes: 5 additions & 0 deletions spec/dummy/config/environment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

require_relative "application"

Rails.application.initialize!
59 changes: 59 additions & 0 deletions spec/tapioca/addon_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# typed: true
# frozen_string_literal: true

require "addon_spec_helper"
require "ruby_lsp/ruby_lsp_rails/runner_client"
require "minitest/hooks"

module RubyLsp
module Tapioca
class AddonSpec < Minitest::HooksSpec
# The approach here is based on tests within the Ruby LSP Rails gem

# TODO: Replace by `before(:all)` once Sorbet understands it
def initialize(*args)
super(*T.unsafe(args))
FileUtils.cp("spec/dummy/bin/rails", "bin/rails")
@outgoing_queue = Thread::Queue.new
@client = T.let(nil, T.nilable(RubyLsp::Rails::RunnerClient))
FileUtils.chdir("spec/dummy") do
@client = RubyLsp::Rails::RunnerClient.new(@outgoing_queue)
end
end

after(:all) do
# TODO: Remove `bind` once Sorbet understands `after(:all)`
T.bind(self, AddonSpec)

T.must(@client).shutdown

assert_predicate(@client, :stopped?)
@outgoing_queue.close
FileUtils.rm("bin/rails")
end

EXPECTED_RBI_PATH = "spec/dummy/sorbet/rbi/dsl/notify_user_job.rbi"
it "generates DSL RBIs for a given constant" do
addon_path = File.expand_path("lib/ruby_lsp/tapioca/server_addon.rb")
T.must(@client).register_server_addon(File.expand_path(addon_path))
T.must(@client).delegate_notification(
server_addon_name: "Tapioca",
request_name: "dsl",
constants: ["NotifyUserJob"],
)

begin
Timeout.timeout(10) do
sleep(1)
until File.exist?(EXPECTED_RBI_PATH)
end
end
rescue Timeout::Error
flunk("RBI file was not generated")
end
ensure
FileUtils.rm_rf("spec/dummy/sorbet/rbi")
end
end
end
end

0 comments on commit 9cfb25c

Please sign in to comment.