diff options
Diffstat (limited to 'railties/test')
59 files changed, 1467 insertions, 509 deletions
diff --git a/railties/test/app_loader_test.rb b/railties/test/app_loader_test.rb index bb556f1968..0deb1a76df 100644 --- a/railties/test/app_loader_test.rb +++ b/railties/test/app_loader_test.rb @@ -9,12 +9,12 @@ class AppLoaderTest < ActiveSupport::TestCase @loader ||= Class.new do extend Rails::AppLoader - def self.exec_arguments - @exec_arguments - end + class << self + attr_accessor :exec_arguments - def self.exec(*args) - @exec_arguments = args + def exec(*args) + self.exec_arguments = args + end end end end @@ -40,13 +40,13 @@ class AppLoaderTest < ActiveSupport::TestCase test "is not in a Rails application if #{exe} is not found in the current or parent directories" do def loader.find_executables; end - assert !loader.exec_app + assert_not loader.exec_app end test "is not in a Rails application if #{exe} exists but is a folder" do FileUtils.mkdir_p(exe) - assert !loader.exec_app + assert_not loader.exec_app end ["APP_PATH", "ENGINE_PATH"].each do |keyword| @@ -61,7 +61,7 @@ class AppLoaderTest < ActiveSupport::TestCase test "is not in a Rails application if #{exe} exists but doesn't contain #{keyword}" do write exe - assert !loader.exec_app + assert_not loader.exec_app end test "is in a Rails application if parent directory has #{exe} containing #{keyword} and chdirs to the root directory" do @@ -76,7 +76,7 @@ class AppLoaderTest < ActiveSupport::TestCase # Compare the realpath in case either of them has symlinks. # - # This happens in particular in Mac OS X, where @tmp starts + # This happens in particular in macOS, where @tmp starts # with "/var", and Dir.pwd with "/private/var", due to a # default system symlink var -> private/var. assert_equal File.realpath("#@tmp/foo"), File.realpath(Dir.pwd) diff --git a/railties/test/application/asset_debugging_test.rb b/railties/test/application/asset_debugging_test.rb index e56c7b958e..3e0f31860b 100644 --- a/railties/test/application/asset_debugging_test.rb +++ b/railties/test/application/asset_debugging_test.rb @@ -77,7 +77,8 @@ module ApplicationTests stylesheet_link_tag: %r{<link rel="stylesheet" media="screen" href="/stylesheets/#{contents}.css" />}, javascript_include_tag: %r{<script src="/javascripts/#{contents}.js">}, audio_tag: %r{<audio src="/audios/#{contents}"></audio>}, - video_tag: %r{<video src="/videos/#{contents}"></video>} + video_tag: %r{<video src="/videos/#{contents}"></video>}, + image_submit_tag: %r{<input type="image" src="/images/#{contents}" />} } cases.each do |(view_method, tag_match)| diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index 0d3262d6f6..4ca6d02b85 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -47,7 +47,7 @@ module ApplicationTests end def assert_no_file_exists(filename) - assert !File.exist?(filename), "#{filename} does exist" + assert_not File.exist?(filename), "#{filename} does exist" end test "assets routes have higher priority" do @@ -76,7 +76,7 @@ module ApplicationTests # Load app env app "production" - assert !defined?(Uglifier) + assert_not defined?(Uglifier) get "/assets/demo.js" assert_match "alert()", last_response.body assert defined?(Uglifier) @@ -270,10 +270,10 @@ module ApplicationTests app "production" # Checking if Uglifier is defined we can know if Sprockets was reached or not - assert !defined?(Uglifier) + assert_not defined?(Uglifier) get "/assets/#{asset_path}" assert_match "alert()", last_response.body - assert !defined?(Uglifier) + assert_not defined?(Uglifier) end test "precompile properly refers files referenced with asset_path" do diff --git a/railties/test/application/configuration/custom_test.rb b/railties/test/application/configuration/custom_test.rb index 05b17b4a7a..608bc2fbe3 100644 --- a/railties/test/application/configuration/custom_test.rb +++ b/railties/test/application/configuration/custom_test.rb @@ -33,7 +33,7 @@ module ApplicationTests assert_nil x.i_do_not_exist.zomg # test that custom configuration responds to all messages - assert_equal true, x.respond_to?(:i_do_not_exist) + assert_respond_to x, :i_do_not_exist assert_kind_of Method, x.method(:i_do_not_exist) assert_kind_of ActiveSupport::OrderedOptions, x.i_do_not_exist end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 907eb4fa58..c2699006f6 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -94,7 +94,7 @@ module ApplicationTests with_rails_env "development" do app "development" - assert Rails.application.config.log_tags.blank? + assert_predicate Rails.application.config.log_tags, :blank? end end @@ -361,7 +361,7 @@ module ApplicationTests end RUBY - assert !$prepared + assert_not $prepared app "development" @@ -576,6 +576,7 @@ module ApplicationTests app "development" assert_equal "3b7cd727ee24e8444053437c36cc66c3", app.secrets.secret_key_base + assert_equal "3b7cd727ee24e8444053437c36cc66c3", app.secret_key_base end test "secret_key_base is copied from config to secrets when not set" do @@ -1416,14 +1417,14 @@ module ApplicationTests assert_equal "XML", last_response.body end - test "Rails.application#env_config exists and include some existing parameters" do + test "Rails.application#env_config exists and includes some existing parameters" do make_basic_app - assert_equal app.env_config["action_dispatch.parameter_filter"], app.config.filter_parameters - assert_equal app.env_config["action_dispatch.show_exceptions"], app.config.action_dispatch.show_exceptions - assert_equal app.env_config["action_dispatch.logger"], Rails.logger - assert_equal app.env_config["action_dispatch.backtrace_cleaner"], Rails.backtrace_cleaner - assert_equal app.env_config["action_dispatch.key_generator"], Rails.application.key_generator + assert_equal app.env_config["action_dispatch.parameter_filter"], app.config.filter_parameters + assert_equal app.env_config["action_dispatch.show_exceptions"], app.config.action_dispatch.show_exceptions + assert_equal app.env_config["action_dispatch.logger"], Rails.logger + assert_equal app.env_config["action_dispatch.backtrace_cleaner"], Rails.backtrace_cleaner + assert_equal app.env_config["action_dispatch.key_generator"], Rails.application.key_generator end test "config.colorize_logging default is true" do @@ -1478,7 +1479,7 @@ module ApplicationTests test "respond_to? accepts include_private" do make_basic_app - assert_not Rails.configuration.respond_to?(:method_missing) + assert_not_respond_to Rails.configuration, :method_missing assert Rails.configuration.respond_to?(:method_missing, true) end @@ -1509,7 +1510,7 @@ module ApplicationTests end end - assert_not_nil SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/] + assert_not_nil Rails::SourceAnnotationExtractor::Annotation.extensions[/\.(coffee)$/] end test "rake_tasks block works at instance level" do @@ -1739,9 +1740,7 @@ module ApplicationTests test "default SQLite3Adapter.represent_boolean_as_integer for 5.1 is false" do remove_from_config '.*config\.load_defaults.*\n' - add_to_top_of_config <<-RUBY - config.load_defaults 5.1 - RUBY + app_file "app/models/post.rb", <<-RUBY class Post < ActiveRecord::Base end @@ -1768,7 +1767,7 @@ module ApplicationTests test "represent_boolean_as_integer should be able to set via config.active_record.sqlite3.represent_boolean_as_integer" do remove_from_config '.*config\.load_defaults.*\n' - app_file "config/initializers/new_framework_defaults_5_2.rb", <<-RUBY + app_file "config/initializers/new_framework_defaults_6_0.rb", <<-RUBY Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true RUBY @@ -1833,7 +1832,7 @@ module ApplicationTests test "api_only is false by default" do app "development" - refute Rails.application.config.api_only + assert_not Rails.application.config.api_only end test "api_only generator config is set when api_only is set" do @@ -1890,17 +1889,51 @@ module ApplicationTests assert_equal "https://example.org/", last_response.location end - test "config.active_support.hash_digest_class is Digest::MD5 by default" do + test "ActiveSupport::MessageEncryptor.use_authenticated_message_encryption is true by default for new apps" do + app "development" + + assert_equal true, ActiveSupport::MessageEncryptor.use_authenticated_message_encryption + end + + test "ActiveSupport::MessageEncryptor.use_authenticated_message_encryption is false by default for upgraded apps" do + remove_from_config '.*config\.load_defaults.*\n' + + app "development" + + assert_equal false, ActiveSupport::MessageEncryptor.use_authenticated_message_encryption + end + + test "ActiveSupport::MessageEncryptor.use_authenticated_message_encryption can be configured via config.active_support.use_authenticated_message_encryption" do + remove_from_config '.*config\.load_defaults.*\n' + + app_file "config/initializers/new_framework_defaults_6_0.rb", <<-RUBY + Rails.application.config.active_support.use_authenticated_message_encryption = true + RUBY + + app "development" + + assert_equal true, ActiveSupport::MessageEncryptor.use_authenticated_message_encryption + end + + test "ActiveSupport::Digest.hash_digest_class is Digest::SHA1 by default for new apps" do + app "development" + + assert_equal Digest::SHA1, ActiveSupport::Digest.hash_digest_class + end + + test "ActiveSupport::Digest.hash_digest_class is Digest::MD5 by default for upgraded apps" do + remove_from_config '.*config\.load_defaults.*\n' + app "development" assert_equal Digest::MD5, ActiveSupport::Digest.hash_digest_class end - test "config.active_support.hash_digest_class can be configured" do - app_file "config/environments/development.rb", <<-RUBY - Rails.application.configure do - config.active_support.hash_digest_class = Digest::SHA1 - end + test "ActiveSupport::Digest.hash_digest_class can be configured via config.active_support.use_sha1_digests" do + remove_from_config '.*config\.load_defaults.*\n' + + app_file "config/initializers/new_framework_defaults_6_0.rb", <<-RUBY + Rails.application.config.active_support.use_sha1_digests = true RUBY app "development" @@ -1908,6 +1941,61 @@ module ApplicationTests assert_equal Digest::SHA1, ActiveSupport::Digest.hash_digest_class end + test "custom serializers should be able to set via config.active_job.custom_serializers in an initializer" do + class ::DummySerializer < ActiveJob::Serializers::ObjectSerializer; end + + app_file "config/initializers/custom_serializers.rb", <<-RUBY + Rails.application.config.active_job.custom_serializers << DummySerializer + RUBY + + app "development" + + assert_includes ActiveJob::Serializers.serializers, DummySerializer + end + + test "ActionView::Helpers::FormTagHelper.default_enforce_utf8 is false by default" do + app "development" + assert_equal false, ActionView::Helpers::FormTagHelper.default_enforce_utf8 + end + + test "ActionView::Helpers::FormTagHelper.default_enforce_utf8 is true in an upgraded app" do + remove_from_config '.*config\.load_defaults.*\n' + add_to_config 'config.load_defaults "5.2"' + + app "development" + + assert_equal true, ActionView::Helpers::FormTagHelper.default_enforce_utf8 + end + + test "ActionView::Helpers::FormTagHelper.default_enforce_utf8 can be configured via config.action_view.default_enforce_utf8" do + remove_from_config '.*config\.load_defaults.*\n' + + app_file "config/initializers/new_framework_defaults_6_0.rb", <<-RUBY + Rails.application.config.action_view.default_enforce_utf8 = true + RUBY + + app "development" + + assert_equal true, ActionView::Helpers::FormTagHelper.default_enforce_utf8 + end + + test "ActionView::Template.finalize_compiled_template_methods is true by default" do + app "test" + assert_equal true, ActionView::Template.finalize_compiled_template_methods + end + + test "ActionView::Template.finalize_compiled_template_methods can be configured via config.action_view.finalize_compiled_template_methods" do + app_file "config/environments/test.rb", <<-RUBY + Rails.application.configure do + config.action_view.finalize_compiled_template_methods = false + end + RUBY + + app "test" + + assert_equal false, ActionView::Template.finalize_compiled_template_methods + end + private def force_lazy_load_hooks yield # Tasty clarifying sugar, homie! We only need to reference a constant to load it. diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb index 13164f49c2..4a14042cd3 100644 --- a/railties/test/application/console_test.rb +++ b/railties/test/application/console_test.rb @@ -73,7 +73,7 @@ class ConsoleTest < ActiveSupport::TestCase MODEL load_environment - assert User.new.respond_to?(:name) + assert_respond_to User.new, :name app_file "app/models/user.rb", <<-MODEL class User @@ -81,9 +81,9 @@ class ConsoleTest < ActiveSupport::TestCase end MODEL - assert !User.new.respond_to?(:age) + assert_not_respond_to User.new, :age irb_context.reload!(false) - assert User.new.respond_to?(:age) + assert_respond_to User.new, :age end def test_access_to_helpers diff --git a/railties/test/application/content_security_policy_test.rb b/railties/test/application/content_security_policy_test.rb index 97f2957c33..0d28df16f8 100644 --- a/railties/test/application/content_security_policy_test.rb +++ b/railties/test/application/content_security_policy_test.rb @@ -16,7 +16,7 @@ module ApplicationTests teardown_app end - test "default content security policy is empty" do + test "default content security policy is nil" do controller :pages, <<-RUBY class PagesController < ApplicationController def index @@ -34,7 +34,33 @@ module ApplicationTests app("development") get "/" - assert_equal ";", last_response.headers["Content-Security-Policy"] + assert_nil last_response.headers["Content-Security-Policy"] + end + + test "empty content security policy is generated" do + controller :pages, <<-RUBY + class PagesController < ApplicationController + def index + render html: "<h1>Welcome to Rails!</h1>" + end + end + RUBY + + app_file "config/initializers/content_security_policy.rb", <<-RUBY + Rails.application.config.content_security_policy do |p| + end + RUBY + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + root to: "pages#index" + end + RUBY + + app("development") + + get "/" + assert_policy "" end test "global content security policy in an initializer" do @@ -61,7 +87,7 @@ module ApplicationTests app("development") get "/" - assert_policy "default-src 'self' https:;" + assert_policy "default-src 'self' https:" end test "global report only content security policy in an initializer" do @@ -90,7 +116,7 @@ module ApplicationTests app("development") get "/" - assert_policy "default-src 'self' https:;", report_only: true + assert_policy "default-src 'self' https:", report_only: true end test "override content security policy in a controller" do @@ -121,7 +147,7 @@ module ApplicationTests app("development") get "/" - assert_policy "default-src https://example.com;" + assert_policy "default-src https://example.com" end test "override content security policy to report only in a controller" do @@ -150,7 +176,7 @@ module ApplicationTests app("development") get "/" - assert_policy "default-src 'self' https:;", report_only: true + assert_policy "default-src 'self' https:", report_only: true end test "global content security policy added to rack app" do @@ -174,7 +200,7 @@ module ApplicationTests app("development") get "/" - assert_policy "default-src 'self' https:;" + assert_policy "default-src 'self' https:" end private diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index d2b77bd015..1530ea82d6 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -226,7 +226,7 @@ module ApplicationTests rails %w(generate model post title:string) rails %w(db:migrate db:schema:cache:dump db:rollback) require "#{app_path}/config/environment" - assert !ActiveRecord::Base.connection.schema_cache.data_sources("posts") + assert_not ActiveRecord::Base.connection.schema_cache.data_sources("posts") end test "active record establish_connection uses Rails.env if DATABASE_URL is not set" do @@ -266,7 +266,7 @@ module ApplicationTests ActiveRecord::Base.connection RUBY require "#{app_path}/config/environment" - assert !ActiveRecord::Base.connection_pool.active_connection? + assert_not_predicate ActiveRecord::Base.connection_pool, :active_connection? end end end diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb index de1e240fd3..889ad16fb8 100644 --- a/railties/test/application/loading_test.rb +++ b/railties/test/application/loading_test.rb @@ -352,11 +352,23 @@ class LoadingTest < ActiveSupport::TestCase def test_initialize_can_be_called_at_any_time require "#{app_path}/config/application" - assert !Rails.initialized? - assert !Rails.application.initialized? + assert_not_predicate Rails, :initialized? + assert_not_predicate Rails.application, :initialized? Rails.initialize! - assert Rails.initialized? - assert Rails.application.initialized? + assert_predicate Rails, :initialized? + assert_predicate Rails.application, :initialized? + end + + test "frameworks aren't loaded during initialization" do + app_file "config/initializers/raise_when_frameworks_load.rb", <<-RUBY + %i(action_controller action_mailer active_job active_record).each do |framework| + ActiveSupport.on_load(framework) { raise "\#{framework} loaded!" } + end + RUBY + + assert_nothing_raised do + require "#{app_path}/config/environment" + end end private diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb index 4e77cece1b..ba186bda44 100644 --- a/railties/test/application/mailer_previews_test.rb +++ b/railties/test/application/mailer_previews_test.rb @@ -296,7 +296,7 @@ module ApplicationTests test "mailer preview not found" do app("development") get "/rails/mailers/notifier" - assert last_response.not_found? + assert_predicate last_response, :not_found? assert_match "Mailer preview 'notifier' not found", last_response.body end @@ -326,7 +326,7 @@ module ApplicationTests app("development") get "/rails/mailers/notifier/bar" - assert last_response.not_found? + assert_predicate last_response, :not_found? assert_match "Email 'bar' not found in NotifierPreview", last_response.body end @@ -382,7 +382,7 @@ module ApplicationTests app("development") get "/rails/mailers/notifier/foo?part=text%2Fhtml" - assert last_response.not_found? + assert_predicate last_response, :not_found? assert_match "Email part 'text/html' not found in NotifierPreview#foo", last_response.body end @@ -450,11 +450,67 @@ module ApplicationTests get "/rails/mailers/notifier/foo.html" assert_equal 200, last_response.status - assert_match '<option selected value="?part=text%2Fhtml">View as HTML email</option>', last_response.body + assert_match '<option selected value="part=text%2Fhtml">View as HTML email</option>', last_response.body get "/rails/mailers/notifier/foo.txt" assert_equal 200, last_response.status - assert_match '<option selected value="?part=text%2Fplain">View as plain-text email</option>', last_response.body + assert_match '<option selected value="part=text%2Fplain">View as plain-text email</option>', last_response.body + end + + test "locale menu selects correct option" do + app_file "config/initializers/available_locales.rb", <<-RUBY + Rails.application.configure do + config.i18n.available_locales = %i[en ja] + end + RUBY + + mailer "notifier", <<-RUBY + class Notifier < ActionMailer::Base + default from: "from@example.com" + + def foo + mail to: "to@example.org" + end + end + RUBY + + html_template "notifier/foo", <<-RUBY + <p>Hello, World!</p> + RUBY + + text_template "notifier/foo", <<-RUBY + Hello, World! + RUBY + + mailer_preview "notifier", <<-RUBY + class NotifierPreview < ActionMailer::Preview + def foo + Notifier.foo + end + end + RUBY + + app("development") + + get "/rails/mailers/notifier/foo.html" + assert_equal 200, last_response.status + assert_match '<option selected value="locale=en">en', last_response.body + assert_match '<option value="locale=ja">ja', last_response.body + + get "/rails/mailers/notifier/foo.html?locale=ja" + assert_equal 200, last_response.status + assert_match '<option value="locale=en">en', last_response.body + assert_match '<option selected value="locale=ja">ja', last_response.body + + get "/rails/mailers/notifier/foo.txt" + assert_equal 200, last_response.status + assert_match '<option selected value="locale=en">en', last_response.body + assert_match '<option value="locale=ja">ja', last_response.body + + get "/rails/mailers/notifier/foo.txt?locale=ja" + assert_equal 200, last_response.status + assert_match '<option value="locale=en">en', last_response.body + assert_match '<option selected value="locale=ja">ja', last_response.body end test "mailer previews create correct links when loaded on a subdirectory" do @@ -520,8 +576,8 @@ module ApplicationTests get "/rails/mailers/notifier/foo.txt" assert_equal 200, last_response.status assert_match '<iframe seamless name="messageBody" src="?part=text%2Fplain">', last_response.body - assert_match '<option selected value="?part=text%2Fplain">', last_response.body - assert_match '<option value="?part=text%2Fhtml">', last_response.body + assert_match '<option selected value="part=text%2Fplain">', last_response.body + assert_match '<option value="part=text%2Fhtml">', last_response.body get "/rails/mailers/notifier/foo?part=text%2Fplain" assert_equal 200, last_response.status @@ -530,8 +586,8 @@ module ApplicationTests get "/rails/mailers/notifier/foo.html?name=Ruby" assert_equal 200, last_response.status assert_match '<iframe seamless name="messageBody" src="?name=Ruby&part=text%2Fhtml">', last_response.body - assert_match '<option selected value="?name=Ruby&part=text%2Fhtml">', last_response.body - assert_match '<option value="?name=Ruby&part=text%2Fplain">', last_response.body + assert_match '<option selected value="name=Ruby&part=text%2Fhtml">', last_response.body + assert_match '<option value="name=Ruby&part=text%2Fplain">', last_response.body get "/rails/mailers/notifier/foo?name=Ruby&part=text%2Fhtml" assert_equal 200, last_response.status diff --git a/railties/test/application/middleware/cache_test.rb b/railties/test/application/middleware/cache_test.rb index 9822ec563d..3768d8ce2d 100644 --- a/railties/test/application/middleware/cache_test.rb +++ b/railties/test/application/middleware/cache_test.rb @@ -140,7 +140,7 @@ module ApplicationTests etag = last_response.headers["ETag"] get "/expires/expires_etag", { private: true }, { "HTTP_IF_NONE_MATCH" => etag } - assert_equal "miss", last_response.headers["X-Rack-Cache"] + assert_equal "miss", last_response.headers["X-Rack-Cache"] assert_not_equal body, last_response.body end @@ -174,7 +174,7 @@ module ApplicationTests last = last_response.headers["Last-Modified"] get "/expires/expires_last_modified", { private: true }, { "HTTP_IF_MODIFIED_SINCE" => last } - assert_equal "miss", last_response.headers["X-Rack-Cache"] + assert_equal "miss", last_response.headers["X-Rack-Cache"] assert_not_equal body, last_response.body end end diff --git a/railties/test/application/middleware/sendfile_test.rb b/railties/test/application/middleware/sendfile_test.rb index 9def3a0ce7..818ad61c64 100644 --- a/railties/test/application/middleware/sendfile_test.rb +++ b/railties/test/application/middleware/sendfile_test.rb @@ -29,7 +29,7 @@ module ApplicationTests simple_controller get "/" - assert !last_response.headers["X-Sendfile"] + assert_not last_response.headers["X-Sendfile"] assert_equal File.read(__FILE__), last_response.body end diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb index a17988235a..9182a63ab7 100644 --- a/railties/test/application/middleware/session_test.rb +++ b/railties/test/application/middleware/session_test.rb @@ -31,7 +31,7 @@ module ApplicationTests add_to_config "config.force_ssl = true" add_to_config "config.ssl_options = { secure_cookies: false }" require "#{app_path}/config/environment" - assert !app.config.session_options[:secure] + assert_not app.config.session_options[:secure] end test "session is not loaded if it's not used" do @@ -51,7 +51,7 @@ module ApplicationTests get "/" assert last_request.env["HTTP_COOKIE"] - assert !last_response.headers["Set-Cookie"] + assert_not last_response.headers["Set-Cookie"] end test "session is empty and isn't saved on unverified request when using :null_session protect method" do diff --git a/railties/test/application/middleware_test.rb b/railties/test/application/middleware_test.rb index d59384e982..5efaf841d4 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -45,7 +45,8 @@ module ApplicationTests "ActionDispatch::ContentSecurityPolicy::Middleware", "Rack::Head", "Rack::ConditionalGet", - "Rack::ETag" + "Rack::ETag", + "Rack::TempfileReaper" ], middleware end diff --git a/railties/test/application/paths_test.rb b/railties/test/application/paths_test.rb index 0abc5cc9aa..28a9206daa 100644 --- a/railties/test/application/paths_test.rb +++ b/railties/test/application/paths_test.rb @@ -37,7 +37,7 @@ module ApplicationTests end def assert_not_in_load_path(*path) - assert !$:.any? { |p| File.expand_path(p) == root(*path) }, "Load path includes '#{root(*path)}'. They are:\n-----\n #{$:.join("\n")}\n-----" + assert_not $:.any? { |p| File.expand_path(p) == root(*path) }, "Load path includes '#{root(*path)}'. They are:\n-----\n #{$:.join("\n")}\n-----" end test "booting up Rails yields a valid paths object" do diff --git a/railties/test/application/per_request_digest_cache_test.rb b/railties/test/application/per_request_digest_cache_test.rb index e9bc91785c..ab055c7648 100644 --- a/railties/test/application/per_request_digest_cache_test.rb +++ b/railties/test/application/per_request_digest_cache_test.rb @@ -5,11 +5,9 @@ require "rack/test" require "minitest/mock" require "action_view" -require "active_support/testing/method_call_assertions" class PerRequestDigestCacheTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation - include ActiveSupport::Testing::MethodCallAssertions include Rack::Test::Methods setup do @@ -59,7 +57,7 @@ class PerRequestDigestCacheTest < ActiveSupport::TestCase assert_equal 200, last_response.status values = ActionView::LookupContext::DetailsKey.digest_caches.first.values - assert_equal [ "8ba099b7749542fe765ff34a6824d548" ], values + assert_equal [ "effc8928d0b33535c8a21d24ec617161" ], values assert_equal %w(david dingus), last_response.body.split.map(&:strip) end diff --git a/railties/test/application/rack/logger_test.rb b/railties/test/application/rack/logger_test.rb index d949a48366..ea425d5fa5 100644 --- a/railties/test/application/rack/logger_test.rb +++ b/railties/test/application/rack/logger_test.rb @@ -53,6 +53,12 @@ module ApplicationTests wait assert_match 'Started HEAD "/"', logs end + + test "logger logs correct remote IP address" do + get "/", {}, { "REMOTE_ADDR" => "127.0.0.1", "HTTP_X_FORWARDED_FOR" => "1.2.3.4" } + wait + assert_match 'Started GET "/" for 1.2.3.4', logs + end end end end diff --git a/railties/test/application/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb index 5b4c42c189..0594236b1f 100644 --- a/railties/test/application/rake/dbs_test.rb +++ b/railties/test/application/rake/dbs_test.rb @@ -34,7 +34,7 @@ module ApplicationTests assert_equal expected_database, ActiveRecord::Base.connection_config[:database] if environment_loaded output = rails("db:drop") assert_match(/Dropped database/, output) - assert !File.exist?(expected_database) + assert_not File.exist?(expected_database) end end diff --git a/railties/test/application/rake/migrations_test.rb b/railties/test/application/rake/migrations_test.rb index 788f9160d6..47c5ac105a 100644 --- a/railties/test/application/rake/migrations_test.rb +++ b/railties/test/application/rake/migrations_test.rb @@ -29,12 +29,32 @@ module ApplicationTests assert_match(/AMigration: migrated/, output) + # run all the migrations to test scope for down + output = rails("db:migrate") + assert_match(/CreateUsers: migrated/, output) + output = rails("db:migrate", "SCOPE=bukkits", "VERSION=0") assert_no_match(/drop_table\(:users\)/, output) assert_no_match(/CreateUsers/, output) assert_no_match(/remove_column\(:users, :email\)/, output) assert_match(/AMigration: reverted/, output) + + output = rails("db:migrate", "VERSION=0") + + assert_match(/CreateUsers: reverted/, output) + end + + test "version outputs current version" do + app_file "db/migrate/01_one_migration.rb", <<-MIGRATION + class OneMigration < ActiveRecord::Migration::Current + end + MIGRATION + + rails "db:migrate" + + output = rails("db:version") + assert_match(/Current version: 1/, output) end test "migrate with specified VERSION in different formats" do @@ -397,7 +417,7 @@ module ApplicationTests version = output =~ %r{[^/]+db/migrate/(\d+)_create_authors\.rb} && $1 rails "db:migrate", "db:rollback", "db:forward", "db:migrate:up", "db:migrate:down", "VERSION=#{version}" - assert !File.exist?("db/schema.rb"), "should not dump schema when configured not to" + assert_not File.exist?("db/schema.rb"), "should not dump schema when configured not to" end add_to_config("config.active_record.dump_schema_after_migration = true") diff --git a/railties/test/application/rake/multi_dbs_test.rb b/railties/test/application/rake/multi_dbs_test.rb new file mode 100644 index 0000000000..07d96fcb56 --- /dev/null +++ b/railties/test/application/rake/multi_dbs_test.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +require "isolation/abstract_unit" + +module ApplicationTests + module RakeTests + class RakeMultiDbsTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + def setup + build_app(multi_db: true) + FileUtils.rm_rf("#{app_path}/config/environments") + end + + def teardown + teardown_app + end + + def db_create_and_drop(namespace, expected_database, environment_loaded: true) + Dir.chdir(app_path) do + output = rails("db:create") + assert_match(/Created database/, output) + assert_match_namespace(namespace, output) + assert File.exist?(expected_database) + + output = rails("db:drop") + assert_match(/Dropped database/, output) + assert_match_namespace(namespace, output) + assert_not File.exist?(expected_database) + end + end + + def db_create_and_drop_namespace(namespace, expected_database, environment_loaded: true) + Dir.chdir(app_path) do + output = rails("db:create:#{namespace}") + assert_match(/Created database/, output) + assert_match_namespace(namespace, output) + assert File.exist?(expected_database) + + output = rails("db:drop:#{namespace}") + assert_match(/Dropped database/, output) + assert_match_namespace(namespace, output) + assert_not File.exist?(expected_database) + end + end + + def assert_match_namespace(namespace, output) + if namespace == "primary" + assert_match(/#{Rails.env}.sqlite3/, output) + else + assert_match(/#{Rails.env}_#{namespace}.sqlite3/, output) + end + end + + def db_migrate_and_schema_dump_and_load(namespace, expected_database, format) + Dir.chdir(app_path) do + rails "generate", "model", "book", "title:string" + rails "generate", "model", "dog", "name:string" + write_models_for_animals + rails "db:migrate", "db:#{format}:dump" + + if format == "schema" + schema_dump = File.read("db/#{format}.rb") + schema_dump_animals = File.read("db/animals_#{format}.rb") + assert_match(/create_table \"books\"/, schema_dump) + assert_match(/create_table \"dogs\"/, schema_dump_animals) + else + schema_dump = File.read("db/#{format}.sql") + schema_dump_animals = File.read("db/animals_#{format}.sql") + assert_match(/CREATE TABLE (?:IF NOT EXISTS )?\"books\"/, schema_dump) + assert_match(/CREATE TABLE (?:IF NOT EXISTS )?\"dogs\"/, schema_dump_animals) + end + + rails "db:#{format}:load" + + ar_tables = lambda { rails("runner", "p ActiveRecord::Base.connection.tables").strip } + animals_tables = lambda { rails("runner", "p AnimalsBase.connection.tables").strip } + + assert_equal '["schema_migrations", "ar_internal_metadata", "books"]', ar_tables[] + assert_equal '["schema_migrations", "ar_internal_metadata", "dogs"]', animals_tables[] + end + end + + def db_migrate_namespaced(namespace, expected_database) + Dir.chdir(app_path) do + rails "generate", "model", "book", "title:string" + rails "generate", "model", "dog", "name:string" + write_models_for_animals + output = rails("db:migrate:#{namespace}") + if namespace == "primary" + assert_match(/CreateBooks: migrated/, output) + else + assert_match(/CreateDogs: migrated/, output) + end + end + end + + def write_models_for_animals + # make a directory for the animals migration + FileUtils.mkdir_p("#{app_path}/db/animals_migrate") + # move the dogs migration if it unless it already lives there + FileUtils.mv(Dir.glob("#{app_path}/db/migrate/**/*dogs.rb").first, "db/animals_migrate/") unless Dir.glob("#{app_path}/db/animals_migrate/**/*dogs.rb").first + # delete the dogs migration if it's still present in the + # migrate folder. This is necessary because sometimes + # the code isn't fast enough and an extra migration gets made + FileUtils.rm(Dir.glob("#{app_path}/db/migrate/**/*dogs.rb").first) if Dir.glob("#{app_path}/db/migrate/**/*dogs.rb").first + + # change the base of the dog model + app_path("/app/models/dog.rb") do |file_name| + file = File.read("#{app_path}/app/models/dog.rb") + file.sub!(/ApplicationRecord/, "AnimalsBase") + File.write(file_name, file) + end + + # create the base model for dog to inherit from + File.open("#{app_path}/app/models/animals_base.rb", "w") do |file| + file.write(<<-EOS +class AnimalsBase < ActiveRecord::Base + self.abstract_class = true + + establish_connection :animals +end +EOS +) + end + end + + test "db:create and db:drop works on all databases for env" do + require "#{app_path}/config/environment" + ActiveRecord::Base.configurations[Rails.env].each do |namespace, config| + db_create_and_drop namespace, config["database"] + end + end + + test "db:create:namespace and db:drop:namespace works on specified databases" do + require "#{app_path}/config/environment" + ActiveRecord::Base.configurations[Rails.env].each do |namespace, config| + db_create_and_drop_namespace namespace, config["database"] + end + end + + test "db:migrate and db:schema:dump and db:schema:load works on all databases" do + require "#{app_path}/config/environment" + ActiveRecord::Base.configurations[Rails.env].each do |namespace, config| + db_migrate_and_schema_dump_and_load namespace, config["database"], "schema" + end + end + + test "db:migrate and db:structure:dump and db:structure:load works on all databases" do + require "#{app_path}/config/environment" + ActiveRecord::Base.configurations[Rails.env].each do |namespace, config| + db_migrate_and_schema_dump_and_load namespace, config["database"], "structure" + end + end + + test "db:migrate:namespace works" do + require "#{app_path}/config/environment" + ActiveRecord::Base.configurations[Rails.env].each do |namespace, config| + db_migrate_namespaced namespace, config["database"] + end + end + end + end +end diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 8e9fe9b6b4..9e22ba84b5 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -30,19 +30,22 @@ module ApplicationTests app_file "config/locales/en.yaml", "# TODO: note in yaml" app_file "app/views/home/index.ruby", "# TODO: note in ruby" - run_rake_notes do |output, lines| - assert_match(/note in erb/, output) - assert_match(/note in js/, output) - assert_match(/note in css/, output) - assert_match(/note in rake/, output) - assert_match(/note in builder/, output) - assert_match(/note in yml/, output) - assert_match(/note in yaml/, output) - assert_match(/note in ruby/, output) - - assert_equal 9, lines.size - assert_equal [4], lines.map(&:size).uniq + stderr = capture(:stderr) do + run_rake_notes do |output, lines| + assert_match(/note in erb/, output) + assert_match(/note in js/, output) + assert_match(/note in css/, output) + assert_match(/note in rake/, output) + assert_match(/note in builder/, output) + assert_match(/note in yml/, output) + assert_match(/note in yaml/, output) + assert_match(/note in ruby/, output) + + assert_equal 9, lines.size + assert_equal [4], lines.map(&:size).uniq + end end + assert_match(/DEPRECATION WARNING: This rake task is deprecated and will be removed in Rails 6.1/, stderr) end test "notes finds notes in default directories" do @@ -54,17 +57,20 @@ module ApplicationTests app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" - run_rake_notes do |output, lines| - assert_match(/note in app directory/, output) - assert_match(/note in config directory/, output) - assert_match(/note in db directory/, output) - assert_match(/note in lib directory/, output) - assert_match(/note in test directory/, output) - assert_no_match(/note in some_other directory/, output) - - assert_equal 5, lines.size - assert_equal [4], lines.map(&:size).uniq + stderr = capture(:stderr) do + run_rake_notes do |output, lines| + assert_match(/note in app directory/, output) + assert_match(/note in config directory/, output) + assert_match(/note in db directory/, output) + assert_match(/note in lib directory/, output) + assert_match(/note in test directory/, output) + assert_no_match(/note in some_other directory/, output) + + assert_equal 5, lines.size + assert_equal [4], lines.map(&:size).uniq + end end + assert_match(/DEPRECATION WARNING: This rake task is deprecated and will be removed in Rails 6.1/, stderr) end test "notes finds notes in custom directories" do @@ -76,18 +82,22 @@ module ApplicationTests app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" - run_rake_notes "SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bin/rails notes" do |output, lines| - assert_match(/note in app directory/, output) - assert_match(/note in config directory/, output) - assert_match(/note in db directory/, output) - assert_match(/note in lib directory/, output) - assert_match(/note in test directory/, output) + stderr = capture(:stderr) do + run_rake_notes "SOURCE_ANNOTATION_DIRECTORIES='some_other_dir' bin/rake notes" do |output, lines| + assert_match(/note in app directory/, output) + assert_match(/note in config directory/, output) + assert_match(/note in db directory/, output) + assert_match(/note in lib directory/, output) + assert_match(/note in test directory/, output) - assert_match(/note in some_other directory/, output) + assert_match(/note in some_other directory/, output) - assert_equal 6, lines.size - assert_equal [4], lines.map(&:size).uniq + assert_equal 6, lines.size + assert_equal [4], lines.map(&:size).uniq + end end + assert_match(/DEPRECATION WARNING: This rake task is deprecated and will be removed in Rails 6.1/, stderr) + assert_match(/DEPRECATION WARNING: `SOURCE_ANNOTATION_DIRECTORIES` is deprecated and will be removed in Rails 6.1/, stderr) end test "custom rake task finds specific notes in specific directories" do @@ -101,7 +111,7 @@ module ApplicationTests task :notes_custom do tags = 'TODO|FIXME' opts = { dirs: %w(lib test), tag: true } - SourceAnnotationExtractor.enumerate(tags, opts) + Rails::SourceAnnotationExtractor.enumerate(tags, opts) end EOS @@ -122,11 +132,14 @@ module ApplicationTests app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss" app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass" - run_rake_notes do |output, lines| - assert_match(/note in scss/, output) - assert_match(/note in sass/, output) - assert_equal 2, lines.size + stderr = capture(:stderr) do + run_rake_notes do |output, lines| + assert_match(/note in scss/, output) + assert_match(/note in sass/, output) + assert_equal 2, lines.size + end end + assert_match(/DEPRECATION WARNING: This rake task is deprecated and will be removed in Rails 6.1/, stderr) end test "register additional directories" do @@ -134,38 +147,27 @@ module ApplicationTests app_file "spec/models/user_spec.rb", "# TODO: note in model spec" add_to_config ' config.annotations.register_directories("spec") ' - run_rake_notes do |output, lines| - assert_match(/note in spec/, output) - assert_match(/note in model spec/, output) - assert_equal 2, lines.size + stderr = capture(:stderr) do + run_rake_notes do |output, lines| + assert_match(/note in spec/, output) + assert_match(/note in model spec/, output) + assert_equal 2, lines.size + end end + assert_match(/DEPRECATION WARNING: This rake task is deprecated and will be removed in Rails 6.1/, stderr) end private - def run_rake_notes(command = "bin/rails notes") - boot_rails - load_tasks - + def run_rake_notes(command = "bin/rake notes") Dir.chdir(app_path) do output = `#{command}` - lines = output.scan(/\[([0-9\s]+)\]\s/).flatten + + lines = output.scan(/\[([0-9\s]+)\]\s/).flatten yield output, lines end end - - def load_tasks - require "rake" - require "rdoc/task" - require "rake/testtask" - - Rails.application.load_tasks - end - - def boot_rails - require "#{app_path}/config/environment" - end end end end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index 5a6404bd0a..1522a2bbc5 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -2,7 +2,6 @@ require "isolation/abstract_unit" require "env_helpers" -require "active_support/core_ext/string/strip" module ApplicationTests class RakeTest < ActiveSupport::TestCase @@ -42,7 +41,7 @@ module ApplicationTests rails "db:create", "db:migrate" output = rails("db:test:prepare", "test") - refute_match(/ActiveRecord::ProtectedEnvironmentError/, output) + assert_no_match(/ActiveRecord::ProtectedEnvironmentError/, output) end end @@ -123,157 +122,6 @@ module ApplicationTests rails("stats") end - def test_rails_routes_calls_the_route_inspector - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - get '/cart', to: 'cart#show' - end - RUBY - - output = rails("routes") - assert_equal <<-MESSAGE.strip_heredoc, output - Prefix Verb URI Pattern Controller#Action - cart GET /cart(.:format) cart#show - rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show - rails_blob_variation GET /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) active_storage/variants#show - rails_blob_preview GET /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format) active_storage/previews#show - rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show - update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update - rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create - MESSAGE - end - - def test_singular_resource_output_in_rake_routes - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - resource :post - end - RUBY - - expected_output = [" Prefix Verb URI Pattern Controller#Action", - " new_post GET /post/new(.:format) posts#new", - "edit_post GET /post/edit(.:format) posts#edit", - " post GET /post(.:format) posts#show", - " PATCH /post(.:format) posts#update", - " PUT /post(.:format) posts#update", - " DELETE /post(.:format) posts#destroy", - " POST /post(.:format) posts#create\n"].join("\n") - - output = rails("routes", "-c", "PostController") - assert_equal expected_output, output - end - - def test_rails_routes_with_global_search_key - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - get '/cart', to: 'cart#show' - post '/cart', to: 'cart#create' - get '/basketballs', to: 'basketball#index' - end - RUBY - - output = rails("routes", "-g", "show") - assert_equal <<-MESSAGE.strip_heredoc, output - Prefix Verb URI Pattern Controller#Action - cart GET /cart(.:format) cart#show - rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show - rails_blob_variation GET /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) active_storage/variants#show - rails_blob_preview GET /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format) active_storage/previews#show - rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show - MESSAGE - - output = rails("routes", "-g", "POST") - assert_equal <<-MESSAGE.strip_heredoc, output - Prefix Verb URI Pattern Controller#Action - POST /cart(.:format) cart#create - rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create - MESSAGE - - output = rails("routes", "-g", "basketballs") - assert_equal " Prefix Verb URI Pattern Controller#Action\n" \ - "basketballs GET /basketballs(.:format) basketball#index\n", output - end - - def test_rails_routes_with_controller_search_key - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - get '/cart', to: 'cart#show' - get '/basketball', to: 'basketball#index' - end - RUBY - - output = rails("routes", "-c", "cart") - assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output - - output = rails("routes", "-c", "Cart") - assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output - - output = rails("routes", "-c", "CartController") - assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output - end - - def test_rails_routes_with_namespaced_controller_search_key - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - namespace :admin do - resource :post - end - end - RUBY - expected_output = [" Prefix Verb URI Pattern Controller#Action", - " new_admin_post GET /admin/post/new(.:format) admin/posts#new", - "edit_admin_post GET /admin/post/edit(.:format) admin/posts#edit", - " admin_post GET /admin/post(.:format) admin/posts#show", - " PATCH /admin/post(.:format) admin/posts#update", - " PUT /admin/post(.:format) admin/posts#update", - " DELETE /admin/post(.:format) admin/posts#destroy", - " POST /admin/post(.:format) admin/posts#create\n"].join("\n") - - output = rails("routes", "-c", "Admin::PostController") - assert_equal expected_output, output - - output = rails("routes", "-c", "PostController") - assert_equal expected_output, output - end - - def test_rails_routes_displays_message_when_no_routes_are_defined - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - end - RUBY - - assert_equal <<-MESSAGE.strip_heredoc, rails("routes") - Prefix Verb URI Pattern Controller#Action - rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show - rails_blob_variation GET /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) active_storage/variants#show - rails_blob_preview GET /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format) active_storage/previews#show - rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show - update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update - rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create - MESSAGE - end - - def test_rake_routes_with_rake_options - app_file "config/routes.rb", <<-RUBY - Rails.application.routes.draw do - get '/cart', to: 'cart#show' - end - RUBY - - output = Dir.chdir(app_path) { `bin/rake --rakefile Rakefile routes` } - - assert_equal <<-MESSAGE.strip_heredoc, output - Prefix Verb URI Pattern Controller#Action - cart GET /cart(.:format) cart#show - rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show - rails_blob_variation GET /rails/active_storage/variants/:signed_blob_id/:variation_key/*filename(.:format) active_storage/variants#show - rails_blob_preview GET /rails/active_storage/previews/:signed_blob_id/:variation_key/*filename(.:format) active_storage/previews#show - rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show - update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update - rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create - MESSAGE - end - def test_logger_is_flushed_when_exiting_production_rake_tasks add_to_config <<-RUBY rake_tasks do @@ -381,7 +229,7 @@ module ApplicationTests def test_rake_clear_schema_cache rails "db:schema:cache:dump", "db:schema:cache:clear" - assert !File.exist?(File.join(app_path, "db", "schema_cache.yml")) + assert_not File.exist?(File.join(app_path, "db", "schema_cache.yml")) end def test_copy_templates diff --git a/railties/test/application/rendering_test.rb b/railties/test/application/rendering_test.rb index 3724886c54..ab1591f388 100644 --- a/railties/test/application/rendering_test.rb +++ b/railties/test/application/rendering_test.rb @@ -4,7 +4,7 @@ require "isolation/abstract_unit" require "rack/test" module ApplicationTests - class RoutingTest < ActiveSupport::TestCase + class RenderingTest < ActiveSupport::TestCase include ActiveSupport::Testing::Isolation include Rack::Test::Methods diff --git a/railties/test/application/runner_test.rb b/railties/test/application/runner_test.rb index aa5d495c97..8f5f48c281 100644 --- a/railties/test/application/runner_test.rb +++ b/railties/test/application/runner_test.rb @@ -107,13 +107,13 @@ module ApplicationTests def test_runner_detects_syntax_errors output = rails("runner", "puts 'hello world", allow_failure: true) - assert_not $?.success? + assert_not_predicate $?, :success? assert_match "unterminated string meets end of file", output end def test_runner_detects_bad_script_name output = rails("runner", "iuiqwiourowe", allow_failure: true) - assert_not $?.success? + assert_not_predicate $?, :success? assert_match "undefined local variable or method `iuiqwiourowe' for", output end diff --git a/railties/test/application/server_test.rb b/railties/test/application/server_test.rb index a6093b5733..92b991dd05 100644 --- a/railties/test/application/server_test.rb +++ b/railties/test/application/server_test.rb @@ -29,14 +29,14 @@ module ApplicationTests server.app log = File.read(Rails.application.config.paths["log"].first) - assert_match(/DEPRECATION WARNING: Use `Rails::Application` subclass to start the server is deprecated/, log) + assert_match(/DEPRECATION WARNING: Using `Rails::Application` subclass to start the server is deprecated/, log) end test "restart rails server with custom pid file path" do skip "PTY unavailable" unless available_pty? File.open("#{app_path}/config/boot.rb", "w") do |f| - f.puts "ENV['BUNDLE_GEMFILE'] = '#{Bundler.default_gemfile.to_s}'" + f.puts "ENV['BUNDLE_GEMFILE'] = '#{Bundler.default_gemfile}'" f.puts "require 'bundler/setup'" end diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb index a01325fdb8..455dc60efd 100644 --- a/railties/test/application/test_runner_test.rb +++ b/railties/test/application/test_runner_test.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require "isolation/abstract_unit" -require "active_support/core_ext/string/strip" require "env_helpers" module ApplicationTests @@ -502,10 +501,10 @@ module ApplicationTests end def test_output_inline_by_default - create_test_file :models, "post", pass: false + create_test_file :models, "post", pass: false, print: false output = run_test_command("test/models/post_test.rb") - expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth \[[^\]]+test/models/post_test.rb:6\]:\nwups!\n\nbin/rails test test/models/post_test.rb:4\n\n\n\n} + expect = %r{Running:\n\nF\n\nFailure:\nPostTest#test_truth \[[^\]]+test/models/post_test.rb:6\]:\nwups!\n\nrails test test/models/post_test.rb:4\n\n\n\n} assert_match expect, output end @@ -523,6 +522,28 @@ module ApplicationTests capture(:stderr) { run_test_command("test/models/post_test.rb --fail-fast", stderr: true) }) end + def test_run_in_parallel_with_processes + file_name = create_parallel_processes_test_file + + output = run_test_command(file_name) + + assert_match %r{Finished in.*\n2 runs, 2 assertions}, output + end + + def test_run_in_parallel_with_threads + app_path("/test/test_helper.rb") do |file_name| + file = File.read(file_name) + file.sub!(/parallelize\(([^\)]*)\)/, "parallelize(\\1, with: :threads)") + File.write(file_name, file) + end + + file_name = create_parallel_threads_test_file + + output = run_test_command(file_name) + + assert_match %r{Finished in.*\n2 runs, 2 assertions}, output + end + def test_raise_error_when_specified_file_does_not_exist error = capture(:stderr) { run_test_command("test/not_exists.rb", stderr: true) } assert_match(%r{cannot load such file.+test/not_exists\.rb}, error) @@ -532,7 +553,7 @@ module ApplicationTests create_test_file :models, "account" create_test_file :models, "post", pass: false # This specifically verifies TEST for backwards compatibility with rake test - # as bin/rails test already supports running tests from a single file more cleanly. + # as `rails test` already supports running tests from a single file more cleanly. output = Dir.chdir(app_path) { `bin/rake test TEST=test/models/post_test.rb` } assert_match "PostTest", output, "passing TEST= should run selected test" @@ -718,7 +739,7 @@ module ApplicationTests def create_model_with_fixture rails "generate", "model", "user", "name:string" - app_file "test/fixtures/users.yml", <<-YAML.strip_heredoc + app_file "test/fixtures/users.yml", <<~YAML vampire: id: 1 name: Koyomi Araragi @@ -800,19 +821,70 @@ module ApplicationTests RUBY end - def create_test_file(path = :unit, name = "test", pass: true) + def create_test_file(path = :unit, name = "test", pass: true, print: true) app_file "test/#{path}/#{name}_test.rb", <<-RUBY require 'test_helper' class #{name.camelize}Test < ActiveSupport::TestCase def test_truth - puts "#{name.camelize}Test" + puts "#{name.camelize}Test" if #{print} assert #{pass}, 'wups!' end end RUBY end + def create_parallel_processes_test_file + app_file "test/models/parallel_test.rb", <<-RUBY + require 'test_helper' + + class ParallelTest < ActiveSupport::TestCase + RD1, WR1 = IO.pipe + RD2, WR2 = IO.pipe + + test "one" do + WR1.close + assert_equal "x", RD1.read(1) # blocks until two runs + + RD2.close + WR2.write "y" # Allow two to run + WR2.close + end + + test "two" do + RD1.close + WR1.write "x" # Allow one to run + WR1.close + + WR2.close + assert_equal "y", RD2.read(1) # blocks until one runs + end + end + RUBY + end + + def create_parallel_threads_test_file + app_file "test/models/parallel_test.rb", <<-RUBY + require 'test_helper' + + class ParallelTest < ActiveSupport::TestCase + Q1 = Queue.new + Q2 = Queue.new + test "one" do + assert_equal "x", Q1.pop # blocks until two runs + + Q2 << "y" + end + + test "two" do + Q1 << "x" + + assert_equal "y", Q2.pop # blocks until one runs + end + end + RUBY + end + def create_env_test app_file "test/unit/env_test.rb", <<-RUBY require 'test_helper' diff --git a/railties/test/application/test_test.rb b/railties/test/application/test_test.rb index 0a51e98656..fb43bebfbe 100644 --- a/railties/test/application/test_test.rb +++ b/railties/test/application/test_test.rb @@ -7,10 +7,15 @@ module ApplicationTests include ActiveSupport::Testing::Isolation def setup + @old = ENV["PARALLEL_WORKERS"] + ENV["PARALLEL_WORKERS"] = "0" + build_app end def teardown + ENV["PARALLEL_WORKERS"] = @old + teardown_app end diff --git a/railties/test/backtrace_cleaner_test.rb b/railties/test/backtrace_cleaner_test.rb index 70917ba20b..8490f9eb10 100644 --- a/railties/test/backtrace_cleaner_test.rb +++ b/railties/test/backtrace_cleaner_test.rb @@ -25,10 +25,18 @@ class BacktraceCleanerTest < ActiveSupport::TestCase end test "should consider traces from irb lines as User code" do - backtrace = [ "from (irb):1", - "from /Path/to/rails/railties/lib/rails/commands/console.rb:77:in `start'", - "from bin/rails:4:in `<main>'" ] + backtrace = [ "(irb):1", + "/Path/to/rails/railties/lib/rails/commands/console.rb:77:in `start'", + "bin/rails:4:in `<main>'" ] + result = @cleaner.clean(backtrace) + assert_equal "(irb):1", result[0] + assert_equal 1, result.length + end + + test "should omit ActionView template methods names" do + method_name = ActionView::Template.new(nil, "app/views/application/index.html.erb", nil, {}).send :method_name + backtrace = [ "app/views/application/index.html.erb:4:in `block in #{method_name}'"] result = @cleaner.clean(backtrace, :all) - assert_equal "from (irb):1", result[0] + assert_equal "app/views/application/index.html.erb:4", result[0] end end diff --git a/railties/test/command/spellchecker_test.rb b/railties/test/command/spellchecker_test.rb new file mode 100644 index 0000000000..e6a7a3957c --- /dev/null +++ b/railties/test/command/spellchecker_test.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "abstract_unit" +require "rails/command/spellchecker" + +class Rails::Command::SpellcheckerTest < ActiveSupport::TestCase + test "suggests a word correction from dictionary" do + assert_equal "thin", Rails::Command::Spellchecker.suggest("tin", from: %w(puma thin cgi)) + end +end diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb index 45ab8d87ff..0b2fe204f8 100644 --- a/railties/test/commands/console_test.rb +++ b/railties/test/commands/console_test.rb @@ -20,30 +20,30 @@ class Rails::ConsoleTest < ActiveSupport::TestCase def test_sandbox_option console = Rails::Console.new(app, parse_arguments(["--sandbox"])) - assert console.sandbox? + assert_predicate console, :sandbox? end def test_short_version_of_sandbox_option console = Rails::Console.new(app, parse_arguments(["-s"])) - assert console.sandbox? + assert_predicate console, :sandbox? end def test_no_options console = Rails::Console.new(app, parse_arguments([])) - assert !console.sandbox? + assert_not_predicate console, :sandbox? end def test_start start - assert app.console.started? + assert_predicate app.console, :started? assert_match(/Loading \w+ environment \(Rails/, output) end def test_start_with_sandbox start ["--sandbox"] - assert app.console.started? + assert_predicate app.console, :started? assert app.sandbox assert_match(/Loading \w+ environment in sandbox \(Rails/, output) end @@ -151,7 +151,8 @@ class Rails::ConsoleTest < ActiveSupport::TestCase def build_app(console) mocked_console = Class.new do - attr_reader :sandbox, :console + attr_accessor :sandbox + attr_reader :console def initialize(console) @console = console @@ -161,10 +162,6 @@ class Rails::ConsoleTest < ActiveSupport::TestCase self end - def sandbox=(arg) - @sandbox = arg - end - def load_console end end diff --git a/railties/test/commands/credentials_test.rb b/railties/test/commands/credentials_test.rb index 7c464b3fde..5b8b9e4eda 100644 --- a/railties/test/commands/credentials_test.rb +++ b/railties/test/commands/credentials_test.rb @@ -15,7 +15,7 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase test "edit without editor gives hint" do run_edit_command(editor: "").tap do |output| assert_match "No $EDITOR to open file in", output - assert_match "bin/rails credentials:edit", output + assert_match "rails credentials:edit", output end end @@ -43,6 +43,18 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase assert_match(/api_key: abc/, run_show_command) end + test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do + Dir.chdir(app_path) do + key = IO.binread("config/master.key").strip + FileUtils.rm("config/master.key") + + switch_env("RAILS_MASTER_KEY", key) do + assert_match(/access_key_id: 123/, run_edit_command) + assert_not File.exist?("config/master.key") + end + end + end + test "show credentials" do assert_match(/access_key_id: 123/, run_show_command) end diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb index 6ad96b28c7..5e3eca6585 100644 --- a/railties/test/commands/dbconsole_test.rb +++ b/railties/test/commands/dbconsole_test.rb @@ -123,31 +123,31 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase def test_mysql start(adapter: "mysql2", database: "db") - assert !aborted + assert_not aborted assert_equal [%w[mysql mysql5], "db"], dbconsole.find_cmd_and_exec_args end def test_mysql_full start(adapter: "mysql2", database: "db", host: "locahost", port: 1234, socket: "socket", username: "user", password: "qwerty", encoding: "UTF-8") - assert !aborted + assert_not aborted assert_equal [%w[mysql mysql5], "--host=locahost", "--port=1234", "--socket=socket", "--user=user", "--default-character-set=UTF-8", "-p", "db"], dbconsole.find_cmd_and_exec_args end def test_mysql_include_password start({ adapter: "mysql2", database: "db", username: "user", password: "qwerty" }, ["-p"]) - assert !aborted + assert_not aborted assert_equal [%w[mysql mysql5], "--user=user", "--password=qwerty", "db"], dbconsole.find_cmd_and_exec_args end def test_postgresql start(adapter: "postgresql", database: "db") - assert !aborted + assert_not aborted assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args end def test_postgresql_full start(adapter: "postgresql", database: "db", username: "user", password: "q1w2e3", host: "host", port: 5432) - assert !aborted + assert_not aborted assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args assert_equal "user", ENV["PGUSER"] assert_equal "host", ENV["PGHOST"] @@ -157,7 +157,7 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase def test_postgresql_include_password start({ adapter: "postgresql", database: "db", username: "user", password: "q1w2e3" }, ["-p"]) - assert !aborted + assert_not aborted assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args assert_equal "user", ENV["PGUSER"] assert_equal "q1w2e3", ENV["PGPASSWORD"] @@ -165,13 +165,13 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase def test_sqlite3 start(adapter: "sqlite3", database: "db.sqlite3") - assert !aborted + assert_not aborted assert_equal ["sqlite3", Rails.root.join("db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args end def test_sqlite3_mode start({ adapter: "sqlite3", database: "db.sqlite3" }, ["--mode", "html"]) - assert !aborted + assert_not aborted assert_equal ["sqlite3", "-html", Rails.root.join("db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args end @@ -182,27 +182,27 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase def test_sqlite3_db_absolute_path start(adapter: "sqlite3", database: "/tmp/db.sqlite3") - assert !aborted + assert_not aborted assert_equal ["sqlite3", "/tmp/db.sqlite3"], dbconsole.find_cmd_and_exec_args end def test_sqlite3_db_without_defined_rails_root Rails.stub(:respond_to?, false) do start(adapter: "sqlite3", database: "config/db.sqlite3") - assert !aborted + assert_not aborted assert_equal ["sqlite3", Rails.root.join("../config/db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args end end def test_oracle start(adapter: "oracle", database: "db", username: "user", password: "secret") - assert !aborted + assert_not aborted assert_equal ["sqlplus", "user@db"], dbconsole.find_cmd_and_exec_args end def test_oracle_include_password start({ adapter: "oracle", database: "db", username: "user", password: "secret" }, ["-p"]) - assert !aborted + assert_not aborted assert_equal ["sqlplus", "user/secret@db"], dbconsole.find_cmd_and_exec_args end @@ -265,14 +265,14 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase stdout = capture(:stdout) do Rails::Command.invoke(:dbconsole, ["-h"]) end - assert_match(/bin\/rails dbconsole \[environment\]/, stdout) + assert_match(/rails dbconsole \[environment\]/, stdout) end def test_print_help_long stdout = capture(:stdout) do Rails::Command.invoke(:dbconsole, ["--help"]) end - assert_match(/bin\/rails dbconsole \[environment\]/, stdout) + assert_match(/rails dbconsole \[environment\]/, stdout) end attr_reader :aborted, :output diff --git a/railties/test/commands/encrypted_test.rb b/railties/test/commands/encrypted_test.rb index 6647dcc902..8b608fe8c0 100644 --- a/railties/test/commands/encrypted_test.rb +++ b/railties/test/commands/encrypted_test.rb @@ -14,7 +14,7 @@ class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase test "edit without editor gives hint" do run_edit_command("config/tokens.yml.enc", editor: "").tap do |output| assert_match "No $EDITOR to open file in", output - assert_match "bin/rails encrypted:edit", output + assert_match "rails encrypted:edit", output end end @@ -33,6 +33,18 @@ class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase end end + test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do + Dir.chdir(app_path) do + key = IO.binread("config/master.key").strip + FileUtils.rm("config/master.key") + + switch_env("RAILS_MASTER_KEY", key) do + run_edit_command("config/tokens.yml.enc") + assert_not File.exist?("config/master.key") + end + end + end + test "edit encrypts file with custom key" do run_edit_command("config/tokens.yml.enc", key: "config/tokens.key") diff --git a/railties/test/commands/notes_test.rb b/railties/test/commands/notes_test.rb new file mode 100644 index 0000000000..147019e299 --- /dev/null +++ b/railties/test/commands/notes_test.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +require "isolation/abstract_unit" +require "rails/command" +require "rails/commands/notes/notes_command" + +class Rails::Command::NotesTest < ActiveSupport::TestCase + setup :build_app + teardown :teardown_app + + test "`rails notes` displays results for default directories and default annotations with aligned line number and annotation tag" do + app_file "app/controllers/some_controller.rb", "# OPTIMIZE: note in app directory" + app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" + app_file "db/some_seeds.rb", "# FIXME: note in db directory" + app_file "lib/some_file.rb", "# TODO: note in lib directory" + app_file "test/some_test.rb", "\n" * 100 + "# FIXME: note in test directory" + + app_file "some_other_dir/blah.rb", "# TODO: note in some_other directory" + + assert_equal <<~OUTPUT, run_notes_command + app/controllers/some_controller.rb: + * [ 1] [OPTIMIZE] note in app directory + + config/initializers/some_initializer.rb: + * [ 1] [TODO] note in config directory + + db/some_seeds.rb: + * [ 1] [FIXME] note in db directory + + lib/some_file.rb: + * [ 1] [TODO] note in lib directory + + test/some_test.rb: + * [101] [FIXME] note in test directory + + OUTPUT + end + + test "`rails notes` displays an empty string when no results were found" do + assert_equal "", run_notes_command + end + + test "`rails notes --annotations` displays results for a single annotation without being prefixed by a tag" do + app_file "db/some_seeds.rb", "# FIXME: note in db directory" + app_file "test/some_test.rb", "# FIXME: note in test directory" + + app_file "app/controllers/some_controller.rb", "# OPTIMIZE: note in app directory" + app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" + + assert_equal <<~OUTPUT, run_notes_command(["--annotations", "FIXME"]) + db/some_seeds.rb: + * [1] note in db directory + + test/some_test.rb: + * [1] note in test directory + + OUTPUT + end + + test "`rails notes --annotations` displays results for multiple annotations being prefixed by a tag" do + app_file "app/controllers/some_controller.rb", "# FOOBAR: note in app directory" + app_file "config/initializers/some_initializer.rb", "# TODO: note in config directory" + app_file "lib/some_file.rb", "# TODO: note in lib directory" + + app_file "test/some_test.rb", "# FIXME: note in test directory" + + assert_equal <<~OUTPUT, run_notes_command(["--annotations", "FOOBAR", "TODO"]) + app/controllers/some_controller.rb: + * [1] [FOOBAR] note in app directory + + config/initializers/some_initializer.rb: + * [1] [TODO] note in config directory + + lib/some_file.rb: + * [1] [TODO] note in lib directory + + OUTPUT + end + + test "displays results from additional directories added to the default directories from a config file" do + app_file "db/some_seeds.rb", "# FIXME: note in db directory" + app_file "lib/some_file.rb", "# TODO: note in lib directory" + app_file "spec/spec_helper.rb", "# TODO: note in spec" + app_file "spec/models/user_spec.rb", "# TODO: note in model spec" + + add_to_config "config.annotations.register_directories \"spec\"" + + assert_equal <<~OUTPUT, run_notes_command + db/some_seeds.rb: + * [1] [FIXME] note in db directory + + lib/some_file.rb: + * [1] [TODO] note in lib directory + + spec/models/user_spec.rb: + * [1] [TODO] note in model spec + + spec/spec_helper.rb: + * [1] [TODO] note in spec + + OUTPUT + end + + test "displays results from additional file extensions added to the default extensions from a config file" do + add_to_config "config.assets.precompile = []" + add_to_config %q{ config.annotations.register_extensions("scss", "sass") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ } } + app_file "db/some_seeds.rb", "# FIXME: note in db directory" + app_file "app/assets/stylesheets/application.css.scss", "// TODO: note in scss" + app_file "app/assets/stylesheets/application.css.sass", "// TODO: note in sass" + + assert_equal <<~OUTPUT, run_notes_command + app/assets/stylesheets/application.css.sass: + * [1] [TODO] note in sass + + app/assets/stylesheets/application.css.scss: + * [1] [TODO] note in scss + + db/some_seeds.rb: + * [1] [FIXME] note in db directory + + OUTPUT + end + + private + def run_notes_command(args = []) + rails "notes", args + end +end diff --git a/railties/test/commands/routes_test.rb b/railties/test/commands/routes_test.rb new file mode 100644 index 0000000000..77ed2bda61 --- /dev/null +++ b/railties/test/commands/routes_test.rb @@ -0,0 +1,175 @@ +# frozen_string_literal: true + +require "isolation/abstract_unit" +require "rails/command" +require "rails/commands/routes/routes_command" +require "io/console/size" + +class Rails::Command::RoutesTest < ActiveSupport::TestCase + setup :build_app + teardown :teardown_app + + test "singular resource output in rails routes" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + resource :post + end + RUBY + + expected_output = [" Prefix Verb URI Pattern Controller#Action", + " new_post GET /post/new(.:format) posts#new", + "edit_post GET /post/edit(.:format) posts#edit", + " post GET /post(.:format) posts#show", + " PATCH /post(.:format) posts#update", + " PUT /post(.:format) posts#update", + " DELETE /post(.:format) posts#destroy", + " POST /post(.:format) posts#create\n"].join("\n") + + output = run_routes_command(["-c", "PostController"]) + assert_equal expected_output, output + end + + test "rails routes with global search key" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get '/cart', to: 'cart#show' + post '/cart', to: 'cart#create' + get '/basketballs', to: 'basketball#index' + end + RUBY + + output = run_routes_command(["-g", "show"]) + assert_equal <<~MESSAGE, output + Prefix Verb URI Pattern Controller#Action + cart GET /cart(.:format) cart#show + rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show + rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show + rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show + MESSAGE + + output = run_routes_command(["-g", "POST"]) + assert_equal <<~MESSAGE, output + Prefix Verb URI Pattern Controller#Action + POST /cart(.:format) cart#create + rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create + MESSAGE + + output = run_routes_command(["-g", "basketballs"]) + assert_equal " Prefix Verb URI Pattern Controller#Action\n" \ + "basketballs GET /basketballs(.:format) basketball#index\n", output + end + + test "rails routes with controller search key" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get '/cart', to: 'cart#show' + get '/basketball', to: 'basketball#index' + end + RUBY + + output = run_routes_command(["-c", "cart"]) + assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output + + output = run_routes_command(["-c", "Cart"]) + assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output + + output = run_routes_command(["-c", "CartController"]) + assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output + end + + test "rails routes with namespaced controller search key" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + namespace :admin do + resource :post + end + end + RUBY + + expected_output = [" Prefix Verb URI Pattern Controller#Action", + " new_admin_post GET /admin/post/new(.:format) admin/posts#new", + "edit_admin_post GET /admin/post/edit(.:format) admin/posts#edit", + " admin_post GET /admin/post(.:format) admin/posts#show", + " PATCH /admin/post(.:format) admin/posts#update", + " PUT /admin/post(.:format) admin/posts#update", + " DELETE /admin/post(.:format) admin/posts#destroy", + " POST /admin/post(.:format) admin/posts#create\n"].join("\n") + + output = run_routes_command(["-c", "Admin::PostController"]) + assert_equal expected_output, output + + output = run_routes_command(["-c", "PostController"]) + assert_equal expected_output, output + end + + test "rails routes displays message when no routes are defined" do + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + end + RUBY + + assert_equal <<~MESSAGE, run_routes_command + Prefix Verb URI Pattern Controller#Action + rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show + rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show + rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show + update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update + rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create + MESSAGE + end + + test "rails routes with expanded option" do + begin + previous_console_winsize = IO.console.winsize + IO.console.winsize = [0, 27] + + app_file "config/routes.rb", <<-RUBY + Rails.application.routes.draw do + get '/cart', to: 'cart#show' + end + RUBY + + output = run_routes_command(["--expanded"]) + + assert_equal <<~MESSAGE, output + --[ Route 1 ]-------------- + Prefix | cart + Verb | GET + URI | /cart(.:format) + Controller#Action | cart#show + --[ Route 2 ]-------------- + Prefix | rails_service_blob + Verb | GET + URI | /rails/active_storage/blobs/:signed_id/*filename(.:format) + Controller#Action | active_storage/blobs#show + --[ Route 3 ]-------------- + 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 4 ]-------------- + Prefix | rails_disk_service + Verb | GET + URI | /rails/active_storage/disk/:encoded_key/*filename(.:format) + Controller#Action | active_storage/disk#show + --[ Route 5 ]-------------- + Prefix | update_rails_disk_service + Verb | PUT + URI | /rails/active_storage/disk/:encoded_token(.:format) + Controller#Action | active_storage/disk#update + --[ Route 6 ]-------------- + Prefix | rails_direct_uploads + Verb | POST + URI | /rails/active_storage/direct_uploads(.:format) + Controller#Action | active_storage/direct_uploads#create + MESSAGE + ensure + IO.console.winsize = previous_console_winsize + end + end + + private + def run_routes_command(args = []) + rails "routes", args + end +end diff --git a/railties/test/commands/server_test.rb b/railties/test/commands/server_test.rb index 33715ea75f..e5b1da6ea4 100644 --- a/railties/test/commands/server_test.rb +++ b/railties/test/commands/server_test.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true -require "abstract_unit" +require "isolation/abstract_unit" require "env_helpers" require "rails/command" require "rails/commands/server/server_command" -class Rails::ServerTest < ActiveSupport::TestCase +class Rails::Command::ServerCommandTest < ActiveSupport::TestCase include EnvHelpers def test_environment_with_server_option - args = ["thin", "-e", "production"] + args = ["-u", "thin", "-e", "production"] options = parse_arguments(args) assert_equal "production", options[:environment] assert_equal "thin", options[:server] @@ -22,6 +22,24 @@ class Rails::ServerTest < ActiveSupport::TestCase assert_nil options[:server] end + def test_explicit_using_option + args = ["-u", "thin"] + options = parse_arguments(args) + assert_equal "thin", options[:server] + end + + def test_using_server_mistype + assert_match(/Could not find server "tin". Maybe you meant "thin"?/, run_command("--using", "tin")) + end + + def test_using_positional_argument_deprecation + assert_match(/DEPRECATION WARNING/, run_command("tin")) + end + + def test_using_known_server_that_isnt_in_the_gemfile + assert_match(/Could not load server "unicorn". Maybe you need to the add it to the Gemfile/, run_command("-u", "unicorn")) + end + def test_daemon_with_option args = ["-d"] options = parse_arguments(args) @@ -35,7 +53,7 @@ class Rails::ServerTest < ActiveSupport::TestCase end def test_server_option_without_environment - args = ["thin"] + args = ["-u", "thin"] with_rack_env nil do with_rails_env nil do options = parse_arguments(args) @@ -72,6 +90,15 @@ class Rails::ServerTest < ActiveSupport::TestCase def test_environment_with_host switch_env "HOST", "1.2.3.4" do + assert_deprecated do + options = parse_arguments + assert_equal "1.2.3.4", options[:Host] + end + end + end + + def test_environment_with_binding + switch_env "BINDING", "1.2.3.4" do options = parse_arguments assert_equal "1.2.3.4", options[:Host] end @@ -116,10 +143,22 @@ class Rails::ServerTest < ActiveSupport::TestCase options = parse_arguments(args) assert_equal true, options[:log_stdout] + args = ["-e", "development", "-d"] + options = parse_arguments(args) + assert_equal false, options[:log_stdout] + args = ["-e", "production"] options = parse_arguments(args) assert_equal false, options[:log_stdout] + args = ["-e", "development", "--no-log-to-stdout"] + options = parse_arguments(args) + assert_equal false, options[:log_stdout] + + args = ["-e", "production", "--log-to-stdout"] + options = parse_arguments(args) + assert_equal true, options[:log_stdout] + with_rack_env "development" do args = [] options = parse_arguments(args) @@ -178,7 +217,7 @@ class Rails::ServerTest < ActiveSupport::TestCase assert_equal 3000, options[:Port] end - switch_env "HOST", "1.2.3.4" do + switch_env "BINDING", "1.2.3.4" do args = ["-b", "127.0.0.1"] options = parse_arguments(args) assert_equal "127.0.0.1", options[:Host] @@ -197,6 +236,11 @@ class Rails::ServerTest < ActiveSupport::TestCase server_options = parse_arguments(["--port=3001"]) assert_equal [:Port], server_options[:user_supplied_options] + + switch_env "BINDING", "1.2.3.4" do + server_options = parse_arguments + assert_equal [:Host], server_options[:user_supplied_options] + end end def test_default_options @@ -213,15 +257,27 @@ class Rails::ServerTest < ActiveSupport::TestCase args = %w(-p 4567 -b 127.0.0.1 -c dummy_config.ru -d -e test -P tmp/server.pid -C) ARGV.replace args - options = parse_arguments(args) - expected = "bin/rails server -p 4567 -b 127.0.0.1 -c dummy_config.ru -d -e test -P tmp/server.pid -C --restart" + expected = "bin/rails server -p 4567 -b 127.0.0.1 -c dummy_config.ru -d -e test -P tmp/server.pid -C --restart" - assert_equal expected, options[:restart_cmd] + assert_equal expected, parse_arguments(args)[:restart_cmd] ensure ARGV.replace original_args end + def test_served_url + args = %w(-u webrick -b 127.0.0.1 -p 4567) + server = Rails::Server.new(parse_arguments(args)) + assert_equal "http://127.0.0.1:4567", server.served_url + end + private + def run_command(*args) + build_app + rails "server", *args + ensure + teardown_app + end + def parse_arguments(args = []) Rails::Command::ServerCommand.new([], args).server_options end diff --git a/railties/test/engine_test.rb b/railties/test/engine_test.rb index 4bd8a07085..19379e200c 100644 --- a/railties/test/engine_test.rb +++ b/railties/test/engine_test.rb @@ -11,7 +11,7 @@ class EngineTest < ActiveSupport::TestCase end end - assert !engine.routes? + assert_not_predicate engine, :routes? end def test_application_can_be_subclassed diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index f421207025..a54a6dbc28 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -403,7 +403,7 @@ class ActionsTest < Rails::Generators::TestCase content.gsub!(/^ \#.*\n/, "") content.gsub!(/^\n/, "") - File.open(route_path, "wb") { |file| file.write(content) } + File.write(route_path, content) routes = <<-F Rails.application.routes.draw do diff --git a/railties/test/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb index 4815cf6362..9c523ad372 100644 --- a/railties/test/generators/api_app_generator_test.rb +++ b/railties/test/generators/api_app_generator_test.rb @@ -13,7 +13,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase Rails.application = TestApp::Application super - Kernel::silence_warnings do + Kernel.silence_warnings do Thor::Base.shell.send(:attr_accessor, :always_force) @shell = Thor::Base.shell.new @shell.send(:always_force=, true) @@ -63,6 +63,23 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase end end + def test_generator_if_skip_action_mailer_is_given + run_generator [destination_root, "--api", "--skip-action-mailer"] + assert_file "config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/ + assert_file "config/environments/development.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + assert_file "config/environments/test.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + assert_file "config/environments/production.rb" do |content| + assert_no_match(/config\.action_mailer/, content) + end + assert_no_directory "app/mailers" + assert_no_directory "test/mailers" + assert_no_directory "app/views" + end + def test_app_update_does_not_generate_unnecessary_config_files run_generator diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index fcb515c606..b0f958091c 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -211,7 +211,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_new_application_doesnt_need_defaults - assert_no_file "config/initializers/new_framework_defaults_5_2.rb" + assert_no_file "config/initializers/new_framework_defaults_6_0.rb" end def test_new_application_load_defaults @@ -219,6 +219,8 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator [app_root] output = nil + assert_file "#{app_root}/config/application.rb", /\s+config\.load_defaults #{Rails::VERSION::STRING.to_f}/ + Dir.chdir(app_root) do output = `./bin/rails r "puts Rails.application.config.assets.unknown_asset_fallback"` end @@ -257,14 +259,14 @@ class AppGeneratorTest < Rails::Generators::TestCase app_root = File.join(destination_root, "myapp") run_generator [app_root] - assert_no_file "#{app_root}/config/initializers/new_framework_defaults_5_2.rb" + assert_no_file "#{app_root}/config/initializers/new_framework_defaults_6_0.rb" 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/initializers/new_framework_defaults_5_2.rb" + assert_file "#{app_root}/config/initializers/new_framework_defaults_6_0.rb" end end @@ -294,6 +296,51 @@ class AppGeneratorTest < Rails::Generators::TestCase end end + def test_app_update_does_not_generate_yarn_contents_when_bin_yarn_is_not_used + app_root = File.join(destination_root, "myapp") + run_generator [app_root, "--skip-yarn"] + + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_yarn: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_bin_files) } + + assert_no_file "#{app_root}/bin/yarn" + + assert_file "#{app_root}/bin/setup" do |content| + assert_no_match(/system\('bin\/yarn'\)/, content) + end + + assert_file "#{app_root}/bin/update" do |content| + assert_no_match(/system\('bin\/yarn'\)/, content) + end + end + end + + def test_app_update_does_not_generate_assets_initializer_when_skip_sprockets_is_given + app_root = File.join(destination_root, "myapp") + run_generator [app_root, "--skip-sprockets"] + + stub_rails_application(app_root) do + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_sprockets: true }, { destination_root: app_root, shell: @shell } + generator.send(:app_const) + quietly { generator.send(:update_config_files) } + + assert_no_file "#{app_root}/config/initializers/assets.rb" + end + end + + def test_app_update_does_not_generate_spring_contents_when_skip_spring_is_given + 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 + + assert_no_file "#{app_root}/config/spring.rb" + 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"] @@ -308,28 +355,30 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_active_storage_mini_magick_gem - run_generator - assert_file "Gemfile", /^# gem 'mini_magick'/ - 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"] - def test_active_storage_install - command_check = -> command, _ do - @binstub_called ||= 0 - case command - when "active_storage:install" - @binstub_called += 1 - assert_equal 1, @binstub_called, "active_storage:install expected to be called once, but was called #{@binstub_called} times" - end + FileUtils.cd(app_root) do + quietly { system("bin/rails app:update") } end - generator.stub :rails_command, command_check do - generator.stub :bundle_command, nil do - quietly { generator.invoke_all } - end + assert_file "#{app_root}/config/boot.rb" do |content| + assert_no_match(/require 'bootsnap\/setup'/, content) end end + def test_gem_for_active_storage + run_generator + assert_file "Gemfile", /^# gem 'image_processing'/ + end + + def test_gem_for_active_storage_when_skip_active_storage_is_given + run_generator [destination_root, "--skip-active-storage"] + + assert_no_gem "image_processing" + end + def test_app_update_does_not_generate_active_storage_contents_when_skip_active_storage_is_given app_root = File.join(destination_root, "myapp") run_generator [app_root, "--skip-active-storage"] @@ -351,10 +400,6 @@ class AppGeneratorTest < Rails::Generators::TestCase end assert_no_file "#{app_root}/config/storage.yml" - - assert_file "#{app_root}/Gemfile" do |content| - assert_no_match(/gem 'mini_magick'/, content) - end end def test_app_update_does_not_generate_active_storage_contents_when_skip_active_record_is_given @@ -378,9 +423,42 @@ class AppGeneratorTest < Rails::Generators::TestCase end assert_no_file "#{app_root}/config/storage.yml" + end + + def test_app_update_does_not_change_config_target_version + run_generator - assert_file "#{app_root}/Gemfile" do |content| - assert_no_match(/gem 'mini_magick'/, content) + FileUtils.cd(destination_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/ + end + + def test_app_update_does_not_change_app_name_when_app_name_is_hyphenated_name + app_root = File.join(destination_root, "hyphenated-app") + run_generator [app_root, "-d", "postgresql"] + + assert_file "#{app_root}/config/database.yml" do |content| + assert_match(/hyphenated_app_development/, content) + assert_no_match(/hyphenated-app_development/, content) + end + + assert_file "#{app_root}/config/cable.yml" do |content| + assert_match(/hyphenated_app/, content) + assert_no_match(/hyphenated-app/, content) + end + + FileUtils.cd(app_root) do + quietly { system("bin/rails app:update") } + end + + assert_file "#{app_root}/config/cable.yml" do |content| + assert_match(/hyphenated_app/, content) + assert_no_match(/hyphenated-app/, content) end end @@ -409,13 +487,13 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - def test_config_another_database + def test_config_mysql_database run_generator([destination_root, "-d", "mysql"]) assert_file "config/database.yml", /mysql/ if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcmysql-adapter" else - assert_gem "mysql2", "'~> 0.4.4'" + assert_gem "mysql2", "'>= 0.4.4', '< 0.6.0'" end end @@ -430,7 +508,7 @@ class AppGeneratorTest < Rails::Generators::TestCase if defined?(JRUBY_VERSION) assert_gem "activerecord-jdbcpostgresql-adapter" else - assert_gem "pg", "'~> 0.18'" + assert_gem "pg", "'>= 0.18', '< 2.0'" end end @@ -475,9 +553,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_generator_if_skip_puma_is_given run_generator [destination_root, "--skip-puma"] assert_no_file "config/puma.rb" - assert_file "Gemfile" do |content| - assert_no_match(/puma/, content) - end + assert_no_gem "puma" end def test_generator_has_assets_gems @@ -497,22 +573,18 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "config/application.rb", /#\s+require\s+["']rails\/test_unit\/railtie["']/ - assert_file "Gemfile" do |content| - assert_no_match(/capybara/, content) - assert_no_match(/selenium-webdriver/, content) - assert_no_match(/chromedriver-helper/, content) - end + assert_no_gem "capybara" + assert_no_gem "selenium-webdriver" + assert_no_gem "chromedriver-helper" assert_no_directory("test") end def test_generator_if_skip_system_test_is_given run_generator [destination_root, "--skip-system-test"] - assert_file "Gemfile" do |content| - assert_no_match(/capybara/, content) - assert_no_match(/selenium-webdriver/, content) - assert_no_match(/chromedriver-helper/, content) - end + assert_no_gem "capybara" + assert_no_gem "selenium-webdriver" + assert_no_gem "chromedriver-helper" assert_directory("test") @@ -558,10 +630,8 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_no_match(/javascript_include_tag\s+'application' \%>/, contents) end - assert_file "Gemfile" do |content| - assert_no_match(/coffee-rails/, content) - assert_no_match(/uglifier/, content) - end + assert_no_gem "coffee-rails" + assert_no_gem "uglifier" assert_file "config/environments/production.rb" do |content| assert_no_match(/config\.assets\.js_compressor = :uglifier/, content) @@ -585,9 +655,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_inclusion_of_a_debugger run_generator if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx" - assert_file "Gemfile" do |content| - assert_no_match(/byebug/, content) - end + assert_no_gem "byebug" else assert_gem "byebug" end @@ -655,6 +723,13 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_empty output end + def test_force_option_overwrites_every_file_except_master_key + run_generator [File.join(destination_root, "myapp")] + output = run_generator [File.join(destination_root, "myapp"), "--force"] + assert_match(/force/, output) + assert_no_match("force config/master.key", output) + end + def test_application_name_with_spaces path = File.join(destination_root, "foo bar") @@ -731,9 +806,7 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_called_with(Process, :respond_to?, [[:fork], [:fork]], returns: false) do run_generator - assert_file "Gemfile" do |content| - assert_no_match(/spring/, content) - end + assert_no_gem "spring" end end @@ -741,17 +814,13 @@ class AppGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, "--skip-spring"] assert_no_file "config/spring.rb" - assert_file "Gemfile" do |content| - assert_no_match(/spring/, content) - end + assert_no_gem "spring" end def test_spring_with_dev_option run_generator [destination_root, "--dev"] - assert_file "Gemfile" do |content| - assert_no_match(/spring/, content) - end + assert_no_gem "spring" end def test_webpack_option @@ -796,9 +865,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_generator_if_skip_turbolinks_is_given run_generator [destination_root, "--skip-turbolinks"] - assert_file "Gemfile" do |content| - assert_no_match(/turbolinks/, content) - end + assert_no_gem "turbolinks" assert_file "app/views/layouts/application.html.erb" do |content| assert_no_match(/data-turbolinks-track/, content) end @@ -810,18 +877,23 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_bootsnap run_generator - assert_gem "bootsnap" - assert_file "config/boot.rb" do |content| - assert_match(/require 'bootsnap\/setup'/, content) + unless defined?(JRUBY_VERSION) + assert_gem "bootsnap" + assert_file "config/boot.rb" do |content| + assert_match(/require 'bootsnap\/setup'/, content) + end + else + assert_no_gem "bootsnap" + assert_file "config/boot.rb" do |content| + assert_no_match(/require 'bootsnap\/setup'/, content) + end end end def test_skip_bootsnap run_generator [destination_root, "--skip-bootsnap"] - assert_file "Gemfile" do |content| - assert_no_match(/bootsnap/, content) - end + assert_no_gem "bootsnap" assert_file "config/boot.rb" do |content| assert_no_match(/require 'bootsnap\/setup'/, content) end @@ -830,9 +902,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_bootsnap_with_dev_option run_generator [destination_root, "--dev"] - assert_file "Gemfile" do |content| - assert_no_match(/bootsnap/, content) - end + assert_no_gem "bootsnap" assert_file "config/boot.rb" do |content| assert_no_match(/require 'bootsnap\/setup'/, content) end @@ -845,7 +915,13 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_match(/ruby '#{RUBY_VERSION}'/, content) end assert_file ".ruby-version" do |content| - assert_match(/#{RUBY_VERSION}/, content) + if ENV["RBENV_VERSION"] + assert_match(/#{ENV["RBENV_VERSION"]}/, content) + elsif ENV["rvm_ruby_string"] + assert_match(/#{ENV["rvm_ruby_string"]}/, content) + else + assert_match(/#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}/, content) + end end end @@ -900,7 +976,7 @@ class AppGeneratorTest < Rails::Generators::TestCase template end - sequence = ["git init", "install", "exec spring binstub --all", "active_storage:install", "echo ran after_bundle"] + sequence = ["git init", "install", "exec spring binstub --all", "echo ran after_bundle"] @sequence_step ||= 0 ensure_bundler_first = -> command, options = nil do assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}" @@ -917,7 +993,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end end - assert_equal 5, @sequence_step + assert_equal 4, @sequence_step end def test_gitignore @@ -931,8 +1007,17 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_system_tests_directory_generated run_generator - assert_file("test/system/.keep") assert_directory("test/system") + assert_file("test/system/.keep") + end + + unless Gem.win_platform? + def test_master_key_is_only_readable_by_the_owner + run_generator + + stat = File.stat("config/master.key") + assert_equal "100600", sprintf("%o", stat.mode) + end end private @@ -955,6 +1040,12 @@ class AppGeneratorTest < Rails::Generators::TestCase end end + def assert_no_gem(gem) + assert_file "Gemfile" do |content| + assert_no_match(gem, content) + end + end + def assert_listen_related_configuration assert_gem "listen" assert_gem "spring-watcher-listen" @@ -965,9 +1056,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def assert_no_listen_related_configuration - assert_file "Gemfile" do |content| - assert_no_match(/listen/, content) - end + assert_no_gem "listen" assert_file "config/environments/development.rb" do |content| assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content) diff --git a/railties/test/generators/channel_generator_test.rb b/railties/test/generators/channel_generator_test.rb index e238197eba..e543cc11b8 100644 --- a/railties/test/generators/channel_generator_test.rb +++ b/railties/test/generators/channel_generator_test.rb @@ -76,4 +76,14 @@ class ChannelGeneratorTest < Rails::Generators::TestCase assert_file "app/channels/application_cable/connection.rb" assert_file "app/assets/javascripts/cable.js" end + + def test_channel_suffix_is_not_duplicated + run_generator ["chat_channel"] + + assert_no_file "app/channels/chat_channel_channel.rb" + assert_file "app/channels/chat_channel.rb" + + assert_no_file "app/assets/javascripts/channels/chat_channel.js" + assert_file "app/assets/javascripts/channels/chat.js" + end end diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb index a3218951a6..021004c9b8 100644 --- a/railties/test/generators/controller_generator_test.rb +++ b/railties/test/generators/controller_generator_test.rb @@ -109,4 +109,33 @@ class ControllerGeneratorTest < Rails::Generators::TestCase assert_match(/^ namespace :admin do\n get 'dashboard\/index'\n get 'dashboard\/show'\n end$/, route) end end + + def test_does_not_add_routes_when_action_is_not_specified + run_generator ["admin/dashboard"] + assert_file "config/routes.rb" do |routes| + assert_no_match(/namespace :admin/, routes) + end + end + + def test_controller_suffix_is_not_duplicated + run_generator ["account_controller"] + + assert_no_file "app/controllers/account_controller_controller.rb" + assert_file "app/controllers/account_controller.rb" + + assert_no_file "app/views/account_controller/" + assert_file "app/views/account/" + + assert_no_file "test/controllers/account_controller_controller_test.rb" + assert_file "test/controllers/account_controller_test.rb" + + assert_no_file "app/helpers/account_controller_helper.rb" + assert_file "app/helpers/account_helper.rb" + + assert_no_file "app/assets/javascripts/account_controller.js" + assert_file "app/assets/javascripts/account.js" + + assert_no_file "app/assets/stylesheets/account_controller.css" + assert_file "app/assets/stylesheets/account.css" + end end diff --git a/railties/test/generators/create_migration_test.rb b/railties/test/generators/create_migration_test.rb index 3cb7fd6baa..2ae38045c5 100644 --- a/railties/test/generators/create_migration_test.rb +++ b/railties/test/generators/create_migration_test.rb @@ -70,7 +70,7 @@ class CreateMigrationTest < Rails::Generators::TestCase create_migration assert_match(/identical db\/migrate\/1_create_articles\.rb\n/, invoke!) - assert @migration.identical? + assert_predicate @migration, :identical? end def test_invoke_when_exists_not_identical diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb index c6f7bdeda1..772b4f6f0d 100644 --- a/railties/test/generators/generated_attribute_test.rb +++ b/railties/test/generators/generated_attribute_test.rb @@ -104,25 +104,25 @@ class GeneratedAttributeTest < Rails::Generators::TestCase def test_reference_is_true %w(references belongs_to).each do |attribute_type| - assert create_generated_attribute(attribute_type).reference? + assert_predicate create_generated_attribute(attribute_type), :reference? end end def test_reference_is_false %w(foo bar baz).each do |attribute_type| - assert !create_generated_attribute(attribute_type).reference? + assert_not_predicate create_generated_attribute(attribute_type), :reference? end end def test_polymorphic_reference_is_true %w(references belongs_to).each do |attribute_type| - assert create_generated_attribute("#{attribute_type}{polymorphic}").polymorphic? + assert_predicate create_generated_attribute("#{attribute_type}{polymorphic}"), :polymorphic? end end def test_polymorphic_reference_is_false %w(foo bar baz).each do |attribute_type| - assert !create_generated_attribute("#{attribute_type}{polymorphic}").polymorphic? + assert_not_predicate create_generated_attribute("#{attribute_type}{polymorphic}"), :polymorphic? end end @@ -148,7 +148,7 @@ class GeneratedAttributeTest < Rails::Generators::TestCase att = Rails::Generators::GeneratedAttribute.parse("supplier:references{required}:index") assert_equal "supplier", att.name assert_equal :references, att.type - assert att.has_index? - assert att.required? + assert_predicate att, :has_index? + assert_predicate att, :required? end end diff --git a/railties/test/generators/job_generator_test.rb b/railties/test/generators/job_generator_test.rb index 13276fac65..234ba6dad7 100644 --- a/railties/test/generators/job_generator_test.rb +++ b/railties/test/generators/job_generator_test.rb @@ -35,4 +35,14 @@ class JobGeneratorTest < Rails::Generators::TestCase assert_match(/class ApplicationJob < ActiveJob::Base/, job) end end + + def test_job_suffix_is_not_duplicated + run_generator ["notifier_job"] + + assert_no_file "app/jobs/notifier_job_job.rb" + assert_file "app/jobs/notifier_job.rb" + + assert_no_file "test/jobs/notifier_job_job_test.rb" + assert_file "test/jobs/notifier_job_test.rb" + end end diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index 516aa0704f..8d933e82c3 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -2,7 +2,6 @@ require "generators/generators_test_helper" require "rails/generators/rails/model/model_generator" -require "active_support/core_ext/string/strip" class ModelGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper @@ -379,10 +378,10 @@ class ModelGeneratorTest < Rails::Generators::TestCase def test_required_belongs_to_adds_required_association run_generator ["account", "supplier:references{required}"] - expected_file = <<-FILE.strip_heredoc - class Account < ApplicationRecord - belongs_to :supplier, required: true - end + expected_file = <<~FILE + class Account < ApplicationRecord + belongs_to :supplier, required: true + end FILE assert_file "app/models/account.rb", expected_file end @@ -390,10 +389,10 @@ class ModelGeneratorTest < Rails::Generators::TestCase def test_required_polymorphic_belongs_to_generages_correct_model run_generator ["account", "supplier:references{required,polymorphic}"] - expected_file = <<-FILE.strip_heredoc - class Account < ApplicationRecord - belongs_to :supplier, polymorphic: true, required: true - end + expected_file = <<~FILE + class Account < ApplicationRecord + belongs_to :supplier, polymorphic: true, required: true + end FILE assert_file "app/models/account.rb", expected_file end @@ -401,10 +400,10 @@ class ModelGeneratorTest < Rails::Generators::TestCase def test_required_and_polymorphic_are_order_independent run_generator ["account", "supplier:references{polymorphic.required}"] - expected_file = <<-FILE.strip_heredoc - class Account < ApplicationRecord - belongs_to :supplier, polymorphic: true, required: true - end + expected_file = <<~FILE + class Account < ApplicationRecord + belongs_to :supplier, polymorphic: true, required: true + end FILE assert_file "app/models/account.rb", expected_file end @@ -452,11 +451,11 @@ class ModelGeneratorTest < Rails::Generators::TestCase def test_token_option_adds_has_secure_token run_generator ["user", "token:token", "auth_token:token"] - expected_file = <<-FILE.strip_heredoc - class User < ApplicationRecord - has_secure_token - has_secure_token :auth_token - end + expected_file = <<~FILE + class User < ApplicationRecord + has_secure_token + has_secure_token :auth_token + end FILE assert_file "app/models/user.rb", expected_file end diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index fc7584c175..28ac3611b7 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -82,11 +82,12 @@ class PluginGeneratorTest < Rails::Generators::TestCase end def test_generating_in_full_mode_with_almost_of_all_skip_options - run_generator [destination_root, "--full", "-M", "-O", "-C", "-S", "-T"] + run_generator [destination_root, "--full", "-M", "-O", "-C", "-S", "-T", "--skip-active-storage"] assert_file "bin/rails" do |content| assert_no_match(/\s+require\s+["']rails\/all["']/, content) end assert_file "bin/rails", /#\s+require\s+["']active_record\/railtie["']/ + assert_file "bin/rails", /#\s+require\s+["']active_storage\/engine["']/ assert_file "bin/rails", /#\s+require\s+["']action_mailer\/railtie["']/ assert_file "bin/rails", /#\s+require\s+["']action_cable\/engine["']/ assert_file "bin/rails", /#\s+require\s+["']sprockets\/railtie["']/ @@ -216,12 +217,22 @@ class PluginGeneratorTest < Rails::Generators::TestCase def test_javascripts_generation run_generator [destination_root, "--mountable"] - assert_file "app/assets/javascripts/bukkits/application.js" + assert_file "app/assets/javascripts/bukkits/application.js" do |content| + assert_match "//= require rails-ujs", content + assert_match "//= require activestorage", content + assert_match "//= require_tree .", content + end + assert_file "app/views/layouts/bukkits/application.html.erb" do |content| + assert_match "javascript_include_tag", content + end end def test_skip_javascripts run_generator [destination_root, "--skip-javascript", "--mountable"] assert_no_file "app/assets/javascripts/bukkits/application.js" + assert_file "app/views/layouts/bukkits/application.html.erb" do |content| + assert_no_match "javascript_include_tag", content + end end def test_template_from_dir_pwd @@ -320,8 +331,11 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/ assert_file "app/views/layouts/bukkits/application.html.erb" do |contents| assert_match "<title>Bukkits</title>", contents + assert_match "<%= csrf_meta_tags %>", contents + assert_match "<%= csp_meta_tag %>", contents assert_match(/stylesheet_link_tag\s+['"]bukkits\/application['"]/, contents) assert_match(/javascript_include_tag\s+['"]bukkits\/application['"]/, contents) + assert_match "<%= yield %>", contents end assert_file "test/test_helper.rb" do |content| assert_match(/ActiveRecord::Migrator\.migrations_paths.+\.\.\/test\/dummy\/db\/migrate/, content) diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 29426cd99f..3e631f6021 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -347,7 +347,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase content = File.read(route_path).gsub(/\.routes\.draw do/) do |match| "#{match} |map|" end - File.open(route_path, "wb") { |file| file.write(content) } + File.write(route_path, content) run_generator ["product_line"], behavior: :revoke @@ -364,7 +364,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase content.gsub!(/^ \#.*\n/, "") content.gsub!(/^\n/, "") - File.open(route_path, "wb") { |file| file.write(content) } + File.write(route_path, content) assert_file "config/routes.rb", /\.routes\.draw do\n resources :product_lines\nend\n\z/ run_generator ["product_line"], behavior: :revoke diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index 29528825b8..aa577e4234 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -9,7 +9,7 @@ module SharedGeneratorTests super Rails::Generators::AppGenerator.instance_variable_set("@desc", nil) - Kernel::silence_warnings do + Kernel.silence_warnings do Thor::Base.shell.send(:attr_accessor, :always_force) @shell = Thor::Base.shell.new @shell.send(:always_force=, true) @@ -245,7 +245,6 @@ module SharedGeneratorTests end assert_no_file "#{application_path}/config/storage.yml" - assert_no_directory "#{application_path}/db/migrate" assert_no_directory "#{application_path}/storage" assert_no_directory "#{application_path}/tmp/storage" @@ -276,7 +275,6 @@ module SharedGeneratorTests end assert_no_file "#{application_path}/config/storage.yml" - assert_no_directory "#{application_path}/db/migrate" assert_no_directory "#{application_path}/storage" assert_no_directory "#{application_path}/tmp/storage" diff --git a/railties/test/generators/test_runner_in_engine_test.rb b/railties/test/generators/test_runner_in_engine_test.rb index 0e15b5e388..bd102a32b5 100644 --- a/railties/test/generators/test_runner_in_engine_test.rb +++ b/railties/test/generators/test_runner_in_engine_test.rb @@ -19,7 +19,7 @@ class TestRunnerInEngineTest < ActiveSupport::TestCase create_test_file "post", pass: false output = run_test_command("test/post_test.rb") - expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth \[[^\]]+test/post_test\.rb:6\]:\nwups!\n\nbin/rails test test/post_test\.rb:4} + expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth \[[^\]]+test/post_test\.rb:6\]:\nwups!\n\nrails test test/post_test\.rb:4} assert_match expect, output end diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb index 1735804664..f98c1f78f7 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -33,7 +33,7 @@ class GeneratorsTest < Rails::Generators::TestCase def test_generator_suggestions name = :migrationz output = capture(:stdout) { Rails::Generators.invoke name } - assert_match "Maybe you meant 'migration'", output + assert_match 'Maybe you meant "migration"?', output end def test_generator_suggestions_except_en_locale @@ -43,18 +43,12 @@ class GeneratorsTest < Rails::Generators::TestCase I18n.default_locale = :ja name = :tas output = capture(:stdout) { Rails::Generators.invoke name } - assert_match "Maybe you meant 'task', 'job' or", output + assert_match 'Maybe you meant "task"?', output ensure I18n.available_locales = orig_available_locales I18n.default_locale = orig_default_locale end - def test_generator_multiple_suggestions - name = :tas - output = capture(:stdout) { Rails::Generators.invoke name } - assert_match "Maybe you meant 'task', 'job' or", output - end - def test_help_when_a_generator_with_required_arguments_is_invoked_without_arguments output = capture(:stdout) { Rails::Generators.invoke :model, [] } assert_match(/Description:/, output) @@ -64,7 +58,7 @@ class GeneratorsTest < Rails::Generators::TestCase assert File.exist?(File.join(@path, "generators", "model_generator.rb")) assert_called_with(Rails::Generators::ModelGenerator, :start, [["Account"], {}]) do warnings = capture(:stderr) { Rails::Generators.invoke :model, ["Account"] } - assert warnings.empty? + assert_empty warnings end end diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 6568a356d6..516c457e48 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -14,6 +14,7 @@ require "bundler/setup" unless defined?(Bundler) require "active_support" require "active_support/testing/autorun" require "active_support/testing/stream" +require "active_support/testing/method_call_assertions" require "active_support/test_case" RAILS_FRAMEWORK_ROOT = File.expand_path("../../..", __dir__) @@ -38,7 +39,12 @@ module TestHelpers end def app_path(*args) - tmp_path(*%w[app] + args) + path = tmp_path(*%w[app] + args) + if block_given? + yield path + else + path + end end def framework_path @@ -107,22 +113,57 @@ module TestHelpers end end - File.open("#{app_path}/config/database.yml", "w") do |f| - f.puts <<-YAML - default: &default - adapter: sqlite3 - pool: 5 - timeout: 5000 - development: - <<: *default - database: db/development.sqlite3 - test: - <<: *default - database: db/test.sqlite3 - production: - <<: *default - database: db/production.sqlite3 - YAML + if options[:multi_db] + File.open("#{app_path}/config/database.yml", "w") do |f| + f.puts <<-YAML + default: &default + adapter: sqlite3 + pool: 5 + timeout: 5000 + development: + primary: + <<: *default + database: db/development.sqlite3 + animals: + <<: *default + database: db/development_animals.sqlite3 + migrations_paths: db/animals_migrate + test: + primary: + <<: *default + database: db/test.sqlite3 + animals: + <<: *default + database: db/test_animals.sqlite3 + migrations_paths: db/animals_migrate + production: + primary: + <<: *default + database: db/production.sqlite3 + animals: + <<: *default + database: db/production_animals.sqlite3 + migrations_paths: db/animals_migrate + YAML + end + else + File.open("#{app_path}/config/database.yml", "w") do |f| + f.puts <<-YAML + default: &default + adapter: sqlite3 + pool: 5 + timeout: 5000 + development: + <<: *default + database: db/development.sqlite3 + test: + <<: *default + database: db/test.sqlite3 + production: + <<: *default + database: db/production.sqlite3 + YAML + end end add_to_config <<-RUBY @@ -390,6 +431,7 @@ class ActiveSupport::TestCase include TestHelpers::Rack include TestHelpers::Generation include ActiveSupport::Testing::Stream + include ActiveSupport::Testing::MethodCallAssertions def frozen_error_class Object.const_defined?(:FrozenError) ? FrozenError : RuntimeError diff --git a/railties/test/minitest/rails_plugin_test.rb b/railties/test/minitest/rails_plugin_test.rb new file mode 100644 index 0000000000..7c3a2022a9 --- /dev/null +++ b/railties/test/minitest/rails_plugin_test.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +require "abstract_unit" + +class Minitest::RailsPluginTest < ActiveSupport::TestCase + setup do + @options = Minitest.process_args [] + @output = StringIO.new("".encode("UTF-8")) + end + + test "default reporters are replaced" do + with_reporter Minitest::CompositeReporter.new do |reporter| + reporter << Minitest::SummaryReporter.new(@output, @options) + reporter << Minitest::ProgressReporter.new(@output, @options) + reporter << Minitest::Reporter.new(@output, @options) + + Minitest.plugin_rails_init({}) + + assert_equal 3, reporter.reporters.count + assert reporter.reporters.any? { |candidate| candidate.kind_of?(Minitest::SuppressedSummaryReporter) } + assert reporter.reporters.any? { |candidate| candidate.kind_of?(::Rails::TestUnitReporter) } + assert reporter.reporters.any? { |candidate| candidate.kind_of?(Minitest::Reporter) } + end + end + + test "no custom reporters are added if nothing to replace" do + with_reporter Minitest::CompositeReporter.new do |reporter| + Minitest.plugin_rails_init({}) + + assert_empty reporter.reporters + end + end + + private + def with_reporter(reporter) + old_reporter, Minitest.reporter = Minitest.reporter, reporter + + yield reporter + ensure + Minitest.reporter = old_reporter + end +end diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb index 854b4448a4..9f5bb37c20 100644 --- a/railties/test/paths_test.rb +++ b/railties/test/paths_test.rb @@ -104,7 +104,7 @@ class PathsTest < ActiveSupport::TestCase File.stub(:exist?, true) do @root.add "app", with: "/app" @root["app"].autoload_once! - assert @root["app"].autoload_once? + assert_predicate @root["app"], :autoload_once? assert_includes @root.autoload_once, @root["app"].expanded.first end end @@ -112,17 +112,17 @@ class PathsTest < ActiveSupport::TestCase test "it is possible to remove a path that should be autoloaded only once" do @root["app"] = "/app" @root["app"].autoload_once! - assert @root["app"].autoload_once? + assert_predicate @root["app"], :autoload_once? @root["app"].skip_autoload_once! - assert !@root["app"].autoload_once? + assert_not_predicate @root["app"], :autoload_once? assert_not_includes @root.autoload_once, @root["app"].expanded.first end test "it is possible to add a path without assignment and specify it should be loaded only once" do File.stub(:exist?, true) do @root.add "app", with: "/app", autoload_once: true - assert @root["app"].autoload_once? + assert_predicate @root["app"], :autoload_once? assert_includes @root.autoload_once, "/app" end end @@ -130,7 +130,7 @@ class PathsTest < ActiveSupport::TestCase test "it is possible to add multiple paths without assignment and specify it should be loaded only once" do File.stub(:exist?, true) do @root.add "app", with: ["/app", "/app2"], autoload_once: true - assert @root["app"].autoload_once? + assert_predicate @root["app"], :autoload_once? assert_includes @root.autoload_once, "/app" assert_includes @root.autoload_once, "/app2" end @@ -158,7 +158,7 @@ class PathsTest < ActiveSupport::TestCase File.stub(:exist?, true) do @root["app"] = "/app" @root["app"].eager_load! - assert @root["app"].eager_load? + assert_predicate @root["app"], :eager_load? assert_includes @root.eager_load, @root["app"].to_a.first end end @@ -166,17 +166,17 @@ class PathsTest < ActiveSupport::TestCase test "it is possible to skip a path from eager loading" do @root["app"] = "/app" @root["app"].eager_load! - assert @root["app"].eager_load? + assert_predicate @root["app"], :eager_load? @root["app"].skip_eager_load! - assert !@root["app"].eager_load? + assert_not_predicate @root["app"], :eager_load? assert_not_includes @root.eager_load, @root["app"].to_a.first end test "it is possible to add a path without assignment and mark it as eager" do File.stub(:exist?, true) do @root.add "app", with: "/app", eager_load: true - assert @root["app"].eager_load? + assert_predicate @root["app"], :eager_load? assert_includes @root.eager_load, "/app" end end @@ -184,7 +184,7 @@ class PathsTest < ActiveSupport::TestCase test "it is possible to add multiple paths without assignment and mark them as eager" do File.stub(:exist?, true) do @root.add "app", with: ["/app", "/app2"], eager_load: true - assert @root["app"].eager_load? + assert_predicate @root["app"], :eager_load? assert_includes @root.eager_load, "/app" assert_includes @root.eager_load, "/app2" end @@ -193,8 +193,8 @@ class PathsTest < ActiveSupport::TestCase test "it is possible to create a path without assignment and mark it both as eager and load once" do File.stub(:exist?, true) do @root.add "app", with: "/app", eager_load: true, autoload_once: true - assert @root["app"].eager_load? - assert @root["app"].autoload_once? + assert_predicate @root["app"], :eager_load? + assert_predicate @root["app"], :autoload_once? assert_includes @root.eager_load, "/app" assert_includes @root.autoload_once, "/app" end @@ -254,7 +254,7 @@ class PathsTest < ActiveSupport::TestCase test "a path can be added to the load path on creation" do File.stub(:exist?, true) do @root.add "app", with: "/app", load_path: true - assert @root["app"].load_path? + assert_predicate @root["app"], :load_path? assert_equal ["/app"], @root.load_paths end end @@ -271,7 +271,7 @@ class PathsTest < ActiveSupport::TestCase test "a path can be marked as autoload on creation" do File.stub(:exist?, true) do @root.add "app", with: "/app", autoload: true - assert @root["app"].autoload? + assert_predicate @root["app"], :autoload? assert_equal ["/app"], @root.autoload_paths end end diff --git a/railties/test/rack_logger_test.rb b/railties/test/rack_logger_test.rb index e47f30d5b6..6e8f333e1d 100644 --- a/railties/test/rack_logger_test.rb +++ b/railties/test/rack_logger_test.rb @@ -14,14 +14,21 @@ module Rails attr_reader :logger - def initialize(logger = NULL, taggers = nil, &block) - super(->(_) { block.call; [200, {}, []] }, taggers) + def initialize(logger = NULL, app: nil, taggers: nil, &block) + app ||= ->(_) { block.call; [200, {}, []] } + super(app, taggers) @logger = logger end def development?; false; end end + class TestApp < Struct.new(:response) + def call(_env) + response + end + end + Subscriber = Struct.new(:starts, :finishes) do def initialize(starts = [], finishes = []) super @@ -72,6 +79,17 @@ module Rails end end end + + def test_logger_does_not_mutate_app_return + response = [].freeze + app = TestApp.new(response) + logger = TestLogger.new(app: app) + assert_no_changes("response") do + assert_nothing_raised do + logger.call("REQUEST_METHOD" => "GET") + end + end + end end end end diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb index 43b60b9144..50522c1be6 100644 --- a/railties/test/rails_info_test.rb +++ b/railties/test/rails_info_test.rb @@ -9,7 +9,7 @@ class InfoTest < ActiveSupport::TestCase property("Bogus") { raise } end end - assert !property_defined?("Bogus") + assert_not property_defined?("Bogus") end def test_property_with_string diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 339a56c34f..4ac8f8d741 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -34,7 +34,7 @@ module RailtiesTest def migrations migration_root = File.expand_path(ActiveRecord::Migrator.migrations_paths.first, app_path) - ActiveRecord::Migrator.migrations(migration_root) + ActiveRecord::MigrationContext.new(migration_root).migrations end test "serving sprocket's assets" do @@ -226,7 +226,7 @@ module RailtiesTest require "rdoc/task" require "rake/testtask" Rails.application.load_tasks - assert !Rake::Task.task_defined?("bukkits:install:migrations") + assert_not Rake::Task.task_defined?("bukkits:install:migrations") end test "puts its lib directory on load path" do @@ -570,7 +570,6 @@ YAML get("/arunagw") assert_equal "arunagw", last_response.body - end test "it provides routes as default endpoint" do @@ -745,7 +744,7 @@ YAML assert_equal "bukkits", Bukkits::Engine.engine_name assert_equal Bukkits.railtie_namespace, Bukkits::Engine assert ::Bukkits::MyMailer.method_defined?(:foo_url) - assert !::Bukkits::MyMailer.method_defined?(:bar_url) + assert_not ::Bukkits::MyMailer.method_defined?(:bar_url) get("/bukkits/from_app") assert_equal "false", last_response.body diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb index 359ab0fdae..7c3d1e3759 100644 --- a/railties/test/railties/railtie_test.rb +++ b/railties/test/railties/railtie_test.rb @@ -65,7 +65,7 @@ module RailtiesTest test "railtie can add to_prepare callbacks" do $to_prepare = false class Foo < Rails::Railtie ; config.to_prepare { $to_prepare = true } ; end - assert !$to_prepare + assert_not $to_prepare require "#{app_path}/config/environment" require "rack/test" extend Rack::Test::Methods @@ -91,7 +91,7 @@ module RailtiesTest test "railtie can add after_initialize callbacks" do $after_initialize = false class Foo < Rails::Railtie ; config.after_initialize { $after_initialize = true } ; end - assert !$after_initialize + assert_not $after_initialize require "#{app_path}/config/environment" assert $after_initialize end @@ -107,7 +107,7 @@ module RailtiesTest require "#{app_path}/config/environment" - assert !$ran_block + assert_not $ran_block require "rake" require "rake/testtask" require "rdoc/task" @@ -151,7 +151,7 @@ module RailtiesTest require "#{app_path}/config/environment" - assert !$ran_block + assert_not $ran_block Rails.application.load_generators assert $ran_block end @@ -167,7 +167,7 @@ module RailtiesTest require "#{app_path}/config/environment" - assert !$ran_block + assert_not $ran_block Rails.application.load_console assert $ran_block end @@ -183,7 +183,7 @@ module RailtiesTest require "#{app_path}/config/environment" - assert !$ran_block + assert_not $ran_block Rails.application.load_runner assert $ran_block end @@ -197,7 +197,7 @@ module RailtiesTest end end - assert !$ran_block + assert_not $ran_block require "#{app_path}/config/environment" assert $ran_block end diff --git a/railties/test/test_unit/reporter_test.rb b/railties/test/test_unit/reporter_test.rb index ad852d0f35..81b7ab19a1 100644 --- a/railties/test/test_unit/reporter_test.rb +++ b/railties/test/test_unit/reporter_test.rb @@ -18,7 +18,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase @reporter.record(failed_test) @reporter.report - assert_match %r{^bin/rails test .*test/test_unit/reporter_test\.rb:\d+$}, @output.string + assert_match %r{^rails test .*test/test_unit/reporter_test\.rb:\d+$}, @output.string assert_rerun_snippet_count 1 end @@ -64,7 +64,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase @reporter.record(failed_test) @reporter.report - expect = %r{\AF\n\nFailure:\nTestUnitReporterTest::ExampleTest#woot \[[^\]]+\]:\nboo\n\nbin/rails test test/test_unit/reporter_test\.rb:\d+\n\n\z} + expect = %r{\AF\n\nFailure:\nTestUnitReporterTest::ExampleTest#woot \[[^\]]+\]:\nboo\n\nrails test test/test_unit/reporter_test\.rb:\d+\n\n\z} assert_match expect, @output.string end @@ -72,7 +72,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase @reporter.record(errored_test) @reporter.report - expect = %r{\AE\n\nError:\nTestUnitReporterTest::ExampleTest#woot:\nArgumentError: wups\n \n\nbin/rails test .*test/test_unit/reporter_test\.rb:\d+\n\n\z} + expect = %r{\AE\n\nError:\nTestUnitReporterTest::ExampleTest#woot:\nArgumentError: wups\n \n\nrails test .*test/test_unit/reporter_test\.rb:\d+\n\n\z} assert_match expect, @output.string end @@ -81,7 +81,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase verbose.record(skipped_test) verbose.report - expect = %r{\ATestUnitReporterTest::ExampleTest#woot = 10\.00 s = S\n\n\nSkipped:\nTestUnitReporterTest::ExampleTest#woot \[[^\]]+\]:\nskipchurches, misstemples\n\nbin/rails test test/test_unit/reporter_test\.rb:\d+\n\n\z} + expect = %r{\ATestUnitReporterTest::ExampleTest#woot = 10\.00 s = S\n\n\nSkipped:\nTestUnitReporterTest::ExampleTest#woot \[[^\]]+\]:\nskipchurches, misstemples\n\nrails test test/test_unit/reporter_test\.rb:\d+\n\n\z} assert_match expect, @output.string end @@ -159,11 +159,11 @@ class TestUnitReporterTest < ActiveSupport::TestCase private def assert_rerun_snippet_count(snippet_count) - assert_equal snippet_count, @output.string.scan(%r{^bin/rails test }).size + assert_equal snippet_count, @output.string.scan(%r{^rails test }).size end def failed_test - ft = ExampleTest.new(:woot) + ft = Minitest::Result.from(ExampleTest.new(:woot)) ft.failures << begin raise Minitest::Assertion, "boo" rescue Minitest::Assertion => e @@ -176,17 +176,17 @@ class TestUnitReporterTest < ActiveSupport::TestCase error = ArgumentError.new("wups") error.set_backtrace([ "some_test.rb:4" ]) - et = ExampleTest.new(:woot) + et = Minitest::Result.from(ExampleTest.new(:woot)) et.failures << Minitest::UnexpectedError.new(error) et end def passing_test - ExampleTest.new(:woot) + Minitest::Result.from(ExampleTest.new(:woot)) end def skipped_test - st = ExampleTest.new(:woot) + st = Minitest::Result.from(ExampleTest.new(:woot)) st.failures << begin raise Minitest::Skip, "skipchurches, misstemples" rescue Minitest::Assertion => e |