aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock18
-rw-r--r--actionmailer/lib/action_mailer/railtie.rb16
-rw-r--r--activesupport/lib/active_support/dependencies/zeitwerk_integration.rb71
-rw-r--r--railties/lib/rails.rb20
-rw-r--r--railties/lib/rails/application/configuration.rb13
-rw-r--r--railties/lib/rails/application/finisher.rb8
-rw-r--r--railties/lib/rails/engine.rb26
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile.tt6
-rw-r--r--railties/test/application/configuration_test.rb21
-rw-r--r--railties/test/application/mailer_previews_test.rb3
-rw-r--r--railties/test/application/multiple_applications_test.rb24
-rw-r--r--railties/test/application/rake_test.rb4
-rw-r--r--railties/test/application/zeitwerk_integration_test.rb164
-rw-r--r--railties/test/generators/app_generator_test.rb9
-rw-r--r--railties/test/isolation/abstract_unit.rb10
-rw-r--r--railties/test/railties/engine_test.rb32
17 files changed, 383 insertions, 66 deletions
diff --git a/Gemfile b/Gemfile
index f665321625..fda8c86cae 100644
--- a/Gemfile
+++ b/Gemfile
@@ -44,7 +44,9 @@ gem "libxml-ruby", platforms: :ruby
gem "connection_pool", require: false
# for railties app_generator_test
-gem "bootsnap", ">= 1.1.0", require: false
+gem "bootsnap", ">= 1.4.0", require: false
+
+gem "zeitwerk", ">= 1.0.0" if RUBY_ENGINE == "ruby"
# Active Job
group :job do
diff --git a/Gemfile.lock b/Gemfile.lock
index b05ae7915e..fa8094bf23 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -166,9 +166,9 @@ GEM
childprocess
faraday
selenium-webdriver
- bootsnap (1.3.2)
+ bootsnap (1.4.0)
msgpack (~> 1.0)
- bootsnap (1.3.2-java)
+ bootsnap (1.4.0-java)
msgpack (~> 1.0)
builder (3.2.3)
bunny (2.13.0)
@@ -324,10 +324,10 @@ GEM
minitest-server (1.0.5)
minitest (~> 5.0)
mono_logger (1.1.0)
- msgpack (1.2.4)
- msgpack (1.2.4-java)
- msgpack (1.2.4-x64-mingw32)
- msgpack (1.2.4-x86-mingw32)
+ msgpack (1.2.6)
+ msgpack (1.2.6-java)
+ msgpack (1.2.6-x64-mingw32)
+ msgpack (1.2.6-x86-mingw32)
multi_json (1.13.1)
multipart-post (2.0.0)
mustache (1.1.0)
@@ -516,6 +516,7 @@ GEM
websocket-extensions (0.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
+ zeitwerk (1.0.0)
PLATFORMS
java
@@ -535,7 +536,7 @@ DEPENDENCIES
benchmark-ips
blade
blade-sauce_labs_plugin
- bootsnap (>= 1.1.0)
+ bootsnap (>= 1.4.0)
byebug
capybara (>= 2.15)
chromedriver-helper
@@ -588,6 +589,7 @@ DEPENDENCIES
webmock
webpacker (>= 4.0.0.rc.3)
websocket-client-simple!
+ zeitwerk (>= 1.0.0)
BUNDLED WITH
- 1.17.2
+ 1.17.3
diff --git a/actionmailer/lib/action_mailer/railtie.rb b/actionmailer/lib/action_mailer/railtie.rb
index 23488db790..893a4a25b1 100644
--- a/actionmailer/lib/action_mailer/railtie.rb
+++ b/actionmailer/lib/action_mailer/railtie.rb
@@ -59,6 +59,14 @@ module ActionMailer
end
end
+ initializer "action_mailer.set_autoload_paths" do |app|
+ options = app.config.action_mailer
+
+ if options.show_previews && options.preview_path
+ ActiveSupport::Dependencies.autoload_paths << options.preview_path
+ end
+ end
+
initializer "action_mailer.compile_config_methods" do
ActiveSupport.on_load(:action_mailer) do
config.compile_methods! if config.respond_to?(:compile_methods!)
@@ -76,12 +84,8 @@ module ActionMailer
if options.show_previews
app.routes.prepend do
- get "/rails/mailers" => "rails/mailers#index", internal: true
- get "/rails/mailers/*path" => "rails/mailers#preview", internal: true
- end
-
- if options.preview_path
- ActiveSupport::Dependencies.autoload_paths << options.preview_path
+ get "/rails/mailers" => "rails/mailers#index", internal: true
+ get "/rails/mailers/*path" => "rails/mailers#preview", internal: true
end
end
end
diff --git a/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb b/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb
new file mode 100644
index 0000000000..8b2e1b5391
--- /dev/null
+++ b/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb
@@ -0,0 +1,71 @@
+module ActiveSupport
+ module Dependencies
+ module ZeitwerkIntegration # :nodoc: all
+ module Decorations
+ def clear
+ Dependencies.unload_interlock do
+ Rails.autoloader.reload
+ end
+ end
+
+ def constantize(cpath)
+ Inflector.constantize(cpath)
+ end
+
+ def safe_constantize(cpath)
+ Inflector.safe_constantize(cpath)
+ end
+
+ def autoloaded_constants
+ Rails.autoloaders.flat_map do |autoloader|
+ autoloader.loaded.to_a
+ end
+ end
+
+ def autoloaded?(object)
+ cpath = object.is_a?(Module) ? object.name : object.to_s
+ Rails.autoloaders.any? { |autoloader| autoloader.loaded?(cpath) }
+ end
+ end
+
+ class << self
+ def take_over
+ setup_autoloaders
+ freeze_autoload_paths
+ decorate_dependencies
+ end
+
+ private
+
+ def setup_autoloaders
+ Dependencies.autoload_paths.each do |autoload_path|
+ if File.directory?(autoload_path)
+ if autoload_once?(autoload_path)
+ Rails.once_autoloader.push_dir(autoload_path)
+ else
+ Rails.autoloader.push_dir(autoload_path)
+ end
+ end
+ end
+
+ Rails.autoloaders.each(&:setup)
+ end
+
+ def autoload_once?(autoload_path)
+ Dependencies.autoload_once_paths.include?(autoload_path) ||
+ Gem.path.any? { |gem_path| autoload_path.to_s.start_with?(gem_path) }
+ end
+
+ def freeze_autoload_paths
+ Dependencies.autoload_paths.freeze
+ Dependencies.autoload_once_paths.freeze
+ end
+
+ def decorate_dependencies
+ Dependencies.singleton_class.prepend(Decorations)
+ Object.class_eval { alias_method :require_dependency, :require }
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb
index 092105d502..bca2cf34e1 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -110,5 +110,25 @@ module Rails
def public_path
application && Pathname.new(application.paths["public"].first)
end
+
+ def autoloader
+ if configuration.autoloader == :zeitwerk
+ @autoloader ||= Zeitwerk::Loader.new
+ end
+ end
+
+ def once_autoloader
+ if configuration.autoloader == :zeitwerk
+ @once_autoloader ||= Zeitwerk::Loader.new
+ end
+ end
+
+ def autoloaders
+ if configuration.autoloader == :zeitwerk
+ [autoloader, once_autoloader]
+ else
+ []
+ end
+ end
end
end
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index b7838f7e32..16fbc99e7a 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -20,7 +20,7 @@ module Rails
:read_encrypted_secrets, :log_level, :content_security_policy_report_only,
:content_security_policy_nonce_generator, :require_master_key, :credentials
- attr_reader :encoding, :api_only, :loaded_config_version
+ attr_reader :encoding, :api_only, :loaded_config_version, :autoloader
def initialize(*)
super
@@ -64,6 +64,7 @@ module Rails
@credentials = ActiveSupport::OrderedOptions.new
@credentials.content_path = default_credentials_content_path
@credentials.key_path = default_credentials_key_path
+ @autoloader = :classic
end
def load_defaults(target_version)
@@ -117,6 +118,8 @@ module Rails
when "6.0"
load_defaults "5.2"
+ self.autoloader = :zeitwerk if RUBY_ENGINE == "ruby"
+
if respond_to?(:action_view)
action_view.default_enforce_utf8 = false
end
@@ -267,6 +270,14 @@ module Rails
end
end
+ def autoloader=(autoloader)
+ if %i(classic zeitwerk).include?(autoloader)
+ @autoloader = autoloader
+ else
+ raise ArgumentError, "config.autoloader may be :classic or :zeitwerk, got #{autoloader.inspect} instead"
+ end
+ end
+
class Custom #:nodoc:
def initialize
@configurations = Hash.new
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 04aaf6dd9a..39e8ef6631 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -21,6 +21,13 @@ module Rails
end
end
+ initializer :let_zeitwerk_take_over do
+ if config.autoloader == :zeitwerk
+ require "active_support/dependencies/zeitwerk_integration"
+ ActiveSupport::Dependencies::ZeitwerkIntegration.take_over
+ end
+ end
+
initializer :add_builtin_route do |app|
if Rails.env.development?
app.routes.prepend do
@@ -66,6 +73,7 @@ module Rails
initializer :eager_load! do
if config.eager_load
ActiveSupport.run_load_hooks(:before_eager_load, self)
+ Zeitwerk::Loader.eager_load_all if defined?(Zeitwerk)
config.eager_load_namespaces.each(&:eager_load!)
end
end
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index d6c329b581..2485158a7b 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -472,12 +472,10 @@ module Rails
# Eager load the application by loading all ruby
# files inside eager_load paths.
def eager_load!
- config.eager_load_paths.each do |load_path|
- # Starts after load_path plus a slash, ends before ".rb".
- relname_range = (load_path.to_s.length + 1)...-3
- Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
- require_dependency file[relname_range]
- end
+ if Rails.autoloader
+ eager_load_with_zeitwerk!
+ else
+ eager_load_with_dependencies!
end
end
@@ -653,6 +651,22 @@ module Rails
private
+ def eager_load_with_zeitwerk!
+ (config.eager_load_paths - Zeitwerk::Loader.all_dirs).each do |path|
+ Dir.glob("#{path}/**/*.rb").sort.each { |file| require file }
+ end
+ end
+
+ def eager_load_with_dependencies!
+ config.eager_load_paths.each do |load_path|
+ # Starts after load_path plus a slash, ends before ".rb".
+ relname_range = (load_path.to_s.length + 1)...-3
+ Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
+ require_dependency file[relname_range]
+ end
+ end
+ end
+
def load_config_initializer(initializer) # :doc:
ActiveSupport::Notifications.instrument("load_config_initializer.railties", initializer: initializer) do
load(initializer)
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
index d39b5d311f..a1f1224a45 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
@@ -28,7 +28,7 @@ ruby <%= "'#{RUBY_VERSION}'" -%>
<% if depend_on_bootsnap? -%>
# Reduces boot times through caching; required in config/boot.rb
-gem 'bootsnap', '>= 1.1.0', require: false
+gem 'bootsnap', '>= 1.4.0', require: false
<%- end -%>
<%- if options.api? -%>
@@ -36,7 +36,9 @@ gem 'bootsnap', '>= 1.1.0', require: false
# gem 'rack-cors'
<%- end -%>
-<% if RUBY_ENGINE == 'ruby' -%>
+<% if RUBY_ENGINE == "ruby" -%>
+gem "zeitwerk", ">= 1.0.0"
+
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 9ea4d6dc5f..960f708bdf 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -1157,6 +1157,27 @@ module ApplicationTests
end
end
+ test "autoloader & autoloader=" do
+ app "development"
+
+ config = Rails.application.config
+ assert_instance_of Zeitwerk::Loader, Rails.autoloader
+ assert_instance_of Zeitwerk::Loader, Rails.once_autoloader
+ assert_equal [Rails.autoloader, Rails.once_autoloader], Rails.autoloaders
+
+ config.autoloader = :classic
+ assert_nil Rails.autoloader
+ assert_nil Rails.once_autoloader
+ assert_empty Rails.autoloaders
+
+ config.autoloader = :zeitwerk
+ assert_instance_of Zeitwerk::Loader, Rails.autoloader
+ assert_instance_of Zeitwerk::Loader, Rails.once_autoloader
+ assert_equal [Rails.autoloader, Rails.once_autoloader], Rails.autoloaders
+
+ assert_raises(ArgumentError) { config.autoloader = :unknown }
+ end
+
test "config.action_view.cache_template_loading with cache_classes default" do
add_to_config "config.cache_classes = true"
diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb
index ba186bda44..fb84276b8a 100644
--- a/railties/test/application/mailer_previews_test.rb
+++ b/railties/test/application/mailer_previews_test.rb
@@ -85,6 +85,7 @@ module ApplicationTests
end
test "mailer previews are loaded from a custom preview_path" do
+ app_dir "lib/mailer_previews"
add_to_config "config.action_mailer.preview_path = '#{app_path}/lib/mailer_previews'"
mailer "notifier", <<-RUBY
@@ -254,6 +255,7 @@ module ApplicationTests
end
test "mailer previews are reloaded from a custom preview_path" do
+ app_dir "lib/mailer_previews"
add_to_config "config.action_mailer.preview_path = '#{app_path}/lib/mailer_previews'"
app("development")
@@ -818,6 +820,7 @@ module ApplicationTests
def build_app
super
app_file "config/routes.rb", "Rails.application.routes.draw do; end"
+ app_dir "test/mailers/previews"
end
def mailer(name, contents)
diff --git a/railties/test/application/multiple_applications_test.rb b/railties/test/application/multiple_applications_test.rb
index 432344bccc..f0f1112f6b 100644
--- a/railties/test/application/multiple_applications_test.rb
+++ b/railties/test/application/multiple_applications_test.rb
@@ -100,30 +100,6 @@ module ApplicationTests
assert_nothing_raised { AppTemplate::Application.new }
end
- def test_initializers_run_on_different_applications_go_to_the_same_class
- application1 = AppTemplate::Application.new
- run_count = 0
-
- AppTemplate::Application.initializer :init0 do
- run_count += 1
- end
-
- application1.initializer :init1 do
- run_count += 1
- end
-
- AppTemplate::Application.new.initializer :init2 do
- run_count += 1
- end
-
- assert_equal 0, run_count, "Without loading the initializers, the count should be 0"
-
- # Set config.eager_load to false so that an eager_load warning doesn't pop up
- AppTemplate::Application.create { config.eager_load = false }.initialize!
-
- assert_equal 3, run_count, "There should have been three initializers that incremented the count"
- end
-
def test_consoles_run_on_different_applications_go_to_the_same_class
run_count = 0
AppTemplate::Application.console { run_count += 1 }
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 44e3b0f66b..fe56e3d076 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -145,8 +145,8 @@ module ApplicationTests
# loading a specific fixture
rails "db:fixtures:load", "FIXTURES=products"
- assert_equal 2, ::AppTemplate::Application::Product.count
- assert_equal 0, ::AppTemplate::Application::User.count
+ assert_equal 2, Product.count
+ assert_equal 0, User.count
end
def test_loading_only_yml_fixtures
diff --git a/railties/test/application/zeitwerk_integration_test.rb b/railties/test/application/zeitwerk_integration_test.rb
new file mode 100644
index 0000000000..d44b7f7e4d
--- /dev/null
+++ b/railties/test/application/zeitwerk_integration_test.rb
@@ -0,0 +1,164 @@
+# frozen_string_literal: true
+
+require "isolation/abstract_unit"
+require "active_support/dependencies/zeitwerk_integration"
+
+class ZeitwerkIntegrationTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ end
+
+ def boot(env = "development")
+ app(env)
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ def deps
+ ActiveSupport::Dependencies
+ end
+
+ def decorated?
+ deps.singleton_class < deps::ZeitwerkIntegration::Decorations
+ end
+
+ test "ActiveSupport::Dependencies is decorated by default" do
+ boot
+
+ assert decorated?
+ assert_instance_of Zeitwerk::Loader, Rails.autoloader
+ assert_instance_of Zeitwerk::Loader, Rails.once_autoloader
+ assert_equal [Rails.autoloader, Rails.once_autoloader], Rails.autoloaders
+ end
+
+ test "ActiveSupport::Dependencies is not decorated in classic mode" do
+ add_to_config 'config.autoloader = :classic'
+ boot
+
+ assert_not decorated?
+ assert_nil Rails.autoloader
+ assert_nil Rails.once_autoloader
+ assert_empty Rails.autoloaders
+ end
+
+ test "constantize returns the value stored in the constant" do
+ app_file "app/models/admin/user.rb", "class Admin::User; end"
+ boot
+
+ assert_same Admin::User, deps.constantize("Admin::User")
+ end
+
+ test "constantize raises if the constant is unknown" do
+ boot
+
+ assert_raises(NameError) { deps.constantize("Admin") }
+ end
+
+ test "safe_constantize returns the value stored in the constant" do
+ app_file "app/models/admin/user.rb", "class Admin::User; end"
+ boot
+
+ assert_same Admin::User, deps.safe_constantize("Admin::User")
+ end
+
+ test "safe_constantize returns nil for unknown constants" do
+ boot
+
+ assert_nil deps.safe_constantize("Admin")
+ end
+
+ test "autoloaded_constants returns autoloaded constant paths" do
+ app_file "app/models/admin/user.rb", "class Admin::User; end"
+ app_file "app/models/post.rb", "class Post; end"
+ boot
+
+ assert Admin::User
+ assert_equal ["Admin", "Admin::User"], deps.autoloaded_constants
+ end
+
+ test "autoloaded? says if a constant has been autoloaded" do
+ app_file "app/models/user.rb", "class User; end"
+ app_file "app/models/post.rb", "class Post; end"
+ boot
+
+ assert Post
+ assert deps.autoloaded?("Post")
+ assert deps.autoloaded?(Post)
+ assert_not deps.autoloaded?("User")
+ end
+
+ test "eager loading loads the application code" do
+ $zeitwerk_integration_test_user = false
+ $zeitwerk_integration_test_post = false
+
+ app_file "app/models/user.rb", "class User; end; $zeitwerk_integration_test_user = true"
+ app_file "app/models/post.rb", "class Post; end; $zeitwerk_integration_test_post = true"
+ boot("production")
+
+ assert $zeitwerk_integration_test_user
+ assert $zeitwerk_integration_test_post
+ end
+
+ test "eager loading loads anything managed by Zeitwerk" do
+ $zeitwerk_integration_test_user = false
+ app_file "app/models/user.rb", "class User; end; $zeitwerk_integration_test_user = true"
+
+ $zeitwerk_integration_test_extras = false
+ app_dir "extras"
+ app_file "extras/webhook_hacks.rb", "WebhookHacks = 1; $zeitwerk_integration_test_extras = true"
+
+ require "zeitwerk"
+ autoloader = Zeitwerk::Loader.new
+ autoloader.push_dir("#{app_path}/extras")
+ autoloader.setup
+
+ boot("production")
+
+ assert $zeitwerk_integration_test_user
+ assert $zeitwerk_integration_test_extras
+ end
+
+ test "autoload paths that are below Gem.path go to the once autoloader" do
+ app_dir "extras"
+ add_to_config 'config.autoload_paths << "#{Rails.root}/extras"'
+
+ # Mocks Gem.path to include the extras directory.
+ Gem.singleton_class.prepend(
+ Module.new do
+ def path
+ super + ["#{Rails.root}/extras"]
+ end
+ end
+ )
+ boot
+
+ refute_includes Rails.autoloader.dirs, "#{app_path}/extras"
+ assert_includes Rails.once_autoloader.dirs, "#{app_path}/extras"
+ end
+
+ test "clear reloads the main autoloader, and does not reload the once one" do
+ boot
+
+ $zeitwerk_integration_reload_test = []
+
+ autoloader = Rails.autoloader
+ def autoloader.reload
+ $zeitwerk_integration_reload_test << :autoloader
+ super
+ end
+
+ once_autoloader = Rails.once_autoloader
+ def once_autoloader.reload
+ $zeitwerk_integration_reload_test << :once_autoloader
+ super
+ end
+
+ ActiveSupport::Dependencies.clear
+
+ assert_equal %i(autoloader), $zeitwerk_integration_reload_test
+ end
+end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 1ee9e43e89..937b8eb427 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -660,6 +660,15 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_gem "jbuilder"
end
+ def test_inclusion_of_zeitwerk
+ run_generator
+ if RUBY_ENGINE == "ruby"
+ assert_gem "zeitwerk"
+ else
+ assert_no_gem "zeitwerk"
+ end
+ end
+
def test_inclusion_of_a_debugger
run_generator
if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx"
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 0e8e0e86ee..47d42645c6 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -421,6 +421,10 @@ module TestHelpers
file_name
end
+ def app_dir(path)
+ FileUtils.mkdir_p("#{app_path}/#{path}")
+ end
+
def remove_file(path)
FileUtils.rm_rf "#{app_path}/#{path}"
end
@@ -487,7 +491,11 @@ Module.new do
# Fake 'Bundler.require' -- we run using the repo's Gemfile, not an
# app-specific one: we don't want to require every gem that lists.
contents = File.read("#{app_template_path}/config/application.rb")
- contents.sub!(/^Bundler\.require.*/, "%w(turbolinks webpacker).each { |r| require r }")
+ if RUBY_ENGINE == "ruby"
+ contents.sub!(/^Bundler\.require.*/, "%w(turbolinks webpacker zeitwerk).each { |r| require r }")
+ else
+ contents.sub!(/^Bundler\.require.*/, "%w(turbolinks webpacker).each { |r| require r }")
+ end
File.write("#{app_template_path}/config/application.rb", contents)
require "rails"
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index 851407dede..69f6e34d58 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -704,25 +704,27 @@ YAML
RUBY
@plugin.write "app/controllers/bukkits/foo_controller.rb", <<-RUBY
- class Bukkits::FooController < ActionController::Base
- def index
- render inline: "<%= help_the_engine %>"
- end
+ module Bukkits
+ class FooController < ActionController::Base
+ def index
+ render inline: "<%= help_the_engine %>"
+ end
- def show
- render plain: foo_path
- end
+ def show
+ render plain: foo_path
+ end
- def from_app
- render inline: "<%= (self.respond_to?(:bar_path) || self.respond_to?(:something)) %>"
- end
+ def from_app
+ render inline: "<%= (self.respond_to?(:bar_path) || self.respond_to?(:something)) %>"
+ end
- def routes_helpers_in_view
- render inline: "<%= foo_path %>, <%= main_app.bar_path %>"
- end
+ def routes_helpers_in_view
+ render inline: "<%= foo_path %>, <%= main_app.bar_path %>"
+ end
- def polymorphic_path_without_namespace
- render plain: polymorphic_path(Post.new)
+ def polymorphic_path_without_namespace
+ render plain: polymorphic_path(Post.new)
+ end
end
end
RUBY