FooBarWidget / rspec-sorbet-types

Sorbet typechecking support for RSpec
MIT License
3 stars 1 forks source link

Support request specs in rspec-rails #3

Open marknuzz opened 1 month ago

marknuzz commented 1 month ago

https://rspec.info/features/6-0/rspec-rails/request-specs/request-spec/

RSpec.describe SomeClass, type: :request do a 'response' method is often referenced in these tests.

method_missing will delegate calls to the "integration_session" object, which has an anonymous class

> integration_session.class.included_modules

[ActionDispatch::Routing::RouteSet::MountedHelpers,
 #<Module:0x00000001619796b0>,
 #<Module:0x0000000160d9c630>,
 #<Module:0x0000000160d9c6d0>,
 ActionDispatch::Routing::UrlFor,
 ActionDispatch::Routing::PolymorphicRoutes,
 ActionDispatch::TestProcess,
 ActionDispatch::TestProcess::FixtureFile,
 ActionDispatch::Integration::RequestHelpers,
 ActionDispatch::Assertions,
 Rails::Dom::Testing::Assertions,
 Rails::Dom::Testing::Assertions::SelectorAssertions,
 Rails::Dom::Testing::Assertions::DomAssertions,
 ActionDispatch::Assertions::ResponseAssertions,
 ActionDispatch::Assertions::RoutingAssertions,
 Minitest::Assertions,
 ActiveSupport::Dependencies::RequireDependency,
 ActiveSupport::ToJsonWithActiveSupportEncoder,
 JSON::Ext::Generator::GeneratorMethods::Object,
 ActiveSupport::Tryable,
 PP::ObjectMixin,
 DEBUGGER__::TrapInterceptor,
 Kernel]
 > integration_session.method(:response)
=> #<Method: #<Class:0x0000000331b38038>(ActionDispatch::Integration::Session)#response() /Users/admin/.rvm/gems/ruby-3.3.5/gems/actionpack-7.1.3.4/lib/action_dispatch/testing/integration.rb:123>

Unfortunately this ActionDispatch::Integration::Session is a class and not a module so it can't easily be included. And I don't find any other modules which have this list of methods.

However, I do see that ActionPack's ActionDispatch::Integration::Runner has a couple of rbi annotations from rbi-central. And if you try using the method https! and "go to definition", the editor will in fact jump to that rbi. The two methods in the annotation have a comment: # @method_missing: delegated to ActionDispatch::Integration::Session

So the thing to do here may be to submit a PR to rbi-central to update these annotations, and to use a shim in the meantime.

I don't think gems can provide shims or installed annotations (would be great if they did but maybe there's a good reason?). I'd rather find a way to fix it without updating the compiler to add all these methods separately for each module as that would bloat things even more.

marknuzz commented 1 month ago

Added locally to sorbet/rbi/shims/actionpack.rbi as a workaround

module ActionDispatch
  module Integration
    module Runner
      # @method_missing: delegated to ActionDispatch::Integration::Session
      sig { returns(ActionDispatch::Request) }
      def request; end

      # @method_missing: delegated to ActionDispatch::Integration::Session
      sig { returns(ActionDispatch::TestResponse) }
      def response; end
    end
  end

  class TestResponse
    sig { returns(String) }
    def body; end
  end
end