diff options
Diffstat (limited to 'railties/test/application')
26 files changed, 586 insertions, 287 deletions
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 |