diff options
Diffstat (limited to 'railties')
43 files changed, 427 insertions, 168 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 1a415449d1..91fa3aa8be 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,25 @@ +* Add an `abort_on_failure` boolean option to the generator method that shell + out (`generate`, `rake`, `rails_command`) to abort the generator if the + command fails. + + *David RodrÃguez* + +* Remove `app/assets` and `app/javascript` from `eager_load_paths` and `autoload_paths`. + + *Gannon McGibbon* + +* Add JSON support to rails properties route (`/rails/info/properties`). + + Now, `Rails::Info` properties may be accessed in JSON format at `/rails/info/properties.json`. + + *Yoshiyuki Hirano* + +* Use Ids instead of memory addresses when displaying references in scaffold views. + + Fixes #29200. + + *Rasesh Patel* + * Adds support for multiple databases to `rails db:migrate:status`. Subtasks are also added to get the status of individual databases (eg. `rails db:migrate:status:animals`). @@ -11,34 +33,18 @@ *DHH*, *Lachlan Sylvester* -* Refactors `migrations_paths` command option in generators - to `database` (aliased as `db`). Now, the migrations paths - will be read from the specified database configuration in the - current environment. - - ``` - bin/rails g model Chair brand:string --database=kingston - invoke active_record - create db/kingston_migrate/20180830151055_create_chairs.rb - ``` - - `--database` can be used with the migration, model, and scaffold generators. - - *Gannon McGibbon* - -* Adds an option to the model generator to allow setting the - migrations paths for that migration. This is useful for - applications that use multiple databases and put migrations - per database in their own directories. +* Add `database` (aliased as `db`) option to model generator to allow + setting the database. This is useful for applications that use + multiple databases and put migrations per database in their own directories. ``` - bin/rails g model Room capacity:integer --migrations-paths=db/kingston_migrate + bin/rails g model Room capacity:integer --database=kingston invoke active_record create db/kingston_migrate/20180830151055_create_rooms.rb ``` Because rails scaffolding uses the model generator, you can - also specify migrations paths with the scaffold generator. + also specify a database with the scaffold generator. *Gannon McGibbon* @@ -66,15 +72,15 @@ *Yoshiyuki Kinjo* -* Add `--migrations_paths` option to migration generator. +* Add `database` (aliased as `db`) option to migration generator. If you're using multiple databases and have a folder for each database for migrations (ex db/migrate and db/new_db_migrate) you can now pass the - `--migrations_paths` option to the generator to make sure the the migration + `--database` option to the generator to make sure the the migration is inserted into the correct folder. ``` - rails g migration CreateHouses --migrations_paths=db/kingston_migrate + rails g migration CreateHouses --database=kingston invoke active_record create db/kingston_migrate/20180830151055_create_houses.rb ``` diff --git a/railties/lib/rails/app_updater.rb b/railties/lib/rails/app_updater.rb index a243968a39..19d136e041 100644 --- a/railties/lib/rails/app_updater.rb +++ b/railties/lib/rails/app_updater.rb @@ -21,7 +21,7 @@ module Rails private def generator_options options = { api: !!Rails.application.config.api_only, update: true } - options[:skip_yarn] = !File.exist?(Rails.root.join("bin", "yarn")) + options[:skip_javascript] = !File.exist?(Rails.root.join("bin", "yarn")) options[:skip_active_record] = !defined?(ActiveRecord::Railtie) options[:skip_active_storage] = !defined?(ActiveStorage::Engine) || !defined?(ActiveRecord::Railtie) options[:skip_action_mailer] = !defined?(ActionMailer::Railtie) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 656786246d..acd97b64bf 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -232,10 +232,12 @@ module Rails if yaml.exist? require "erb" - require "active_support/ordered_options" + config = YAML.load(ERB.new(yaml.read).result) || {} + config = (config["shared"] || {}).merge(config[env] || {}) - config = (YAML.load(ERB.new(yaml.read).result) || {})[env] || {} - ActiveSupport::InheritableOptions.new(config.deep_symbolize_keys) + ActiveSupport::OrderedOptions.new.tap do |config_as_ordered_options| + config_as_ordered_options.update(config.deep_symbolize_keys) + end else raise "Could not load configuration. No such file - #{yaml}" end diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index eae902a938..f30e5d2a0f 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -127,6 +127,10 @@ module Rails if respond_to?(:action_dispatch) action_dispatch.use_cookies_with_metadata = true end + + if respond_to?(:active_job) + active_job.return_false_on_aborted_enqueue = true + end else raise "Unknown version #{target_version.to_s.inspect}" end @@ -202,7 +206,7 @@ module Rails "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \ "Error: #{e.message}" rescue => e - raise e, "Cannot load `Rails.application.database_configuration`:\n#{e.message}", e.backtrace + raise e, "Cannot load database configuration:\n#{e.message}", e.backtrace end def colorize_logging diff --git a/railties/lib/rails/command.rb b/railties/lib/rails/command.rb index 6d99ac9936..f09aa3ae0d 100644 --- a/railties/lib/rails/command.rb +++ b/railties/lib/rails/command.rb @@ -83,20 +83,21 @@ module Rails end def print_commands # :nodoc: - sorted_groups.each { |b, n| print_list(b, n) } + commands.each { |command| puts(" #{command}") } end - def sorted_groups # :nodoc: - lookup! + private + COMMANDS_IN_USAGE = %w(generate console server test test:system dbconsole new) + private_constant :COMMANDS_IN_USAGE - groups = (subclasses - hidden_commands).group_by { |c| c.namespace.split(":").first } - groups.transform_values! { |commands| commands.flat_map(&:printing_commands).sort } + def commands + lookup! - rails = groups.delete("rails") - [[ "rails", rails ]] + groups.sort.to_a - end + visible_commands = (subclasses - hidden_commands).flat_map(&:printing_commands) + + (visible_commands - COMMANDS_IN_USAGE).sort + end - private def command_type # :doc: @command_type ||= "command" end diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 6bf0406b21..4143b3c881 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -38,7 +38,9 @@ module Rails @paths ||= begin paths = Rails::Paths::Root.new(@root) - paths.add "app", eager_load: true, glob: "{*,*/concerns}" + paths.add "app", eager_load: true, + glob: "{*,*/concerns}", + exclude: %w(assets javascript) paths.add "app/assets", glob: "*" paths.add "app/controllers", eager_load: true paths.add "app/channels", eager_load: true, glob: "**/*_channel.rb" diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index cd8f16e247..5e8cebc50a 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -54,8 +54,6 @@ module Rails force_plural: false, helper: true, integration_tool: nil, - javascripts: true, - javascript_engine: :js, orm: false, resource_controller: :controller, resource_route: true, diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 78d2471890..4646a55316 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -221,9 +221,11 @@ module Rails # generate(:authenticated, "user session") def generate(what, *args) log :generate, what + + options = args.extract_options! argument = args.flat_map(&:to_s).join(" ") - in_root { run_ruby_script("bin/rails generate #{what} #{argument}", verbose: false) } + execute_command :rails, "generate #{what} #{argument}", options end # Runs the supplied rake task (invoked with 'rake ...') @@ -307,6 +309,7 @@ module Rails config = { verbose: false } config[:capture] = options[:capture] if options[:capture] + config[:abort_on_failure] = options[:abort_on_failure] if options[:abort_on_failure] in_root { run("#{sudo}#{extify(executor)} #{command} RAILS_ENV=#{env}", config) } end diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 2e4797e5bb..4dc4d27a46 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -31,9 +31,6 @@ module Rails class_option :database, type: :string, aliases: "-d", default: "sqlite3", desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})" - class_option :skip_yarn, type: :boolean, default: false, - desc: "Don't use Yarn for managing JavaScript dependencies" - class_option :skip_gemfile, type: :boolean, default: false, desc: "Don't create a Gemfile" diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt index e1ede7c713..2cf4e5c9d0 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt @@ -16,7 +16,7 @@ <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %> <tr> <% attributes.reject(&:password_digest?).each do |attribute| -%> - <td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td> + <td><%%= <%= singular_table_name %>.<%= attribute.column_name %> %></td> <% end -%> <td><%%= link_to 'Show', <%= model_resource_name %> %></td> <td><%%= link_to 'Edit', edit_<%= singular_route_name %>_path(<%= singular_table_name %>) %></td> diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt index 5e634153be..7deba07926 100644 --- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt +++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt @@ -3,7 +3,7 @@ <% attributes.reject(&:password_digest?).each do |attribute| -%> <p> <strong><%= attribute.human_name %>:</strong> - <%%= @<%= singular_table_name %>.<%= attribute.name %> %> + <%%= @<%= singular_table_name %>.<%= attribute.column_name %> %> </p> <% end -%> diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index b118ea989b..33002790d4 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -95,7 +95,7 @@ module Rails def bin_when_updating bin - if options[:skip_yarn] + if options[:skip_javascript] remove_file "bin/yarn" end end @@ -258,8 +258,8 @@ module Rails class_option :skip_bundle, type: :boolean, aliases: "-B", default: false, desc: "Don't run bundle install" - class_option :webpack, type: :string, default: nil, - desc: "Preconfigure Webpack with a particular framework (options: #{WEBPACKS.join('/')})" + class_option :webpack, type: :string, aliases: "--webpacker", default: nil, + desc: "Preconfigure Webpack with a particular framework (options: #{WEBPACKS.join(", ")})" class_option :skip_webpack_install, type: :boolean, default: false, desc: "Don't run Webpack install" @@ -274,7 +274,7 @@ module Rails # Force sprockets and yarn to be skipped when generating API only apps. # Can't modify options hash as it's frozen by default. if options[:api] - self.options = options.merge(skip_sprockets: true, skip_javascript: true, skip_yarn: true).freeze + self.options = options.merge(skip_sprockets: true, skip_javascript: true).freeze end end @@ -289,7 +289,7 @@ module Rails build(:gitignore) unless options[:skip_git] build(:gemfile) unless options[:skip_gemfile] build(:version_control) - build(:package_json) unless options[:skip_yarn] + build(:package_json) unless options[:skip_javascript] end def create_app_files @@ -438,7 +438,6 @@ module Rails def delete_action_cable_files_skipping_action_cable if options[:skip_action_cable] - remove_file "app/javascript/channels/consumer.js" remove_dir "app/javascript/channels" remove_dir "app/channels" end @@ -463,8 +462,8 @@ module Rails end end - def delete_bin_yarn_if_skip_yarn_option - remove_file "bin/yarn" if options[:skip_yarn] + def delete_bin_yarn + remove_file "bin/yarn" if options[:skip_javascript] end def finish_template diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt index 1567333023..fb264935bd 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt @@ -45,6 +45,7 @@ group :development, :test do gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] end +<% end -%> group :development do <%- unless options.api? -%> # Access an interactive console on exception pages or by calling 'console' anywhere in the code. @@ -75,7 +76,6 @@ group :test do gem 'chromedriver-helper' end <%- end -%> -<% end -%> # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] diff --git a/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js index 5da1ce2dce..0cfcf74919 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js +++ b/railties/lib/rails/generators/rails/app/templates/app/javascript/channels/index.js @@ -1,5 +1,5 @@ -// Load all the channels within this directory and all subdirectories. +// Load all the channels within this directory and all subdirectories. // Channel files must be named *_channel.js. -const channels = require.context('.', true, /\_channel\.js$/) +const channels = require.context('.', true, /_channel\.js$/) channels.keys().forEach(channels) diff --git a/railties/lib/rails/generators/rails/app/templates/bin/setup.tt b/railties/lib/rails/generators/rails/app/templates/bin/setup.tt index 955a424878..3f73bae3da 100644 --- a/railties/lib/rails/generators/rails/app/templates/bin/setup.tt +++ b/railties/lib/rails/generators/rails/app/templates/bin/setup.tt @@ -14,16 +14,16 @@ FileUtils.chdir APP_ROOT do puts '== Installing dependencies ==' system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') -<% unless options.skip_yarn? -%> +<% unless options.skip_javascript? -%> - # Install JavaScript dependencies if using Yarn + # Install JavaScript dependencies # system('bin/yarn') <% end -%> <% unless options.skip_active_record? -%> # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') - # cp 'config/database.yml.sample', 'config/database.yml' + # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' # end puts "\n== Preparing database ==" diff --git a/railties/lib/rails/generators/rails/app/templates/bin/update.tt b/railties/lib/rails/generators/rails/app/templates/bin/update.tt index ed17959e1d..03b77d0d46 100644 --- a/railties/lib/rails/generators/rails/app/templates/bin/update.tt +++ b/railties/lib/rails/generators/rails/app/templates/bin/update.tt @@ -14,9 +14,9 @@ FileUtils.chdir APP_ROOT do puts '== Installing dependencies ==' system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') -<% unless options.skip_yarn? -%> +<% unless options.skip_javascript? -%> - # Install JavaScript dependencies if using Yarn + # Install JavaScript dependencies # system('bin/yarn') <% end -%> <% unless options.skip_active_record? -%> diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt index df8a6ad627..2383fe97d3 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt @@ -1,4 +1,4 @@ -# PostgreSQL. Versions 9.1 and up are supported. +# PostgreSQL. Versions 9.3 and up are supported. # # Configure Using Gemfile # gem 'activerecord-jdbcpostgresql-adapter' diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt index 5860563908..b6c2e7448a 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt @@ -11,6 +11,7 @@ # default: &default adapter: mysql2 + encoding: utf8mb4 pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt index dcd57425e2..2f51030756 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt @@ -1,4 +1,4 @@ -# PostgreSQL. Versions 9.1 and up are supported. +# PostgreSQL. Versions 9.3 and up are supported. # # Install the pg driver: # gem install pg diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt index 51196ae743..fe48fc34ee 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt @@ -5,10 +5,6 @@ Rails.application.config.assets.version = '1.0' # Add additional assets to the asset load path. # Rails.application.config.assets.paths << Emoji.images_path -<%- unless options[:skip_yarn] -%> -# Add Yarn node_modules folder to the asset load path. -Rails.application.config.assets.paths << Rails.root.join('node_modules') -<%- end -%> # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in the app/assets diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt index d3bcaa5ec8..c517b0f96b 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt @@ -11,6 +11,10 @@ # policy.object_src :none # policy.script_src :self, :https # policy.style_src :self, :https +<%- unless options[:skip_javascript] -%> +# # If you are using webpack-dev-server then specify webpack-dev-server host +# policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development? +<%- end -%> # # Specify URI for violation reports # # policy.report_uri "/csp-violation-report-endpoint" diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt index 54eb0cb1d2..5cca8ae570 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt @@ -15,3 +15,6 @@ # This option is not backwards compatible with earlier Rails versions. # It's best enabled when your entire app is migrated and stable on 6.0. # Rails.application.config.action_dispatch.use_cookies_with_metadata = true + +# Return false instead of self when #enqueue method was aborted from the callback +Rails.application.config.active_job.return_false_on_aborted_enqueue = true diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore.tt b/railties/lib/rails/generators/rails/app/templates/gitignore.tt index 4e114fb1d9..860baa1595 100644 --- a/railties/lib/rails/generators/rails/app/templates/gitignore.tt +++ b/railties/lib/rails/generators/rails/app/templates/gitignore.tt @@ -22,19 +22,14 @@ <% end -%> <% unless skip_active_storage? -%> -# Ignore uploaded files in development +# Ignore uploaded files in development. /storage/* <% if keeps? -%> !/storage/.keep <% end -%> <% end -%> - -<% unless options.skip_yarn? -%> -/node_modules -/yarn-error.log - -<% end -%> <% unless options.api? -%> + /public/assets <% end -%> .byebug_history diff --git a/railties/lib/rails/generators/rails/app/templates/package.json.tt b/railties/lib/rails/generators/rails/app/templates/package.json.tt index a654cba39c..7174116989 100644 --- a/railties/lib/rails/generators/rails/app/templates/package.json.tt +++ b/railties/lib/rails/generators/rails/app/templates/package.json.tt @@ -5,7 +5,7 @@ "rails-ujs": ">=5.2.1"<% unless options[:skip_turbolinks] %>, "turbolinks": "5.1.1"<% end -%><% unless skip_active_storage? %>, "activestorage": ">=5.2.1"<% end -%><% unless options[:skip_action_cable] %>, - "actioncable": ">=5.2.1"<% end -%> + "actioncable": ">=5.2.1"<% end %> }, "version": "0.1.0" } 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 c918b57eca..c06cd525d7 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 @@ -4,7 +4,7 @@ require 'rails/test_help' class ActiveSupport::TestCase # Run tests in parallel with specified workers -<% if defined?(JRUBY_VERSION) -%> +<% if defined?(JRUBY_VERSION) || Gem.win_platform? -%> parallelize(workers: 2, with: :threads) <%- else -%> parallelize(workers: 2) diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index a018a98c53..239b3a5739 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -88,7 +88,7 @@ task default: :test PASSTHROUGH_OPTIONS = [ :skip_active_record, :skip_active_storage, :skip_action_mailer, :skip_javascript, :skip_action_cable, :skip_sprockets, :database, - :javascript, :skip_yarn, :api, :quiet, :pretend, :skip + :api, :quiet, :pretend, :skip ] def generate_test_dummy(force = false) diff --git a/railties/lib/rails/generators/rails/plugin/templates/gitignore.tt b/railties/lib/rails/generators/rails/plugin/templates/gitignore.tt index 7a68da5c4b..0aabf09252 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/gitignore.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/gitignore.tt @@ -7,7 +7,7 @@ pkg/ <%= dummy_path %>/db/*.sqlite3-journal <% end -%> <%= dummy_path %>/log/*.log -<% unless options[:skip_yarn] -%> +<% unless options[:skip_javascript] -%> <%= dummy_path %>/node_modules/ <%= dummy_path %>/yarn-error.log <% end -%> diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb index 3df36efc4c..b8173c8d11 100644 --- a/railties/lib/rails/info.rb +++ b/railties/lib/rails/info.rb @@ -54,6 +54,10 @@ module Rails table << "</table>" end end + + def to_json + Hash[properties].to_json + end end # The Rails version. diff --git a/railties/lib/rails/info_controller.rb b/railties/lib/rails/info_controller.rb index b4f4a5922a..50fe176946 100644 --- a/railties/lib/rails/info_controller.rb +++ b/railties/lib/rails/info_controller.rb @@ -14,8 +14,16 @@ class Rails::InfoController < Rails::ApplicationController # :nodoc: end def properties - @info = Rails::Info.to_html - @page_title = "Properties" + respond_to do |format| + format.html do + @info = Rails::Info.to_html + @page_title = "Properties" + end + + format.json do + render json: Rails::Info.to_json + end + end end def routes diff --git a/railties/lib/rails/paths.rb b/railties/lib/rails/paths.rb index 87222563fd..8367ac8980 100644 --- a/railties/lib/rails/paths.rb +++ b/railties/lib/rails/paths.rb @@ -113,10 +113,11 @@ module Rails attr_accessor :glob def initialize(root, current, paths, options = {}) - @paths = paths - @current = current - @root = root - @glob = options[:glob] + @paths = paths + @current = current + @root = root + @glob = options[:glob] + @exclude = options[:exclude] options[:autoload_once] ? autoload_once! : skip_autoload_once! options[:eager_load] ? eager_load! : skip_eager_load! @@ -189,13 +190,11 @@ module Rails raise "You need to set a path root" unless @root.path result = [] - each do |p| - path = File.expand_path(p, @root.path) + each do |path| + path = File.expand_path(path, @root.path) if @glob && File.directory?(path) - Dir.chdir(path) do - result.concat(Dir.glob(@glob).map { |file| File.join path, file }.sort) - end + result.concat files_in(path) else result << path end @@ -222,6 +221,17 @@ module Rails end alias to_a expanded + + private + + def files_in(path) + Dir.chdir(path) do + files = Dir.glob(@glob) + files -= @exclude if @exclude + files.map! { |file| File.join(path, file) } + files.sort + end + end end end end diff --git a/railties/railties.gemspec b/railties/railties.gemspec index 6fdb4648c2..91407ee1ae 100644 --- a/railties/railties.gemspec +++ b/railties/railties.gemspec @@ -30,11 +30,14 @@ Gem::Specification.new do |s| "changelog_uri" => "https://github.com/rails/rails/blob/v#{version}/railties/CHANGELOG.md" } + # NOTE: Please read our dependency guidelines before updating versions: + # https://edgeguides.rubyonrails.org/security.html#dependency-management-and-cves + s.add_dependency "activesupport", version s.add_dependency "actionpack", version s.add_dependency "rake", ">= 0.8.7" - s.add_dependency "thor", ">= 0.19.0", "< 2.0" + s.add_dependency "thor", ">= 0.20.3", "< 2.0" s.add_dependency "method_source" s.add_development_dependency "actionview", version diff --git a/railties/test/application/bin_setup_test.rb b/railties/test/application/bin_setup_test.rb index d02100d94c..a952d2466b 100644 --- a/railties/test/application/bin_setup_test.rb +++ b/railties/test/application/bin_setup_test.rb @@ -45,6 +45,8 @@ module ApplicationTests output.sub!(/^Resolving dependencies\.\.\.\n/, "") # Suppress Bundler platform warnings from output output.gsub!(/^The dependency .* will be unused .*\.\n/, "") + # Ignore warnings such as `Psych.safe_load is deprecated` + output.gsub!(/^warning:\s.*\n/, "") assert_equal(<<~OUTPUT, output) == Installing dependencies == diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 9b01d42b1e..9fff764eca 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -1663,6 +1663,14 @@ module ApplicationTests assert_kind_of Hash, Rails.application.config.database_configuration end + test "autoload paths do not include asset paths" do + app "development" + ActiveSupport::Dependencies.autoload_paths.each do |path| + assert_not_operator path, :ends_with?, "app/assets" + assert_not_operator path, :ends_with?, "app/javascript" + end + end + test "raises with proper error message if no database configuration found" do FileUtils.rm("#{app_path}/config/database.yml") err = assert_raises RuntimeError do @@ -1728,21 +1736,6 @@ module ApplicationTests assert_equal true, Rails.application.config.action_mailer.show_previews end - test "config_for loads custom configuration from yaml files" do - app_file "config/custom.yml", <<-RUBY - development: - foo: 'bar' - RUBY - - add_to_config <<-RUBY - config.my_custom_config = config_for('custom') - RUBY - - app "development" - - assert_equal "bar", Rails.application.config.my_custom_config["foo"] - end - test "config_for loads custom configuration from yaml accessible as symbol" do app_file "config/custom.yml", <<-RUBY development: @@ -1758,10 +1751,12 @@ module ApplicationTests assert_equal "bar", Rails.application.config.my_custom_config[:foo] end - test "config_for loads custom configuration from yaml accessible as method" do + test "config_for loads nested custom configuration from yaml as symbol keys" do app_file "config/custom.yml", <<-RUBY development: - foo: 'bar' + foo: + bar: + baz: 1 RUBY add_to_config <<-RUBY @@ -1770,15 +1765,15 @@ module ApplicationTests app "development" - assert_equal "bar", Rails.application.config.my_custom_config.foo + assert_equal 1, Rails.application.config.my_custom_config[:foo][:bar][:baz] end - test "config_for loads nested custom configuration from yaml as symbol keys" do + test "config_for makes all hash methods available" do app_file "config/custom.yml", <<-RUBY development: - foo: - bar: - baz: 1 + foo: 0 + bar: + baz: 1 RUBY add_to_config <<-RUBY @@ -1787,7 +1782,14 @@ module ApplicationTests app "development" - assert_equal 1, Rails.application.config.my_custom_config.foo[:bar][:baz] + actual = Rails.application.config.my_custom_config + + assert_equal actual, foo: 0, bar: { baz: 1 } + assert_equal actual.keys, [ :foo, :bar ] + assert_equal actual.values, [ 0, baz: 1] + assert_equal actual.to_h, foo: 0, bar: { baz: 1 } + assert_equal actual[:foo], 0 + assert_equal actual[:bar], baz: 1 end test "config_for uses the Pathname object if it is provided" do @@ -1802,7 +1804,7 @@ module ApplicationTests app "development" - assert_equal "custom key", Rails.application.config.my_custom_config["key"] + assert_equal "custom key", Rails.application.config.my_custom_config[:key] end test "config_for raises an exception if the file does not exist" do @@ -1832,6 +1834,40 @@ module ApplicationTests assert_equal({}, Rails.application.config.my_custom_config) end + test "config_for implements shared configuration as secrets case found" do + app_file "config/custom.yml", <<-RUBY + shared: + foo: :bar + test: + foo: :baz + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + + app "test" + + assert_equal(:baz, Rails.application.config.my_custom_config[:foo]) + end + + test "config_for implements shared configuration as secrets case not found" do + app_file "config/custom.yml", <<-RUBY + shared: + foo: :bar + test: + foo: :baz + RUBY + + add_to_config <<-RUBY + config.my_custom_config = config_for('custom') + RUBY + + app "development" + + assert_equal(:bar, Rails.application.config.my_custom_config[:foo]) + end + test "config_for with empty file returns an empty hash" do app_file "config/custom.yml", <<-RUBY RUBY @@ -1901,7 +1937,7 @@ module ApplicationTests app "development" - assert_equal "custom key", Rails.application.config.my_custom_config["key"] + assert_equal "custom key", Rails.application.config.my_custom_config[:key] end test "config_for with syntax error show a more descriptive exception" do @@ -1934,7 +1970,7 @@ module ApplicationTests RUBY require "#{app_path}/config/environment" - assert_equal "unicorn", Rails.application.config.my_custom_config["key"] + assert_equal "unicorn", Rails.application.config.my_custom_config[:key] end test "api_only is false by default" do @@ -2103,13 +2139,40 @@ module ApplicationTests assert_equal false, ActionView::Template.finalize_compiled_template_methods end + test "ActiveJob::Base.return_false_on_aborted_enqueue is true by default" do + app "development" + + assert_equal true, ActiveJob::Base.return_false_on_aborted_enqueue + end + + test "ActiveJob::Base.return_false_on_aborted_enqueue is false in the 5.x defaults" do + remove_from_config '.*config\.load_defaults.*\n' + add_to_config 'config.load_defaults "5.2"' + + app "development" + + assert_equal false, ActiveJob::Base.return_false_on_aborted_enqueue + end + + test "ActiveJob::Base.return_false_on_aborted_enqueue can be configured in the new framework defaults" do + remove_from_config '.*config\.load_defaults.*\n' + + app_file "config/initializers/new_framework_defaults_6_0.rb", <<-RUBY + Rails.application.config.active_job.return_false_on_aborted_enqueue = true + RUBY + + app "development" + + assert_equal true, ActiveJob::Base.return_false_on_aborted_enqueue + end + test "ActiveRecord::Base.filter_attributes should equal to filter_parameters" do app_file "config/initializers/filter_parameters_logging.rb", <<-RUBY Rails.application.config.filter_parameters += [ :password, :credit_card_number ] RUBY app "development" assert_equal [ :password, :credit_card_number ], Rails.application.config.filter_parameters - assert_equal [ "password", "credit_card_number" ].to_set, ActiveRecord::Base.filter_attributes + assert_equal [ :password, :credit_card_number ], ActiveRecord::Base.filter_attributes end test "ActiveStorage.routes_prefix can be configured via config.active_storage.routes_prefix" do diff --git a/railties/test/application/rake/multi_dbs_test.rb b/railties/test/application/rake/multi_dbs_test.rb index 6478e06250..ef99365e75 100644 --- a/railties/test/application/rake/multi_dbs_test.rb +++ b/railties/test/application/rake/multi_dbs_test.rb @@ -65,6 +65,27 @@ module ApplicationTests end end + def db_migrate_and_schema_cache_dump + Dir.chdir(app_path) do + generate_models_for_animals + rails "db:migrate" + rails "db:schema:cache:dump" + assert File.exist?("db/schema_cache.yml") + assert File.exist?("db/animals_schema_cache.yml") + end + end + + def db_migrate_and_schema_cache_dump_and_schema_cache_clear + Dir.chdir(app_path) do + generate_models_for_animals + rails "db:migrate" + rails "db:schema:cache:dump" + rails "db:schema:cache:clear" + assert_not File.exist?("db/schema_cache.yml") + assert_not File.exist?("db/animals_schema_cache.yml") + end + end + def db_migrate_and_schema_dump_and_load(format) Dir.chdir(app_path) do generate_models_for_animals @@ -92,7 +113,7 @@ module ApplicationTests end end - def db_migrate_namespaced(namespace, expected_database) + def db_migrate_namespaced(namespace) Dir.chdir(app_path) do generate_models_for_animals output = rails("db:migrate:#{namespace}") @@ -104,7 +125,7 @@ module ApplicationTests end end - def db_migrate_status_namespaced(namespace, expected_database) + def db_migrate_status_namespaced(namespace) Dir.chdir(app_path) do generate_models_for_animals output = rails("db:migrate:status:#{namespace}") @@ -178,7 +199,7 @@ module ApplicationTests test "db:migrate:namespace works" do require "#{app_path}/config/environment" ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config| - db_migrate_namespaced db_config.spec_name, db_config.config["database"] + db_migrate_namespaced db_config.spec_name end end @@ -190,10 +211,20 @@ module ApplicationTests test "db:migrate:status:namespace works" do require "#{app_path}/config/environment" ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config| - db_migrate_namespaced db_config.spec_name, db_config.config["database"] - db_migrate_status_namespaced db_config.spec_name, db_config.config["database"] + db_migrate_namespaced db_config.spec_name + db_migrate_status_namespaced db_config.spec_name end end + + test "db:schema:cache:dump works on all databases" do + require "#{app_path}/config/environment" + db_migrate_and_schema_cache_dump + end + + test "db:schema:cache:clear works on all databases" do + require "#{app_path}/config/environment" + db_migrate_and_schema_cache_dump_and_schema_cache_clear + end end end end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index a0cdae898b..44e3b0f66b 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -160,7 +160,10 @@ module ApplicationTests def test_scaffold_tests_pass_by_default rails "generate", "scaffold", "user", "username:string", "password:string" - with_rails_env("test") { rails("db:migrate") } + with_rails_env("test") do + rails("db:migrate") + rails("webpacker:compile") + end output = rails("test") assert_match(/7 runs, 9 assertions, 0 failures, 0 errors/, output) @@ -189,8 +192,10 @@ module ApplicationTests rails "generate", "model", "Product" rails "generate", "model", "Cart" rails "generate", "scaffold", "LineItems", "product:references", "cart:belongs_to" - with_rails_env("test") { rails("db:migrate") } - rails("webpacker:compile") + with_rails_env("test") do + rails("db:migrate") + rails("webpacker:compile") + end output = rails("test") assert_match(/7 runs, 9 assertions, 0 failures, 0 errors/, output) diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb index 5c34b205c9..140703e118 100644 --- a/railties/test/application/test_runner_test.rb +++ b/railties/test/application/test_runner_test.rb @@ -562,6 +562,44 @@ module ApplicationTests assert_no_match "create_table(:users)", output end + def test_run_in_parallel_with_unmarshable_exception + file = app_file "test/fail_test.rb", <<-RUBY + require "test_helper" + class FailTest < ActiveSupport::TestCase + class BadError < StandardError + def initialize + super + @proc = ->{ } + end + end + + test "fail" do + raise BadError + assert true + end + end + RUBY + + output = run_test_command(file) + + assert_match "DRb::DRbRemoteError: FailTest::BadError", output + assert_match "1 runs, 0 assertions, 0 failures, 1 errors", output + end + + def test_run_in_parallel_with_unknown_object + create_scaffold + app_file "config/environments/test.rb", <<-RUBY + Rails.application.configure do + config.action_controller.allow_forgery_protection = true + config.action_dispatch.show_exceptions = false + end + RUBY + + output = run_test_command("-n test_should_create_user") + + assert_match "ActionController::InvalidAuthenticityToken", 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) @@ -703,6 +741,31 @@ module ApplicationTests end end + def test_reset_sessions_on_failed_system_test_screenshot + app_file "test/system/reset_sessions_on_failed_system_test_screenshot_test.rb", <<~RUBY + require "application_system_test_case" + + class ResetSessionsOnFailedSystemTestScreenshotTest < ApplicationSystemTestCase + ActionDispatch::SystemTestCase.class_eval do + def take_failed_screenshot + raise Capybara::CapybaraError + end + end + + Capybara.instance_eval do + def reset_sessions! + puts "Capybara.reset_sessions! called" + end + end + + test "dummy" do + end + end + RUBY + output = run_test_command("test/system/reset_sessions_on_failed_system_test_screenshot_test.rb") + assert_match "Capybara.reset_sessions! called", output + end + def test_system_tests_are_not_run_with_the_default_test_command app_file "test/system/dummy_test.rb", <<-RUBY require "application_system_test_case" diff --git a/railties/test/credentials_test.rb b/railties/test/credentials_test.rb index 03370e0fc7..11765b0de5 100644 --- a/railties/test/credentials_test.rb +++ b/railties/test/credentials_test.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true require "isolation/abstract_unit" +require "env_helpers" class Rails::CredentialsTest < ActiveSupport::TestCase - include ActiveSupport::Testing::Isolation + include ActiveSupport::Testing::Isolation, EnvHelpers setup :build_app teardown :teardown_app @@ -38,6 +39,21 @@ class Rails::CredentialsTest < ActiveSupport::TestCase end end + test "reads credentials using environment variable key" do + with_credentials do |content, key| + Dir.chdir(app_path) do + Dir.mkdir("config/credentials") + File.write("config/credentials/production.yml.enc", content) + end + + switch_env("RAILS_MASTER_KEY", key) do + app("production") + + assert_equal "revealed", Rails.application.credentials.mystery + end + end + end + private def with_credentials key = "2117e775dc2024d4f49ddf3aeb585919" diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 6d53230eab..af475400a1 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -303,12 +303,24 @@ class ActionsTest < Rails::Generators::TestCase end def test_generate_should_run_script_generate_with_argument_and_options - assert_called_with(generator, :run_ruby_script, ["bin/rails generate model MyModel", verbose: false]) do - action :generate, "model", "MyModel" + run_generator + action :generate, "model", "MyModel" + assert_file "app/models/my_model.rb", /MyModel/ + end + + def test_generate_aborts_when_subprocess_fails_if_requested + run_generator + content = capture(:stderr) do + assert_raises SystemExit do + action :generate, "model", "MyModel:ADsad", abort_on_failure: true + action :generate, "model", "MyModel" + end end + assert_match(/wrong constant name MyModel:aDsad/, content) + assert_no_file "app/models/my_model.rb" end - def test_rails_should_run_rake_command_with_default_env + def test_rake_should_run_rake_command_with_default_env assert_called_with(generator, :run, ["rake log:clear RAILS_ENV=development", verbose: false]) do with_rails_env nil do action :rake, "log:clear" @@ -316,13 +328,13 @@ class ActionsTest < Rails::Generators::TestCase end end - def test_rails_with_env_option_should_run_rake_command_in_env + def test_rake_with_env_option_should_run_rake_command_in_env assert_called_with(generator, :run, ["rake log:clear RAILS_ENV=production", verbose: false]) do action :rake, "log:clear", env: "production" end end - test "rails command with RAILS_ENV variable should run rake command in env" do + test "rake with RAILS_ENV variable should run rake command in env" do assert_called_with(generator, :run, ["rake log:clear RAILS_ENV=production", verbose: false]) do with_rails_env "production" do action :rake, "log:clear" @@ -338,7 +350,7 @@ class ActionsTest < Rails::Generators::TestCase end end - test "rails command with sudo option should run rake command with sudo" do + test "rake with sudo option should run rake command with sudo" do assert_called_with(generator, :run, ["sudo rake log:clear RAILS_ENV=development", verbose: false]) do with_rails_env nil do action :rake, "log:clear", sudo: true diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index be97abfa52..32d00f3157 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -15,6 +15,8 @@ DEFAULT_APP_FILES = %w( app/assets/images app/javascript app/javascript/channels + app/javascript/channels/consumer.js + app/javascript/channels/index.js app/javascript/packs/application.js app/assets/stylesheets app/assets/stylesheets/application.css @@ -104,7 +106,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_skip_bundle - assert_not_called(generator([destination_root], skip_bundle: true), :bundle_command) do + assert_not_called(generator([destination_root], skip_bundle: true, skip_webpack_install: true), :bundle_command) do quietly { generator.invoke_all } # skip_bundle is only about running bundle install, ensure the Gemfile is still # generated. @@ -228,6 +230,14 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_equal "false\n", output end + def test_csp_initializer_include_connect_src_example + run_generator + + assert_file "config/initializers/content_security_policy.rb" do |content| + assert_match(/# policy\.connect_src/, content) + end + end + def test_app_update_keep_the_cookie_serializer_if_it_is_already_configured app_root = File.join(destination_root, "myapp") run_generator [app_root] @@ -298,10 +308,10 @@ class AppGeneratorTest < Rails::Generators::TestCase 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"] + run_generator [app_root, "--skip-javascript"] stub_rails_application(app_root) do - generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_yarn: true }, { destination_root: app_root, shell: @shell } + generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_javascript: true }, { destination_root: app_root, shell: @shell } generator.send(:app_const) quietly { generator.send(:update_bin_files) } @@ -608,7 +618,7 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "app/views/layouts/application.html.erb" do |contents| assert_match(/stylesheet_link_tag\s+'application', media: 'all' %>/, contents) - assert_no_match(/javascript_include_tag\s+'application' \%>/, contents) + assert_no_match(/javascript_pack_tag\s+'application'/, contents) end end @@ -710,7 +720,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_web_console_with_dev_option - run_generator [destination_root, "--dev"] + run_generator [destination_root, "--dev", "--skip-bundle"] assert_file "Gemfile" do |content| assert_match(/gem 'web-console',\s+github: 'rails\/web-console'/, content) @@ -728,13 +738,13 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_generation_runs_bundle_install - generator([destination_root], {}) + generator([destination_root], skip_webpack_install: true) assert_bundler_command_called("install") end def test_dev_option - generator([destination_root], dev: true) + generator([destination_root], dev: true, skip_webpack_install: true) assert_bundler_command_called("install") rails_path = File.expand_path("../../..", Rails.root) @@ -742,7 +752,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_edge_option - generator([destination_root], edge: true) + generator([destination_root], edge: true, skip_webpack_install: true) assert_bundler_command_called("install") assert_file "Gemfile", %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["']$} @@ -754,12 +764,16 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_bundler_binstub + generator([destination_root], skip_webpack_install: true) + assert_bundler_command_called("binstubs bundler") end def test_spring_binstubs jruby_skip "spring doesn't run on JRuby" + generator([destination_root], skip_webpack_install: true) + assert_bundler_command_called("exec spring binstub --all") end @@ -780,7 +794,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_spring_with_dev_option - run_generator [destination_root, "--dev"] + run_generator [destination_root, "--dev", "--skip-bundle"] assert_no_gem "spring" end @@ -790,7 +804,7 @@ class AppGeneratorTest < Rails::Generators::TestCase @called ||= 0 if command == "webpacker:install" @called += 1 - assert_equal 0, @called, "webpacker:install expected not to be called once, but was called #{@called} times." + assert_equal 0, @called, "webpacker:install expected not to be called, but was called #{@called} times." end end @@ -801,6 +815,9 @@ class AppGeneratorTest < Rails::Generators::TestCase end assert_no_gem "webpacker" + assert_file "config/initializers/content_security_policy.rb" do |content| + assert_no_match(/policy\.connect_src/, content) + end end def test_webpack_option_with_js_framework @@ -878,7 +895,7 @@ class AppGeneratorTest < Rails::Generators::TestCase end def test_bootsnap_with_dev_option - run_generator [destination_root, "--dev"] + run_generator [destination_root, "--dev", "--skip-bundle"] assert_no_gem "bootsnap" assert_file "config/boot.rb" do |content| diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index 21b5013484..3cffdddd38 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -435,8 +435,8 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase end end - def test_scaffold_generator_belongs_to - run_generator ["account", "name", "currency:belongs_to"] + def test_scaffold_generator_belongs_to_and_references + run_generator ["account", "name", "currency:belongs_to", "user:references"] assert_file "app/models/account.rb", /belongs_to :currency/ @@ -449,7 +449,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_file "app/controllers/accounts_controller.rb" do |content| assert_instance_method :account_params, content do |m| - assert_match(/permit\(:name, :currency_id\)/, m) + assert_match(/permit\(:name, :currency_id, :user_id\)/, m) end end @@ -457,6 +457,16 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase assert_match(/^\W{4}<%= form\.text_field :name %>/, content) assert_match(/^\W{4}<%= form\.text_field :currency_id %>/, content) end + + assert_file "app/views/accounts/index.html.erb" do |content| + assert_match(/^\W{8}<td><%= account\.name %><\/td>/, content) + assert_match(/^\W{8}<td><%= account\.user_id %><\/td>/, content) + end + + assert_file "app/views/accounts/show.html.erb" do |content| + assert_match(/^\W{2}<%= @account\.name %>/, content) + assert_match(/^\W{2}<%= @account\.user_id %>/, content) + end end def test_scaffold_generator_database diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb index fc654e867b..2dda856f25 100644 --- a/railties/test/generators/shared_generator_tests.rb +++ b/railties/test/generators/shared_generator_tests.rb @@ -91,7 +91,7 @@ module SharedGeneratorTests template end - generator([destination_root], template: path).stub(:open, check_open, template) do + generator([destination_root], template: path, skip_webpack_install: true).stub(:open, check_open, template) do generator.stub :bundle_command, nil do quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) } end @@ -99,7 +99,7 @@ module SharedGeneratorTests end def test_skip_gemfile - assert_not_called(generator([destination_root], skip_gemfile: true), :bundle_command) do + assert_not_called(generator([destination_root], skip_gemfile: true, skip_webpack_install: true), :bundle_command) do quietly { generator.invoke_all } assert_no_file "Gemfile" end @@ -231,7 +231,7 @@ module SharedGeneratorTests assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/ assert_file "#{application_path}/app/javascript/packs/application.js" do |content| - assert_no_match(/^\/\/= require activestorage/, content) + assert_no_match(/activestorage/, content) end assert_file "#{application_path}/config/environments/development.rb" do |content| @@ -261,7 +261,7 @@ module SharedGeneratorTests assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/ assert_file "#{application_path}/app/javascript/packs/application.js" do |content| - assert_no_match(/^import * as ActiveStorage from "activestorage"\nActiveStorage.start()/, content) + assert_no_match(/^import * as ActiveStorage from "activestorage"\nActiveStorage.start\(\)/, content) end assert_file "#{application_path}/config/environments/development.rb" do |content| @@ -336,28 +336,15 @@ module SharedGeneratorTests end def test_generator_for_yarn + skip "#34009 disabled JS by default for plugins" if generator_class.name == "Rails::Generators::PluginGenerator" run_generator assert_file "#{application_path}/package.json", /dependencies/ - assert_file "#{application_path}/config/initializers/assets.rb", /node_modules/ - - assert_file ".gitignore" do |content| - assert_match(/node_modules/, content) - assert_match(/yarn-error\.log/, content) - end + assert_file "#{application_path}/bin/yarn" end def test_generator_for_yarn_skipped - run_generator([destination_root, "--skip-yarn"]) + run_generator([destination_root, "--skip-javascript"]) assert_no_file "#{application_path}/package.json" assert_no_file "#{application_path}/bin/yarn" - - assert_file "#{application_path}/config/initializers/assets.rb" do |content| - assert_no_match(/node_modules/, content) - end - - assert_file ".gitignore" do |content| - assert_no_match(/node_modules/, content) - assert_no_match(/yarn-error\.log/, content) - end end end diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb index 878a238f8d..6ab68f8333 100644 --- a/railties/test/rails_info_controller_test.rb +++ b/railties/test/rails_info_controller_test.rb @@ -50,6 +50,11 @@ class InfoControllerTest < ActionController::TestCase assert_select "table" end + test "info controller renders json with properties" do + get :properties, format: :json + assert_equal Rails::Info.to_json, response.body + end + test "info controller renders with routes" do get :routes assert_response :success diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb index 50522c1be6..d167a86e56 100644 --- a/railties/test/rails_info_test.rb +++ b/railties/test/rails_info_test.rb @@ -43,6 +43,18 @@ class InfoTest < ActiveSupport::TestCase end end + def test_json_includes_middleware + Rails::Info.module_eval do + property "Middleware", ["Rack::Lock", "Rack::Static"] + end + + hash = JSON.parse(Rails::Info.to_json) + assert_includes hash.keys, "Middleware" + properties.value_for("Middleware").each do |value| + assert_includes hash["Middleware"], value + end + end + private def properties Rails::Info.properties |