diff options
Diffstat (limited to 'railties/test/application')
-rw-r--r-- | railties/test/application/configuration_test.rb | 53 | ||||
-rw-r--r-- | railties/test/application/loading_test.rb | 16 | ||||
-rw-r--r-- | railties/test/application/rake/dbs_test.rb | 143 | ||||
-rw-r--r-- | railties/test/application/rake/multi_dbs_test.rb | 1 | ||||
-rw-r--r-- | railties/test/application/test_test.rb | 2 | ||||
-rw-r--r-- | railties/test/application/zeitwerk_integration_test.rb | 119 |
6 files changed, 295 insertions, 39 deletions
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 960f708bdf..9ba5517afd 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1157,23 +1157,34 @@ module ApplicationTests end end - test "autoloader & autoloader=" do + test "autoloaders" 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 + assert Rails.autoloaders.zeitwerk_enabled? + assert_instance_of Zeitwerk::Loader, Rails.autoloaders.main + assert_equal "rails.main", Rails.autoloaders.main.tag + assert_instance_of Zeitwerk::Loader, Rails.autoloaders.once + assert_equal "rails.once", Rails.autoloaders.once.tag + assert_equal [Rails.autoloaders.main, Rails.autoloaders.once], Rails.autoloaders.to_a + assert_equal ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, Rails.autoloaders.main.inflector + assert_equal ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, Rails.autoloaders.once.inflector config.autoloader = :classic - assert_nil Rails.autoloader - assert_nil Rails.once_autoloader - assert_empty Rails.autoloaders + assert_not Rails.autoloaders.zeitwerk_enabled? + assert_nil Rails.autoloaders.main + assert_nil Rails.autoloaders.once + assert_equal 0, Rails.autoloaders.count 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 Rails.autoloaders.zeitwerk_enabled? + assert_instance_of Zeitwerk::Loader, Rails.autoloaders.main + assert_equal "rails.main", Rails.autoloaders.main.tag + assert_instance_of Zeitwerk::Loader, Rails.autoloaders.once + assert_equal "rails.once", Rails.autoloaders.once.tag + assert_equal [Rails.autoloaders.main, Rails.autoloaders.once], Rails.autoloaders.to_a + assert_equal ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, Rails.autoloaders.main.inflector + assert_equal ActiveSupport::Dependencies::ZeitwerkIntegration::Inflector, Rails.autoloaders.once.inflector assert_raises(ArgumentError) { config.autoloader = :unknown } end @@ -1787,6 +1798,28 @@ module ApplicationTests end end + test "config_for loads nested custom configuration inside array from yaml with deprecated non-symbol access" do + app_file "config/custom.yml", <<-RUBY + development: + foo: + bar: + - baz: 1 + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + + app "development" + + config = Rails.application.config.my_custom_config + assert_instance_of Rails::Application::NonSymbolAccessDeprecatedHash, config[:foo][:bar].first + + assert_deprecated do + assert_equal 1, config[:foo][:bar].first["baz"] + end + end + test "config_for makes all hash methods available" do app_file "config/custom.yml", <<-RUBY development: diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb index bfa66770bd..9c98489590 100644 --- a/railties/test/application/loading_test.rb +++ b/railties/test/application/loading_test.rb @@ -34,6 +34,22 @@ class LoadingTest < ActiveSupport::TestCase assert_equal "omg", p.title end + test "constants without a matching file raise NameError" do + app_file "app/models/post.rb", <<-RUBY + class Post + NON_EXISTING_CONSTANT + end + RUBY + + boot_app + + e = assert_raise(NameError) { User } + assert_equal "uninitialized constant #{self.class}::User", e.message + + e = assert_raise(NameError) { Post } + assert_equal "uninitialized constant Post::NON_EXISTING_CONSTANT", e.message + end + test "concerns in app are autoloaded" do app_file "app/controllers/concerns/trackable.rb", <<-CONCERN module Trackable diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index 5879949b61..4f689bcb78 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true require "isolation/abstract_unit" +require "env_helpers" module ApplicationTests module RakeTests class RakeDbsTest < ActiveSupport::TestCase - include ActiveSupport::Testing::Isolation + include ActiveSupport::Testing::Isolation, EnvHelpers def setup build_app @@ -53,26 +54,17 @@ module ApplicationTests test "db:create and db:drop respect environment setting" do app_file "config/database.yml", <<-YAML development: - database: db/development.sqlite3 + database: <%= Rails.application.config.database %> adapter: sqlite3 YAML app_file "config/environments/development.rb", <<-RUBY Rails.application.configure do - config.read_encrypted_secrets = true + config.database = "db/development.sqlite3" end RUBY - app_file "lib/tasks/check_env.rake", <<-RUBY - Rake::Task["db:create"].enhance do - File.write("tmp/config_value", Rails.application.config.read_encrypted_secrets) - end - RUBY - - db_create_and_drop("db/development.sqlite3", environment_loaded: false) do - assert File.exist?("tmp/config_value") - assert_equal "true", File.read("tmp/config_value") - end + db_create_and_drop("db/development.sqlite3", environment_loaded: false) end def with_database_existing @@ -139,6 +131,59 @@ module ApplicationTests end end + test "db:truncate_all truncates all non-internal tables" do + Dir.chdir(app_path) do + rails "generate", "model", "book", "title:string" + rails "db:migrate" + require "#{app_path}/config/environment" + Book.create!(title: "Remote") + assert_equal 1, Book.count + schema_migrations = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + internal_metadata = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + + rails "db:truncate_all" + + assert_equal( + schema_migrations, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + ) + assert_equal( + internal_metadata, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + ) + assert_equal 0, Book.count + end + end + + test "db:truncate_all does not truncate any tables when environment is protected" do + with_rails_env "production" do + Dir.chdir(app_path) do + rails "generate", "model", "book", "title:string" + rails "db:migrate" + require "#{app_path}/config/environment" + Book.create!(title: "Remote") + assert_equal 1, Book.count + schema_migrations = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + internal_metadata = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + books = ActiveRecord::Base.connection.execute("SELECT * from \"books\"") + + output = rails("db:truncate_all", allow_failure: true) + assert_match(/ActiveRecord::ProtectedEnvironmentError/, output) + + assert_equal( + schema_migrations, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + ) + assert_equal( + internal_metadata, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + ) + assert_equal 1, Book.count + assert_equal(books, ActiveRecord::Base.connection.execute("SELECT * from \"books\"")) + end + end + end + def db_migrate_and_status(expected_database) rails "generate", "model", "book", "title:string" rails "db:migrate" @@ -179,9 +224,10 @@ module ApplicationTests def db_fixtures_load(expected_database) Dir.chdir(app_path) do rails "generate", "model", "book", "title:string" + reload rails "db:migrate", "db:fixtures:load" + assert_match expected_database, ActiveRecord::Base.connection_config[:database] - require "#{app_path}/app/models/book" assert_equal 2, Book.count end end @@ -201,8 +247,9 @@ module ApplicationTests require "#{app_path}/config/environment" rails "generate", "model", "admin::book", "title:string" + reload rails "db:migrate", "db:fixtures:load" - require "#{app_path}/app/models/admin/book" + assert_equal 2, Admin::Book.count end @@ -385,6 +432,72 @@ module ApplicationTests assert_equal "test", test_environment.call end + + test "db:seed:replant truncates all non-internal tables and loads the seeds" do + Dir.chdir(app_path) do + rails "generate", "model", "book", "title:string" + rails "db:migrate" + require "#{app_path}/config/environment" + Book.create!(title: "Remote") + assert_equal 1, Book.count + schema_migrations = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + internal_metadata = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + + app_file "db/seeds.rb", <<-RUBY + Book.create!(title: "Rework") + Book.create!(title: "Ruby Under a Microscope") + RUBY + + rails "db:seed:replant" + + assert_equal( + schema_migrations, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + ) + assert_equal( + internal_metadata, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + ) + assert_equal 2, Book.count + assert_not_predicate Book.where(title: "Remote"), :exists? + assert_predicate Book.where(title: "Rework"), :exists? + assert_predicate Book.where(title: "Ruby Under a Microscope"), :exists? + end + end + + test "db:seed:replant does not truncate any tables and does not load the seeds when environment is protected" do + with_rails_env "production" do + Dir.chdir(app_path) do + rails "generate", "model", "book", "title:string" + rails "db:migrate" + require "#{app_path}/config/environment" + Book.create!(title: "Remote") + assert_equal 1, Book.count + schema_migrations = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + internal_metadata = ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + books = ActiveRecord::Base.connection.execute("SELECT * from \"books\"") + + app_file "db/seeds.rb", <<-RUBY + Book.create!(title: "Rework") + RUBY + + output = rails("db:seed:replant", allow_failure: true) + assert_match(/ActiveRecord::ProtectedEnvironmentError/, output) + + assert_equal( + schema_migrations, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.schema_migrations_table_name}\"") + ) + assert_equal( + internal_metadata, + ActiveRecord::Base.connection.execute("SELECT * from \"#{ActiveRecord::Base.internal_metadata_table_name}\"") + ) + assert_equal 1, Book.count + assert_equal(books, ActiveRecord::Base.connection.execute("SELECT * from \"books\"")) + assert_not_predicate Book.where(title: "Rework"), :exists? + end + end + end end end end diff --git a/railties/test/application/rake/multi_dbs_test.rb b/railties/test/application/rake/multi_dbs_test.rb index ef99365e75..d676e7486e 100644 --- a/railties/test/application/rake/multi_dbs_test.rb +++ b/railties/test/application/rake/multi_dbs_test.rb @@ -170,6 +170,7 @@ module ApplicationTests rails "generate", "model", "book", "title:string" rails "generate", "model", "dog", "name:string" write_models_for_animals + reload end test "db:create and db:drop works on all databases for env" do diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb index fb43bebfbe..83e63718df 100644 --- a/railties/test/application/test_test.rb +++ b/railties/test/application/test_test.rb @@ -234,7 +234,7 @@ module ApplicationTests # TODO: would be nice if we could detect the schema change automatically. # For now, the user has to synchronize the schema manually. - # This test-case serves as a reminder for this use-case. + # This test case serves as a reminder for this use case. test "manually synchronize test schema after rollback" do output = rails("generate", "model", "user", "name:string") version = output.match(/(\d+)_create_users\.rb/)[1] diff --git a/railties/test/application/zeitwerk_integration_test.rb b/railties/test/application/zeitwerk_integration_test.rb index 628a85acd8..cddbf5a22d 100644 --- a/railties/test/application/zeitwerk_integration_test.rb +++ b/railties/test/application/zeitwerk_integration_test.rb @@ -30,9 +30,10 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase 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 + assert Rails.autoloaders.zeitwerk_enabled? + assert_instance_of Zeitwerk::Loader, Rails.autoloaders.main + assert_instance_of Zeitwerk::Loader, Rails.autoloaders.once + assert_equal [Rails.autoloaders.main, Rails.autoloaders.once], Rails.autoloaders.to_a end test "ActiveSupport::Dependencies is not decorated in classic mode" do @@ -40,9 +41,35 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase boot assert_not decorated? - assert_nil Rails.autoloader - assert_nil Rails.once_autoloader - assert_empty Rails.autoloaders + assert_not Rails.autoloaders.zeitwerk_enabled? + assert_nil Rails.autoloaders.main + assert_nil Rails.autoloaders.once + assert_equal 0, Rails.autoloaders.count + end + + test "autoloaders inflect with Active Support" do + app_file "config/initializers/inflections.rb", <<-RUBY + ActiveSupport::Inflector.inflections(:en) do |inflect| + inflect.acronym 'RESTful' + end + RUBY + + app_file "app/controllers/restful_controller.rb", <<-RUBY + class RESTfulController < ApplicationController + end + RUBY + + boot + + basename = "restful_controller" + abspath = "#{Rails.root}/app/controllers/#{basename}.rb" + camelized = "RESTfulController" + + Rails.autoloaders.each do |autoloader| + assert_equal camelized, autoloader.inflector.camelize(basename, abspath) + end + + assert RESTfulController end test "constantize returns the value stored in the constant" do @@ -136,8 +163,8 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase ) boot - assert_not_includes Rails.autoloader.dirs, "#{app_path}/extras" - assert_includes Rails.once_autoloader.dirs, "#{app_path}/extras" + assert_not_includes Rails.autoloaders.main.dirs, "#{app_path}/extras" + assert_includes Rails.autoloaders.once.dirs, "#{app_path}/extras" end test "clear reloads the main autoloader, and does not reload the once one" do @@ -145,13 +172,13 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase $zeitwerk_integration_reload_test = [] - autoloader = Rails.autoloader - def autoloader.reload - $zeitwerk_integration_reload_test << :autoloader + main_autoloader = Rails.autoloaders.main + def main_autoloader.reload + $zeitwerk_integration_reload_test << :main_autoloader super end - once_autoloader = Rails.once_autoloader + once_autoloader = Rails.autoloaders.once def once_autoloader.reload $zeitwerk_integration_reload_test << :once_autoloader super @@ -159,6 +186,72 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase ActiveSupport::Dependencies.clear - assert_equal %i(autoloader), $zeitwerk_integration_reload_test + assert_equal %i(main_autoloader), $zeitwerk_integration_reload_test + end + + test "verbose = true sets the dependencies logger if present" do + boot + + logger = Logger.new(File::NULL) + ActiveSupport::Dependencies.logger = logger + ActiveSupport::Dependencies.verbose = true + + Rails.autoloaders.each do |autoloader| + assert_same logger, autoloader.logger + end + end + + test "verbose = true sets the Rails logger as fallback" do + boot + + ActiveSupport::Dependencies.verbose = true + + Rails.autoloaders.each do |autoloader| + assert_same Rails.logger, autoloader.logger + end + end + + test "verbose = false sets loggers to nil" do + boot + + ActiveSupport::Dependencies.verbose = true + Rails.autoloaders.each do |autoloader| + assert autoloader.logger + end + + ActiveSupport::Dependencies.verbose = false + Rails.autoloaders.each do |autoloader| + assert_nil autoloader.logger + end + end + + test "unhooks" do + boot + + assert_equal Module, Module.method(:const_missing).owner + assert_equal :no_op, deps.unhook! + end + + test "autoloaders.logger=" do + boot + + logger = ->(_msg) { } + Rails.autoloaders.logger = logger + + Rails.autoloaders.each do |autoloader| + assert_same logger, autoloader.logger + end + + Rails.autoloaders.logger = Rails.logger + + Rails.autoloaders.each do |autoloader| + assert_same Rails.logger, autoloader.logger + end + + Rails.autoloaders.logger = nil + + Rails.autoloaders.each do |autoloader| + assert_nil autoloader.logger + end end end |