Skip to content

Commit

Permalink
Only load example group modules when they're used
Browse files Browse the repository at this point in the history
Currently the example group modules for all spec types are always
loaded, regardless of which type of spec is being run. Some of those
modules force parts of the user's application to load; for example,
RSpec::Rails::HelperExampleGroup includes ActionView::TestCase::Behavior
and loading ActionView::TestCase loads all of the application's helpers.

By autoloading these modules and including them lazily the first time
the corresponding spec type is defined, we can avoid loading parts of
the user's application unnecessarily.

Co-authored-by: Iliana Hadzhiatanasova <me@iliana.dev>
  • Loading branch information
eugeneius and ilianah committed Mar 8, 2024
1 parent 260b3bf commit d3e593b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 29 deletions.
19 changes: 18 additions & 1 deletion lib/rspec/rails.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
require 'rspec/core'
require 'rails/version'

module RSpec
module Rails
autoload :RailsExampleGroup, 'rspec/rails/example/rails_example_group'
autoload :ControllerExampleGroup, 'rspec/rails/example/controller_example_group'
autoload :HelperExampleGroup, 'rspec/rails/example/helper_example_group'
autoload :ModelExampleGroup, 'rspec/rails/example/model_example_group'
autoload :RequestExampleGroup, 'rspec/rails/example/request_example_group'
autoload :RoutingExampleGroup, 'rspec/rails/example/routing_example_group'
autoload :ViewExampleGroup, 'rspec/rails/example/view_example_group'
autoload :FeatureExampleGroup, 'rspec/rails/example/feature_example_group'
autoload :SystemExampleGroup, 'rspec/rails/example/system_example_group'
autoload :MailerExampleGroup, 'rspec/rails/example/mailer_example_group'
autoload :JobExampleGroup, 'rspec/rails/example/job_example_group'
autoload :ChannelExampleGroup, 'rspec/rails/example/channel_example_group'
autoload :MailboxExampleGroup, 'rspec/rails/example/mailbox_example_group'
end
end

# Load any of our adapters and extensions early in the process
require 'rspec/rails/adapters'
require 'rspec/rails/extensions'
Expand All @@ -11,7 +29,6 @@
require 'rspec/rails/fixture_support'
require 'rspec/rails/file_fixture_support'
require 'rspec/rails/fixture_file_upload_support'
require 'rspec/rails/example'
require 'rspec/rails/vendor/capybara'
require 'rspec/rails/configuration'
require 'rspec/rails/active_record'
Expand Down
66 changes: 51 additions & 15 deletions lib/rspec/rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,40 @@ class Configuration
#
# @api private
def self.add_test_type_configurations(config)
config.include RSpec::Rails::ControllerExampleGroup, type: :controller
config.include RSpec::Rails::HelperExampleGroup, type: :helper
config.include RSpec::Rails::ModelExampleGroup, type: :model
config.include RSpec::Rails::RequestExampleGroup, type: :request
config.include RSpec::Rails::RoutingExampleGroup, type: :routing
config.include RSpec::Rails::ViewExampleGroup, type: :view
config.include RSpec::Rails::FeatureExampleGroup, type: :feature
config.define_derived_metadata(type: :controller) do
config.include RSpec::Rails::ControllerExampleGroup, type: :controller
end

config.define_derived_metadata(type: :helper) do
config.include RSpec::Rails::HelperExampleGroup, type: :helper
end

config.define_derived_metadata(type: :model) do
config.include RSpec::Rails::ModelExampleGroup, type: :model
end

config.define_derived_metadata(type: :request) do
config.include RSpec::Rails::RequestExampleGroup, type: :request
end

config.define_derived_metadata(type: :routing) do
require "action_controller/test_case"
config.include RSpec::Rails::RoutingExampleGroup, type: :routing
end

config.define_derived_metadata(type: :view) do
config.include RSpec::Rails::ViewExampleGroup, type: :view
end

config.define_derived_metadata(type: :feature) do
config.include RSpec::Rails::FeatureExampleGroup, type: :feature
end

config.include RSpec::Rails::Matchers
config.include RSpec::Rails::SystemExampleGroup, type: :system

config.define_derived_metadata(type: :system) do
config.include RSpec::Rails::SystemExampleGroup, type: :system
end
end

# @private
Expand Down Expand Up @@ -192,27 +217,38 @@ def fixture_path=(path)

if defined?(::Rails::Controller::Testing)
[:controller, :view, :request].each do |type|
config.include ::Rails::Controller::Testing::TestProcess, type: type
config.include ::Rails::Controller::Testing::TemplateAssertions, type: type
config.include ::Rails::Controller::Testing::Integration, type: type
config.define_derived_metadata(type: type) do
config.include ::Rails::Controller::Testing::TestProcess, type: type
config.include ::Rails::Controller::Testing::TemplateAssertions, type: type
config.include ::Rails::Controller::Testing::Integration, type: type
end
end
end

if RSpec::Rails::FeatureCheck.has_action_mailer?
config.include RSpec::Rails::MailerExampleGroup, type: :mailer
config.define_derived_metadata(type: :mailer) do
config.include RSpec::Rails::MailerExampleGroup, type: :mailer
end

config.after { ActionMailer::Base.deliveries.clear }
end

if RSpec::Rails::FeatureCheck.has_active_job?
config.include RSpec::Rails::JobExampleGroup, type: :job
config.define_derived_metadata(type: :job) do
config.include RSpec::Rails::JobExampleGroup, type: :job
end
end

if RSpec::Rails::FeatureCheck.has_action_cable_testing?
config.include RSpec::Rails::ChannelExampleGroup, type: :channel
config.define_derived_metadata(type: :channel) do
config.include RSpec::Rails::ChannelExampleGroup, type: :channel
end
end

if RSpec::Rails::FeatureCheck.has_action_mailbox?
config.include RSpec::Rails::MailboxExampleGroup, type: :mailbox
config.define_derived_metadata(type: :mailbox) do
config.include RSpec::Rails::MailboxExampleGroup, type: :mailbox
end
end
end

Expand Down
16 changes: 3 additions & 13 deletions lib/rspec/rails/example.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
require 'rspec/rails/example/rails_example_group'
require 'rspec/rails/example/controller_example_group'
require 'rspec/rails/example/request_example_group'
require 'rspec/rails/example/helper_example_group'
require 'rspec/rails/example/view_example_group'
require 'rspec/rails/example/mailer_example_group'
require 'rspec/rails/example/routing_example_group'
require 'rspec/rails/example/model_example_group'
require 'rspec/rails/example/job_example_group'
require 'rspec/rails/example/feature_example_group'
require 'rspec/rails/example/system_example_group'
require 'rspec/rails/example/channel_example_group'
require 'rspec/rails/example/mailbox_example_group'
RSpec.warn_deprecation <<~WARNING
Requiring rspec/rails/example.rb no longer has any effect, and it will be removed in RSpec Rails 7.
WARNING

0 comments on commit d3e593b

Please sign in to comment.