diff options
Diffstat (limited to 'railties')
-rw-r--r-- | railties/CHANGELOG.md | 13 | ||||
-rw-r--r-- | railties/Rakefile | 41 | ||||
-rw-r--r-- | railties/lib/rails/application/finisher.rb | 37 | ||||
-rw-r--r-- | railties/lib/rails/command/environment_argument.rb | 4 | ||||
-rw-r--r-- | railties/lib/rails/engine.rb | 8 | ||||
-rw-r--r-- | railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt | 15 | ||||
-rw-r--r-- | railties/lib/rails/generators/rails/plugin/plugin_generator.rb | 15 | ||||
-rw-r--r-- | railties/test/application/configuration_test.rb | 55 | ||||
-rw-r--r-- | railties/test/application/rake/routes_test.rb | 1 | ||||
-rw-r--r-- | railties/test/application/zeitwerk_integration_test.rb | 80 | ||||
-rw-r--r-- | railties/test/commands/routes_test.rb | 43 | ||||
-rw-r--r-- | railties/test/generators/actions_test.rb | 2 | ||||
-rw-r--r-- | railties/test/generators/app_generator_test.rb | 124 | ||||
-rw-r--r-- | railties/test/railties/engine_test.rb | 15 |
14 files changed, 339 insertions, 114 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index c5136b7ab0..109c4836d5 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,16 @@ +* New applications get `config.cache_classes = false` in `config/environments/test.rb` + unless `--skip-spring`. + + *Xavier Noria* + +* Autoloading during initialization is deprecated. + + *Xavier Noria* + +* Only force `:async` ActiveJob adapter to `:inline` during seeding. + + *BatedUrGonnaDie* + * The `connection` option of `rails dbconsole` command is deprecated in favor of `database` option. diff --git a/railties/Rakefile b/railties/Rakefile index 4ae546b202..0f305ea332 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -11,6 +11,33 @@ task test: "test:isolated" namespace :test do task :isolated do + estimated_duration = { + "test/application/test_runner_test.rb" => 201, + "test/application/assets_test.rb" => 131, + "test/application/rake/migrations_test.rb" => 65, + "test/generators/scaffold_generator_test.rb" => 57, + "test/generators/plugin_test_runner_test.rb" => 57, + "test/application/test_test.rb" => 52, + "test/application/configuration_test.rb" => 49, + "test/generators/app_generator_test.rb" => 43, + "test/application/rake/dbs_test.rb" => 43, + "test/application/rake_test.rb" => 33, + "test/generators/plugin_generator_test.rb" => 30, + "test/railties/engine_test.rb" => 27, + "test/generators/scaffold_controller_generator_test.rb" => 23, + "test/railties/generators_test.rb" => 19, + "test/application/console_test.rb" => 16, + "test/engine/commands_test.rb" => 15, + "test/application/routing_test.rb" => 15, + "test/application/mailer_previews_test.rb" => 15, + "test/application/rake/multi_dbs_test.rb" => 13, + "test/application/asset_debugging_test.rb" => 12, + "test/application/bin_setup_test.rb" => 11, + "test/engine/test_test.rb" => 10, + "test/application/runner_test.rb" => 10, + } + estimated_duration.default = 1 + dash_i = [ "test", "lib", @@ -39,13 +66,23 @@ namespace :test do test_patterns = dirs.map { |dir| "test/#{dir}/*_test.rb" } test_files = Dir[*test_patterns].select do |file| !file.start_with?("test/fixtures/") && !file.start_with?("test/isolation/assets/") - end.sort + end if ENV["BUILDKITE_PARALLEL_JOB_COUNT"] n = ENV["BUILDKITE_PARALLEL_JOB"].to_i m = ENV["BUILDKITE_PARALLEL_JOB_COUNT"].to_i - test_files = test_files.each_slice(m).map { |slice| slice[n] }.compact + buckets = Array.new(m) { [] } + allocations = Array.new(m) { 0 } + test_files.sort_by { |file| [-estimated_duration[file], file] }.each do |file| + idx = allocations.index(allocations.min) + buckets[idx] << file + allocations[idx] += estimated_duration[file] + end + + puts "Running #{buckets[n].size} of #{test_files.size} test files, estimated duration #{allocations[n]}s" + + test_files = buckets[n] end test_files.each do |file| diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 1cf44a480c..109c560c80 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +require "active_support/core_ext/string/inflections" +require "active_support/core_ext/array/conversions" + module Rails class Application module Finisher @@ -21,6 +24,40 @@ module Rails end end + # This will become an error if/when we remove classic mode. The plan is + # autoloaders won't be configured up to this point in the finisher, so + # constants just won't be found, raising regular NameError exceptions. + initializer :warn_if_autoloaded, before: :let_zeitwerk_take_over do + next if config.cache_classes + next if ActiveSupport::Dependencies.autoloaded_constants.empty? + + autoloaded = ActiveSupport::Dependencies.autoloaded_constants + constants = "constant".pluralize(autoloaded.size) + enum = autoloaded.to_sentence + have = autoloaded.size == 1 ? "has" : "have" + these = autoloaded.size == 1 ? "This" : "These" + example = autoloaded.first + example_klass = example.constantize.class + + ActiveSupport::DescendantsTracker.clear + ActiveSupport::Dependencies.clear + + ActiveSupport::Deprecation.warn(<<~WARNING) + Initialization autoloaded the #{constants} #{enum}. + + Being able to do this is deprecated. Autoloading during initialization is going + to be an error condition in future versions of Rails. + + Reloading does not reboot the application, and therefore code executed during + initialization does not run again. So, if you reload #{example}, for example, + the expected changes won't be reflected in that stale #{example_klass} object. + + #{these} autoloaded #{constants} #{have} been unloaded. + + Please, check the "Autoloading and Reloading Constants" guide for solutions. + WARNING + end + initializer :let_zeitwerk_take_over do if config.autoloader == :zeitwerk require "active_support/dependencies/zeitwerk_integration" diff --git a/railties/lib/rails/command/environment_argument.rb b/railties/lib/rails/command/environment_argument.rb index 0cb3f1ce1e..9945fd1430 100644 --- a/railties/lib/rails/command/environment_argument.rb +++ b/railties/lib/rails/command/environment_argument.rb @@ -9,7 +9,9 @@ module Rails extend ActiveSupport::Concern included do - class_attribute :environment_desc, default: "Specifies the environment to run this #{self.command_name} under (test/development/production)." + no_commands do + class_attribute :environment_desc, default: "Specifies the environment to run this #{self.command_name} under (test/development/production)." + end class_option :environment, aliases: "-e", type: :string, desc: environment_desc end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 778bbebe75..eb2f0e8fca 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -550,7 +550,13 @@ module Rails # Blog::Engine.load_seed def load_seed seed_file = paths["db/seeds.rb"].existent.first - with_inline_jobs { load(seed_file) } if seed_file + return unless seed_file + + if config.active_job.queue_adapter == :async + with_inline_jobs { load(seed_file) } + else + load(seed_file) + end end # Add configured load paths to Ruby's load path, and remove duplicate entries. diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt index 63ed3fa952..c66e349442 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt @@ -1,11 +1,16 @@ +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! + <%# Spring executes the reloaders when files change. %> + <%- if spring_install? -%> + config.cache_classes = false + <%- else -%> config.cache_classes = true + <%- end -%> # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index 79a06648b5..895b3b2e92 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -144,17 +144,6 @@ task default: :test end end - def javascripts - return if options.skip_javascript? - - if mountable? - template "rails/javascripts.js", - "app/assets/javascripts/#{namespaced_name}/application.js" - elsif full? - empty_directory_with_keep_file "app/assets/javascripts/#{namespaced_name}" - end - end - def bin(force = false) bin_file = engine? ? "bin/rails.tt" : "bin/test.tt" template bin_file, force: force do |content| @@ -236,10 +225,6 @@ task default: :test build(:stylesheets) unless api? end - def create_javascript_files - build(:javascripts) unless api? - end - def create_bin_files build(:bin) end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index b8e167b488..a2e3e781c0 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1704,6 +1704,61 @@ module ApplicationTests end end + test "autoloading during initialization gets deprecation message and clearing if config.cache_classes is false" do + app_file "lib/c.rb", <<~EOS + class C + extend ActiveSupport::DescendantsTracker + end + + class X < C + end + EOS + + app_file "app/models/d.rb", <<~EOS + require "c" + + class D < C + end + EOS + + app_file "config/initializers/autoload.rb", "D" + + app "development" + + # TODO: Test deprecation message, assert_depcrecated { app "development" } + # does not collect it. + + assert_equal [X], C.descendants + assert_empty ActiveSupport::Dependencies.autoloaded_constants + end + + test "autoloading during initialization triggers nothing if config.cache_classes is true" do + app_file "lib/c.rb", <<~EOS + class C + extend ActiveSupport::DescendantsTracker + end + + class X < C + end + EOS + + app_file "app/models/d.rb", <<~EOS + require "c" + + class D < C + end + EOS + + app_file "config/initializers/autoload.rb", "D" + + app "production" + + # TODO: Test no deprecation message is issued. + + assert_equal [X, D], C.descendants + end + + test "raises with proper error message if no database configuration found" do FileUtils.rm("#{app_path}/config/database.yml") err = assert_raises RuntimeError do diff --git a/railties/test/application/rake/routes_test.rb b/railties/test/application/rake/routes_test.rb index 9879d1f047..dffdae7bde 100644 --- a/railties/test/application/rake/routes_test.rb +++ b/railties/test/application/rake/routes_test.rb @@ -20,7 +20,6 @@ module ApplicationTests assert_equal <<~MESSAGE, run_rake_routes Prefix Verb URI Pattern Controller#Action cart GET /cart(.:format) cart#show - rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create diff --git a/railties/test/application/zeitwerk_integration_test.rb b/railties/test/application/zeitwerk_integration_test.rb index a9da060347..40d06ee999 100644 --- a/railties/test/application/zeitwerk_integration_test.rb +++ b/railties/test/application/zeitwerk_integration_test.rb @@ -98,24 +98,35 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase 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" + test "to_unload? says if a constant would be unloaded (main)" do + app_file "app/models/user.rb", "class User; end" app_file "app/models/post.rb", "class Post; end" boot - assert Admin::User - assert_equal ["Admin", "Admin::User"], deps.autoloaded_constants + assert Post + assert deps.to_unload?("Post") + assert_not deps.to_unload?("User") + end + + test "to_unload? says if a constant would be unloaded (once)" do + add_to_config 'config.autoload_once_paths << "#{Rails.root}/extras"' + app_file "extras/foo.rb", "class Foo; end" + app_file "extras/bar.rb", "class Bar; end" + boot + + assert Foo + assert_not deps.to_unload?("Foo") + assert_not deps.to_unload?("Bar") end - test "autoloaded? says if a constant has been autoloaded" do + test "to_unload? says if a constant would be unloaded (reloading disabled)" do app_file "app/models/user.rb", "class User; end" app_file "app/models/post.rb", "class Post; end" - boot + boot("production") assert Post - assert deps.autoloaded?("Post") - assert deps.autoloaded?(Post) - assert_not deps.autoloaded?("User") + assert_not deps.to_unload?("Post") + assert_not deps.to_unload?("User") end test "eager loading loads the application code" do @@ -145,6 +156,15 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase assert_not Rails.autoloaders.once.reloading_enabled? end + test "reloading raises if config.cache_classes is true" do + boot("production") + + e = assert_raises(StandardError) do + deps.clear + end + assert_equal "reloading is disabled because config.cache_classes is true", e.message + end + test "eager loading loads code in engines" do $test_blog_engine_eager_loaded = false @@ -315,4 +335,46 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase assert_nil autoloader.logger end end + + # This is here because to guarantee classic mode works as always, Zeitwerk + # integration does not touch anything in classic. The descendants tracker is a + # very small one-liner exception. We leave its main test suite untouched, and + # add some minimal safety net here. + # + # When time passes, things are going to be reorganized (famous last words). + test "descendants tracker" do + class ::ZeitwerkDTIntegrationTestRoot + extend ActiveSupport::DescendantsTracker + end + class ::ZeitwerkDTIntegrationTestChild < ::ZeitwerkDTIntegrationTestRoot; end + class ::ZeitwerkDTIntegrationTestGrandchild < ::ZeitwerkDTIntegrationTestChild; end + + begin + app_file "app/models/user.rb", "class User < ZeitwerkDTIntegrationTestRoot; end" + app_file "app/models/post.rb", "class Post < ZeitwerkDTIntegrationTestRoot; end" + app_file "app/models/tutorial.rb", "class Tutorial < Post; end" + boot + + assert User + assert Tutorial + + direct_descendants = [ZeitwerkDTIntegrationTestChild, User, Post].to_set + assert_equal direct_descendants, ZeitwerkDTIntegrationTestRoot.direct_descendants.to_set + + descendants = direct_descendants.merge([ZeitwerkDTIntegrationTestGrandchild, Tutorial]) + assert_equal descendants, ZeitwerkDTIntegrationTestRoot.descendants.to_set + + ActiveSupport::DescendantsTracker.clear + + direct_descendants = [ZeitwerkDTIntegrationTestChild].to_set + assert_equal direct_descendants, ZeitwerkDTIntegrationTestRoot.direct_descendants.to_set + + descendants = direct_descendants.merge([ZeitwerkDTIntegrationTestGrandchild]) + assert_equal descendants, ZeitwerkDTIntegrationTestRoot.descendants.to_set + ensure + Object.send(:remove_const, :ZeitwerkDTIntegrationTestRoot) + Object.send(:remove_const, :ZeitwerkDTIntegrationTestChild) + Object.send(:remove_const, :ZeitwerkDTIntegrationTestGrandchild) + end + end end diff --git a/railties/test/commands/routes_test.rb b/railties/test/commands/routes_test.rb index b4f927060e..a2dbd944f5 100644 --- a/railties/test/commands/routes_test.rb +++ b/railties/test/commands/routes_test.rb @@ -62,7 +62,6 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase assert_equal <<~MESSAGE, run_routes_command([ "-g", "POST" ]) Prefix Verb URI Pattern Controller#Action POST /cart(.:format) cart#create - rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create @@ -166,7 +165,6 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase assert_equal <<~MESSAGE, run_routes_command Prefix Verb URI Pattern Controller#Action - rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create @@ -207,101 +205,96 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase URI | /cart(.:format) Controller#Action | cart#show --[ Route 2 ]-------------- - Prefix | rails_amazon_inbound_emails - Verb | POST - URI | /rails/action_mailbox/amazon/inbound_emails(.:format) - Controller#Action | action_mailbox/ingresses/amazon/inbound_emails#create - --[ Route 3 ]-------------- Prefix | rails_mandrill_inbound_emails Verb | POST URI | /rails/action_mailbox/mandrill/inbound_emails(.:format) Controller#Action | action_mailbox/ingresses/mandrill/inbound_emails#create - --[ Route 4 ]-------------- + --[ Route 3 ]-------------- Prefix | rails_postmark_inbound_emails Verb | POST URI | /rails/action_mailbox/postmark/inbound_emails(.:format) Controller#Action | action_mailbox/ingresses/postmark/inbound_emails#create - --[ Route 5 ]-------------- + --[ Route 4 ]-------------- Prefix | rails_relay_inbound_emails Verb | POST URI | /rails/action_mailbox/relay/inbound_emails(.:format) Controller#Action | action_mailbox/ingresses/relay/inbound_emails#create - --[ Route 6 ]-------------- + --[ Route 5 ]-------------- Prefix | rails_sendgrid_inbound_emails Verb | POST URI | /rails/action_mailbox/sendgrid/inbound_emails(.:format) Controller#Action | action_mailbox/ingresses/sendgrid/inbound_emails#create - --[ Route 7 ]-------------- + --[ Route 6 ]-------------- Prefix | rails_mailgun_inbound_emails Verb | POST URI | /rails/action_mailbox/mailgun/inbound_emails/mime(.:format) Controller#Action | action_mailbox/ingresses/mailgun/inbound_emails#create - --[ Route 8 ]-------------- + --[ Route 7 ]-------------- Prefix | rails_conductor_inbound_emails Verb | GET URI | /rails/conductor/action_mailbox/inbound_emails(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#index - --[ Route 9 ]-------------- + --[ Route 8 ]-------------- Prefix | Verb | POST URI | /rails/conductor/action_mailbox/inbound_emails(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#create - --[ Route 10 ]------------- + --[ Route 9 ]-------------- Prefix | new_rails_conductor_inbound_email Verb | GET URI | /rails/conductor/action_mailbox/inbound_emails/new(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#new - --[ Route 11 ]------------- + --[ Route 10 ]------------- Prefix | edit_rails_conductor_inbound_email Verb | GET URI | /rails/conductor/action_mailbox/inbound_emails/:id/edit(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#edit - --[ Route 12 ]------------- + --[ Route 11 ]------------- Prefix | rails_conductor_inbound_email Verb | GET URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#show - --[ Route 13 ]------------- + --[ Route 12 ]------------- Prefix | Verb | PATCH URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#update - --[ Route 14 ]------------- + --[ Route 13 ]------------- Prefix | Verb | PUT URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#update - --[ Route 15 ]------------- + --[ Route 14 ]------------- Prefix | Verb | DELETE URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format) Controller#Action | rails/conductor/action_mailbox/inbound_emails#destroy - --[ Route 16 ]------------- + --[ Route 15 ]------------- Prefix | rails_conductor_inbound_email_reroute Verb | POST URI | /rails/conductor/action_mailbox/:inbound_email_id/reroute(.:format) Controller#Action | rails/conductor/action_mailbox/reroutes#create - --[ Route 17 ]------------- + --[ Route 16 ]------------- Prefix | rails_service_blob Verb | GET URI | /rails/active_storage/blobs/:signed_id/*filename(.:format) Controller#Action | active_storage/blobs#show - --[ Route 18 ]------------- + --[ Route 17 ]------------- Prefix | rails_blob_representation Verb | GET URI | /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) Controller#Action | active_storage/representations#show - --[ Route 19 ]------------- + --[ Route 18 ]------------- Prefix | rails_disk_service Verb | GET URI | /rails/active_storage/disk/:encoded_key/*filename(.:format) Controller#Action | active_storage/disk#show - --[ Route 20 ]------------- + --[ Route 19 ]------------- Prefix | update_rails_disk_service Verb | PUT URI | /rails/active_storage/disk/:encoded_token(.:format) Controller#Action | active_storage/disk#update - --[ Route 21 ]------------- + --[ Route 20 ]------------- Prefix | rails_direct_uploads Verb | POST URI | /rails/active_storage/direct_uploads(.:format) diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 44d4e92256..d913bb5438 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -200,7 +200,7 @@ class ActionsTest < Rails::Generators::TestCase run_generator action :environment do - _ = "# This wont be added"# assignment to silence parse-time warning "unused literal ignored" + _ = "# This wont be added" # assignment to silence parse-time warning "unused literal ignored" "# This will be added" end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 3bdbc70990..8771b53071 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -345,39 +345,44 @@ class AppGeneratorTest < Rails::Generators::TestCase app_root = File.join(destination_root, "myapp") run_generator [app_root, "--skip-spring"] - FileUtils.cd(app_root) do - quietly { system("bin/rails app:update") } - end + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_spring: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_config_files) } - assert_no_file "#{app_root}/config/spring.rb" + assert_no_file "#{app_root}/config/spring.rb" + end end def test_app_update_does_not_generate_action_cable_contents_when_skip_action_cable_is_given app_root = File.join(destination_root, "myapp") run_generator [app_root, "--skip-action-cable"] - FileUtils.cd(app_root) do - quietly { system("bin/rails app:update") } - end + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_action_cable: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_config_files) } - assert_no_file "#{app_root}/config/cable.yml" - assert_file "#{app_root}/config/environments/production.rb" do |content| - assert_no_match(/config\.action_cable/, content) + assert_no_file "#{app_root}/config/cable.yml" + assert_file "#{app_root}/config/environments/production.rb" do |content| + assert_no_match(/config\.action_cable/, content) + end + assert_no_file "#{app_root}/test/channels/application_cable/connection_test.rb" end - - assert_no_file "#{app_root}/test/channels/application_cable/connection_test.rb" end def test_app_update_does_not_generate_bootsnap_contents_when_skip_bootsnap_is_given app_root = File.join(destination_root, "myapp") run_generator [app_root, "--skip-bootsnap"] - FileUtils.cd(app_root) do - quietly { system("bin/rails app:update") } - end + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_bootsnap: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_config_files) } - assert_file "#{app_root}/config/boot.rb" do |content| - assert_no_match(/require 'bootsnap\/setup'/, content) + assert_file "#{app_root}/config/boot.rb" do |content| + assert_no_match(/require 'bootsnap\/setup'/, content) + end end end @@ -396,46 +401,50 @@ class AppGeneratorTest < Rails::Generators::TestCase app_root = File.join(destination_root, "myapp") run_generator [app_root, "--skip-active-storage"] - FileUtils.cd(app_root) do - quietly { system("bin/rails app:update") } - end + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_active_storage: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_config_files) } - assert_file "#{app_root}/config/environments/development.rb" do |content| - assert_no_match(/config\.active_storage/, content) - end + assert_file "#{app_root}/config/environments/development.rb" do |content| + assert_no_match(/config\.active_storage/, content) + end - assert_file "#{app_root}/config/environments/production.rb" do |content| - assert_no_match(/config\.active_storage/, content) - end + assert_file "#{app_root}/config/environments/production.rb" do |content| + assert_no_match(/config\.active_storage/, content) + end - assert_file "#{app_root}/config/environments/test.rb" do |content| - assert_no_match(/config\.active_storage/, content) - end + assert_file "#{app_root}/config/environments/test.rb" do |content| + assert_no_match(/config\.active_storage/, content) + end - assert_no_file "#{app_root}/config/storage.yml" + assert_no_file "#{app_root}/config/storage.yml" + end end def test_app_update_does_not_generate_active_storage_contents_when_skip_active_record_is_given app_root = File.join(destination_root, "myapp") run_generator [app_root, "--skip-active-record"] - FileUtils.cd(app_root) do - quietly { system("bin/rails app:update") } - end + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_active_record: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_config_files) } - assert_file "#{app_root}/config/environments/development.rb" do |content| - assert_no_match(/config\.active_storage/, content) - end + assert_file "#{app_root}/config/environments/development.rb" do |content| + assert_no_match(/config\.active_storage/, content) + end - assert_file "#{app_root}/config/environments/production.rb" do |content| - assert_no_match(/config\.active_storage/, content) - end + assert_file "#{app_root}/config/environments/production.rb" do |content| + assert_no_match(/config\.active_storage/, content) + end - assert_file "#{app_root}/config/environments/test.rb" do |content| - assert_no_match(/config\.active_storage/, content) - end + assert_file "#{app_root}/config/environments/test.rb" do |content| + assert_no_match(/config\.active_storage/, content) + end - assert_no_file "#{app_root}/config/storage.yml" + assert_no_file "#{app_root}/config/storage.yml" + end end def test_generator_skips_action_mailbox_when_skip_action_mailbox_is_given @@ -469,16 +478,17 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_app_update_does_not_change_config_target_version - run_generator + app_root = File.join(destination_root, "myapp") + run_generator [app_root, "--skip-spring"] - FileUtils.cd(destination_root) do + FileUtils.cd(app_root) do config = "config/application.rb" content = File.read(config) File.write(config, content.gsub(/config\.load_defaults #{Rails::VERSION::STRING.to_f}/, "config.load_defaults 5.1")) quietly { system("bin/rails app:update") } end - assert_file "config/application.rb", /\s+config\.load_defaults 5\.1/ + assert_file "#{app_root}/config/application.rb", /\s+config\.load_defaults 5\.1/ end def test_app_update_does_not_change_app_name_when_app_name_is_hyphenated_name @@ -495,13 +505,15 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_match(/hyphenated-app/, content) end - FileUtils.cd(app_root) do - quietly { system("bin/rails app:update") } - end + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_config_files) } - assert_file "#{app_root}/config/cable.yml" do |content| - assert_match(/hyphenated_app/, content) - assert_no_match(/hyphenated-app/, content) + assert_file "#{app_root}/config/cable.yml" do |content| + assert_match(/hyphenated_app/, content) + assert_no_match(/hyphenated-app/, content) + end end end @@ -827,6 +839,9 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_spring run_generator assert_gem "spring" + assert_file("config/environments/test.rb") do |contents| + assert_match("config.cache_classes = false", contents) + end end def test_bundler_binstub @@ -845,7 +860,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_spring_no_fork jruby_skip "spring doesn't run on JRuby" - assert_called_with(Process, :respond_to?, [[:fork], [:fork]], returns: false) do + assert_called_with(Process, :respond_to?, [[:fork], [:fork], [:fork]], returns: false) do run_generator assert_no_gem "spring" @@ -857,6 +872,9 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_file "config/spring.rb" assert_no_gem "spring" + assert_file("config/environments/test.rb") do |contents| + assert_match("config.cache_classes = true", contents) + end end def test_spring_with_dev_option diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 69f6e34d58..fe5c62c07d 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -879,7 +879,7 @@ YAML assert Bukkits::Engine.config.bukkits_seeds_loaded end - test "jobs are ran inline while loading seeds" do + test "jobs are ran inline while loading seeds with async adapter configured" do app_file "db/seeds.rb", <<-RUBY Rails.application.config.seed_queue_adapter = ActiveJob::Base.queue_adapter RUBY @@ -891,6 +891,19 @@ YAML assert_instance_of ActiveJob::QueueAdapters::AsyncAdapter, ActiveJob::Base.queue_adapter end + test "jobs are ran with original adapter while loading seeds with custom adapter configured" do + app_file "db/seeds.rb", <<-RUBY + Rails.application.config.seed_queue_adapter = ActiveJob::Base.queue_adapter + RUBY + + boot_rails + Rails.application.config.active_job.queue_adapter = :delayed_job + Rails.application.load_seed + + assert_instance_of ActiveJob::QueueAdapters::DelayedJobAdapter, Rails.application.config.seed_queue_adapter + assert_instance_of ActiveJob::QueueAdapters::DelayedJobAdapter, ActiveJob::Base.queue_adapter + end + test "skips nonexistent seed data" do FileUtils.rm "#{app_path}/db/seeds.rb" boot_rails |