diff options
Diffstat (limited to 'railties')
36 files changed, 298 insertions, 94 deletions
diff --git a/railties/.gitignore b/railties/.gitignore index 80dd262d2f..c08562e016 100644 --- a/railties/.gitignore +++ b/railties/.gitignore @@ -1 +1,5 @@ -log/ +/log/ +/test/500.html +/test/fixtures/tmp/ +/test/initializer/root/log/ +/tmp/ diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index b3b35307e3..f1e16ec50f 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,16 @@ +## Rails 6.0.0.alpha (Unreleased) ## + +* Rails 6 requires Ruby 2.4.1 or newer. + + *Jeremy Daer* + +* Fix minitest rails plugin. + + The custom reporters are added only if needed. + + This will fix conflicts with others plugins. + + *Kevin Robatel* Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/railties/CHANGELOG.md) for previous changes. diff --git a/railties/lib/minitest/rails_plugin.rb b/railties/lib/minitest/rails_plugin.rb index 6901b0bbc8..7193abbc33 100644 --- a/railties/lib/minitest/rails_plugin.rb +++ b/railties/lib/minitest/rails_plugin.rb @@ -43,10 +43,15 @@ module Minitest Minitest.backtrace_filter = ::Rails.backtrace_cleaner if ::Rails.respond_to?(:backtrace_cleaner) end + # Suppress summary reports when outputting inline rerun snippets. + if reporter.reporters.reject! { |reporter| reporter.kind_of?(SummaryReporter) } + reporter << SuppressedSummaryReporter.new(options[:io], options) + end + # Replace progress reporter for colors. - reporter.reporters.delete_if { |reporter| reporter.kind_of?(SummaryReporter) || reporter.kind_of?(ProgressReporter) } - reporter << SuppressedSummaryReporter.new(options[:io], options) - reporter << ::Rails::TestUnitReporter.new(options[:io], options) + if reporter.reporters.reject! { |reporter| reporter.kind_of?(ProgressReporter) } + reporter << ::Rails::TestUnitReporter.new(options[:io], options) + end end # Backwardscompatibility with Rails 5.0 generated plugin test scripts diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index 2c00d92f8f..84595342b2 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -242,7 +242,11 @@ module Rails end def content_security_policy(&block) - @content_security_policy ||= ActionDispatch::ContentSecurityPolicy.new(&block) + if block_given? + @content_security_policy = ActionDispatch::ContentSecurityPolicy.new(&block) + else + @content_security_policy + end end class Custom #:nodoc: diff --git a/railties/lib/rails/application/default_middleware_stack.rb b/railties/lib/rails/application/default_middleware_stack.rb index 73c7defe7f..433a7ab41f 100644 --- a/railties/lib/rails/application/default_middleware_stack.rb +++ b/railties/lib/rails/application/default_middleware_stack.rb @@ -70,7 +70,8 @@ module Rails middleware.use ::Rack::Head middleware.use ::Rack::ConditionalGet middleware.use ::Rack::ETag, "no-cache" - middleware.use ::Rack::TempfileReaper + + middleware.use ::Rack::TempfileReaper unless config.api_only end end diff --git a/railties/lib/rails/command.rb b/railties/lib/rails/command.rb index 812e846837..078e9f937f 100644 --- a/railties/lib/rails/command.rb +++ b/railties/lib/rails/command.rb @@ -4,7 +4,6 @@ require "active_support" require "active_support/dependencies/autoload" require "active_support/core_ext/enumerable" require "active_support/core_ext/object/blank" -require "active_support/core_ext/hash/transform_values" require "thor" diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 3362bf629a..d85bbfb03e 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "active_support/core_ext/string/strip" + module Rails module Generators module Actions diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 863a914912..e1889979d7 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -2,7 +2,6 @@ require "fileutils" require "digest/md5" -require "active_support/core_ext/string/strip" require "rails/version" unless defined?(Rails::VERSION) require "open-uri" require "uri" diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 98fcc95964..d6732f8ff1 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -31,12 +31,8 @@ module Rails end end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - attr_reader :file_name - private + attr_reader :file_name # FIXME: We are avoiding to use alias because a bug on thor that make # this method public and add it to the task list. diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 72b9044858..5ee9ae05e3 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -248,7 +248,7 @@ module Rails RESERVED_NAMES = %w[application destroy plugin runner test] class AppGenerator < AppBase # :nodoc: - WEBPACKS = %w( react vue angular elm ) + WEBPACKS = %w( react vue angular elm stimulus ) add_shared_options_for "application" @@ -389,9 +389,13 @@ module Rails end end - def delete_application_layout_file_if_api_option + def delete_app_views_if_api_option if options[:api] - remove_file "app/views/layouts/application.html.erb" + if options[:skip_action_mailer] + remove_dir "app/views" + else + remove_file "app/views/layouts/application.html.erb" + end end end diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt index 52d68cc77c..c918b57eca 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt @@ -3,6 +3,13 @@ require_relative '../config/environment' require 'rails/test_help' class ActiveSupport::TestCase + # Run tests in parallel with specified workers +<% if defined?(JRUBY_VERSION) -%> + parallelize(workers: 2, with: :threads) +<%- else -%> + parallelize(workers: 2) +<% end -%> + <% unless options[:skip_active_record] -%> # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. fixtures :all diff --git a/railties/lib/rails/generators/rails/credentials/credentials_generator.rb b/railties/lib/rails/generators/rails/credentials/credentials_generator.rb index 0fb4d5fbd1..719e0c1e4c 100644 --- a/railties/lib/rails/generators/rails/credentials/credentials_generator.rb +++ b/railties/lib/rails/generators/rails/credentials/credentials_generator.rb @@ -2,7 +2,6 @@ require "rails/generators/base" require "rails/generators/rails/master_key/master_key_generator" -require "active_support/core_ext/string/strip" require "active_support/encrypted_configuration" module Rails @@ -43,13 +42,13 @@ module Rails end def credentials_template - <<-YAML.strip_heredoc - # aws: - # access_key_id: 123 - # secret_access_key: 345 + <<~YAML + # aws: + # access_key_id: 123 + # secret_access_key: 345 - # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies. - secret_key_base: #{SecureRandom.hex(64)} + # Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies. + secret_key_base: #{SecureRandom.hex(64)} YAML end end diff --git a/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb b/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb index ef398f52a1..867e28c6db 100644 --- a/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb +++ b/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require "rails/generators/base" -require "active_support/core_ext/string/strip" require "active_support/encrypted_file" module Rails @@ -16,10 +15,10 @@ module Rails private def encrypted_file_template - <<-YAML.strip_heredoc - # aws: - # access_key_id: 123 - # secret_access_key: 345 + <<~YAML + # aws: + # access_key_id: 123 + # secret_access_key: 345 YAML end diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt index abbacd9bec..b86ef0f2f8 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt @@ -1,4 +1,4 @@ -<%= wrap_in_modules <<-rb.strip_heredoc +<%= wrap_in_modules <<~rb class ApplicationController < ActionController::#{api? ? "API" : "Base"} #{ api? ? '# ' : '' }protect_from_forgery with: :exception end diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt index 25d692732d..be078f36de 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt @@ -1,4 +1,4 @@ -<%= wrap_in_modules <<-rb.strip_heredoc +<%= wrap_in_modules <<~rb module ApplicationHelper end rb diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt index bad1ff2d16..846863bc13 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt @@ -1,4 +1,4 @@ -<%= wrap_in_modules <<-rb.strip_heredoc +<%= wrap_in_modules <<~rb class ApplicationJob < ActiveJob::Base end rb diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt index 09aac13f42..246e274348 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt @@ -1,4 +1,4 @@ -<%= wrap_in_modules <<-rb.strip_heredoc +<%= wrap_in_modules <<~rb class ApplicationMailer < ActionMailer::Base default from: 'from@example.com' layout 'mailer' diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt index 8aa3de78f1..21465278be 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt @@ -1,4 +1,4 @@ -<%= wrap_in_modules <<-rb.strip_heredoc +<%= wrap_in_modules <<~rb class ApplicationRecord < ActiveRecord::Base self.abstract_class = true end diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt index 8938770fc4..4ec1804940 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt @@ -1,4 +1,4 @@ -<%= wrap_in_modules <<-rb.strip_heredoc +<%= wrap_in_modules <<~rb class Engine < ::Rails::Engine #{mountable? ? ' isolate_namespace ' + camelized_modules : ' '} #{api? ? " config.generators.api_only = true" : ' '} diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt index 7bdf4ee5fb..b853fabcc3 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt @@ -1,4 +1,4 @@ -<%= wrap_in_modules <<-rb.strip_heredoc +<%= wrap_in_modules <<~rb class Railtie < ::Rails::Railtie end rb diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb index a146a8fda6..5675faff70 100644 --- a/railties/lib/rails/generators/resource_helpers.rb +++ b/railties/lib/rails/generators/resource_helpers.rb @@ -25,13 +25,8 @@ module Rails assign_controller_names!(controller_name.pluralize) end - # TODO Change this to private once we've dropped Ruby 2.2 support. - # Workaround for Ruby 2.2 "private attribute?" warning. - protected - - attr_reader :controller_name, :controller_file_name - private + attr_reader :controller_name, :controller_file_name def controller_class_path if options[:model_name] diff --git a/railties/lib/rails/ruby_version_check.rb b/railties/lib/rails/ruby_version_check.rb index 76b6b80d28..f8d3311156 100644 --- a/railties/lib/rails/ruby_version_check.rb +++ b/railties/lib/rails/ruby_version_check.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true -if RUBY_VERSION < "2.2.2" && RUBY_ENGINE == "ruby" +if RUBY_VERSION < "2.4.1" && RUBY_ENGINE == "ruby" desc = defined?(RUBY_DESCRIPTION) ? RUBY_DESCRIPTION : "ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})" abort <<-end_message - Rails 5 requires Ruby 2.2.2 or newer. + Rails 6 requires Ruby 2.4.1 or newer. You're running #{desc} - Please upgrade to Ruby 2.2.2 or newer to continue. + Please upgrade to Ruby 2.4.1 or newer to continue. end_message end diff --git a/railties/lib/rails/secrets.rb b/railties/lib/rails/secrets.rb index 30e3478c9b..747cf31d7a 100644 --- a/railties/lib/rails/secrets.rb +++ b/railties/lib/rails/secrets.rb @@ -2,7 +2,6 @@ require "yaml" require "active_support/message_encryptor" -require "active_support/core_ext/string/strip" module Rails # Greatly inspired by Ara T. Howard's magnificent sekrets gem. 😘 diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb index 76c28ac85e..4bd7d74b04 100644 --- a/railties/lib/rails/test_help.rb +++ b/railties/lib/rails/test_help.rb @@ -22,6 +22,7 @@ if defined?(ActiveRecord::Base) module ActiveSupport class TestCase + include ActiveRecord::TestDatabases include ActiveRecord::TestFixtures self.fixture_path = "#{Rails.root}/test/fixtures/" self.file_fixture_path = fixture_path + "files" diff --git a/railties/railties.gemspec b/railties/railties.gemspec index 4c665cd546..1df8b1fe39 100644 --- a/railties/railties.gemspec +++ b/railties/railties.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.summary = "Tools for creating, working with, and running Rails applications." s.description = "Rails internals: application bootup, plugins, generators, and rake tasks." - s.required_ruby_version = ">= 2.2.2" + s.required_ruby_version = ">= 2.4.1" s.license = "MIT" diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 236d73d5fd..caadae3136 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1940,6 +1940,18 @@ 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 + 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/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/middleware_test.rb b/railties/test/application/middleware_test.rb index b9e4a9ccc0..5efaf841d4 100644 --- a/railties/test/application/middleware_test.rb +++ b/railties/test/application/middleware_test.rb @@ -70,8 +70,7 @@ module ApplicationTests "ActionDispatch::Callbacks", "Rack::Head", "Rack::ConditionalGet", - "Rack::ETag", - "Rack::TempfileReaper" + "Rack::ETag" ], middleware end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index 5a6404bd0a..d134febaf4 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 @@ -131,7 +130,7 @@ module ApplicationTests RUBY output = rails("routes") - assert_equal <<-MESSAGE.strip_heredoc, output + 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 @@ -173,7 +172,7 @@ module ApplicationTests RUBY output = rails("routes", "-g", "show") - assert_equal <<-MESSAGE.strip_heredoc, output + 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 @@ -183,7 +182,7 @@ module ApplicationTests MESSAGE output = rails("routes", "-g", "POST") - assert_equal <<-MESSAGE.strip_heredoc, output + 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 @@ -242,7 +241,7 @@ module ApplicationTests end RUBY - assert_equal <<-MESSAGE.strip_heredoc, rails("routes") + assert_equal <<~MESSAGE, 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 @@ -262,7 +261,7 @@ module ApplicationTests output = Dir.chdir(app_path) { `bin/rake --rakefile Rakefile routes` } - assert_equal <<-MESSAGE.strip_heredoc, output + 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 diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb index a01325fdb8..8e5ccf94cc 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\nbin/rails 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) @@ -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/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb index 4815cf6362..857124b23a 100644 --- a/railties/test/generators/api_app_generator_test.rb +++ b/railties/test/generators/api_app_generator_test.rb @@ -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 cc4a376d31..99790e602d 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -315,6 +315,15 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "Gemfile", /^# gem 'mini_magick'/ end + def test_mini_magick_gem_when_skip_active_storage_is_given + app_root = File.join(destination_root, "myapp") + run_generator [app_root, "--skip-active-storage"] + + 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_storage_is_given app_root = File.join(destination_root, "myapp") run_generator [app_root, "--skip-active-storage"] @@ -336,10 +345,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 @@ -363,10 +368,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_change_config_target_version 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/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 6568a356d6..0a4d2a9167 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -38,7 +38,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 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 |