aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/.gitignore6
-rw-r--r--railties/CHANGELOG.md155
-rw-r--r--railties/MIT-LICENSE2
-rw-r--r--railties/RDOC_MAIN.rdoc53
-rw-r--r--railties/lib/minitest/rails_plugin.rb13
-rw-r--r--railties/lib/rails.rb8
-rw-r--r--railties/lib/rails/all.rb2
-rw-r--r--railties/lib/rails/api/task.rb2
-rw-r--r--railties/lib/rails/app_loader.rb4
-rw-r--r--railties/lib/rails/app_updater.rb11
-rw-r--r--railties/lib/rails/application.rb77
-rw-r--r--railties/lib/rails/application/bootstrap.rb2
-rw-r--r--railties/lib/rails/application/configuration.rb114
-rw-r--r--railties/lib/rails/application/default_middleware_stack.rb6
-rw-r--r--railties/lib/rails/application/finisher.rb2
-rw-r--r--railties/lib/rails/application_controller.rb11
-rw-r--r--railties/lib/rails/cli.rb6
-rw-r--r--railties/lib/rails/code_statistics.rb2
-rw-r--r--railties/lib/rails/command.rb2
-rw-r--r--railties/lib/rails/command/base.rb2
-rw-r--r--railties/lib/rails/command/behavior.rb40
-rw-r--r--railties/lib/rails/command/helpers/editor.rb35
-rw-r--r--railties/lib/rails/command/spellchecker.rb11
-rw-r--r--railties/lib/rails/commands.rb2
-rw-r--r--railties/lib/rails/commands/application/application_command.rb4
-rw-r--r--railties/lib/rails/commands/console/console_command.rb2
-rw-r--r--railties/lib/rails/commands/credentials/credentials_command.rb51
-rw-r--r--railties/lib/rails/commands/dbconsole/dbconsole_command.rb4
-rw-r--r--railties/lib/rails/commands/destroy/destroy_command.rb2
-rw-r--r--railties/lib/rails/commands/encrypted/encrypted_command.rb86
-rw-r--r--railties/lib/rails/commands/generate/generate_command.rb2
-rw-r--r--railties/lib/rails/commands/plugin/plugin_command.rb4
-rw-r--r--railties/lib/rails/commands/routes/routes_command.rb37
-rw-r--r--railties/lib/rails/commands/runner/runner_command.rb4
-rw-r--r--railties/lib/rails/commands/secrets/secrets_command.rb21
-rw-r--r--railties/lib/rails/commands/server/server_command.rb117
-rw-r--r--railties/lib/rails/commands/test/test_command.rb6
-rw-r--r--railties/lib/rails/configuration.rb4
-rw-r--r--railties/lib/rails/engine.rb10
-rw-r--r--railties/lib/rails/engine/commands.rb2
-rw-r--r--railties/lib/rails/engine/configuration.rb2
-rw-r--r--railties/lib/rails/engine/updater.rb4
-rw-r--r--railties/lib/rails/gem_version.rb4
-rw-r--r--railties/lib/rails/generators.rb16
-rw-r--r--railties/lib/rails/generators/actions.rb10
-rw-r--r--railties/lib/rails/generators/app_base.rb160
-rw-r--r--railties/lib/rails/generators/css/assets/assets_generator.rb2
-rw-r--r--railties/lib/rails/generators/css/scaffold/scaffold_generator.rb8
-rw-r--r--railties/lib/rails/generators/erb.rb2
-rw-r--r--railties/lib/rails/generators/erb/controller/controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/erb/controller/templates/view.html.erb.tt (renamed from railties/lib/rails/generators/erb/controller/templates/view.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/mailer/mailer_generator.rb4
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/view.html.erb.tt (renamed from railties/lib/rails/generators/erb/mailer/templates/view.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/view.text.erb.tt (renamed from railties/lib/rails/generators/erb/mailer/templates/view.text.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb4
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt (renamed from railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb)8
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt (renamed from railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt (renamed from railties/lib/rails/generators/erb/scaffold/templates/index.html.erb)8
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt (renamed from railties/lib/rails/generators/erb/scaffold/templates/new.html.erb)0
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt (renamed from railties/lib/rails/generators/erb/scaffold/templates/show.html.erb)0
-rw-r--r--railties/lib/rails/generators/generated_attribute.rb4
-rw-r--r--railties/lib/rails/generators/js/assets/assets_generator.rb2
-rw-r--r--railties/lib/rails/generators/migration.rb9
-rw-r--r--railties/lib/rails/generators/model_helpers.rb2
-rw-r--r--railties/lib/rails/generators/named_base.rb52
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb74
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile.tt (renamed from railties/lib/rails/generators/rails/app/templates/Gemfile)21
-rw-r--r--railties/lib/rails/generators/rails/app/templates/README.md.tt (renamed from railties/lib/rails/generators/rails/app/templates/README.md)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Rakefile.tt (renamed from railties/lib/rails/generators/rails/app/templates/Rakefile)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/bundle.tt (renamed from railties/lib/rails/generators/rails/app/templates/bin/bundle)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/rails.tt (renamed from railties/lib/rails/generators/rails/app/templates/bin/rails)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/rake.tt (renamed from railties/lib/rails/generators/rails/app/templates/bin/rake)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/update.tt5
-rw-r--r--railties/lib/rails/generators/rails/app/templates/bin/yarn.tt (renamed from railties/lib/rails/generators/rails/app/templates/bin/yarn)6
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config.ru.tt (renamed from railties/lib/rails/generators/rails/app/templates/config.ru)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/application.rb)9
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/boot.rb)2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/cable.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/cable.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environment.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/environment.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt11
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt10
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt12
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt25
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt27
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt10
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/puma.rb)24
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/routes.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/routes.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/secrets.yml32
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/spring.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/spring.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/storage.yml.tt (renamed from railties/lib/rails/generators/rails/app/templates/config/storage.yml)13
-rw-r--r--railties/lib/rails/generators/rails/app/templates/gitignore.tt (renamed from railties/lib/rails/generators/rails/app/templates/gitignore)7
-rw-r--r--railties/lib/rails/generators/rails/app/templates/package.json.tt (renamed from railties/lib/rails/generators/rails/app/templates/package.json)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/ruby-version1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/ruby-version.tt1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb)0
-rw-r--r--railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt (renamed from railties/lib/rails/generators/rails/app/templates/test/test_helper.rb)8
-rw-r--r--railties/lib/rails/generators/rails/assets/templates/stylesheet.css2
-rw-r--r--railties/lib/rails/generators/rails/controller/controller_generator.rb13
-rw-r--r--railties/lib/rails/generators/rails/controller/templates/controller.rb.tt (renamed from railties/lib/rails/generators/rails/controller/templates/controller.rb)0
-rw-r--r--railties/lib/rails/generators/rails/credentials/credentials_generator.rb38
-rw-r--r--railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb27
-rw-r--r--railties/lib/rails/generators/rails/encrypted_secrets/encrypted_secrets_generator.rb72
-rw-r--r--railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb58
-rw-r--r--railties/lib/rails/generators/rails/helper/templates/helper.rb.tt (renamed from railties/lib/rails/generators/rails/helper/templates/helper.rb)0
-rw-r--r--railties/lib/rails/generators/rails/master_key/master_key_generator.rb50
-rw-r--r--railties/lib/rails/generators/rails/model/model_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb14
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Gemfile.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/Gemfile)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/README.md.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/README.md)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/Rakefile)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/helpers/%namespaced_name%/application_helper.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/jobs/%namespaced_name%/application_job.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt6
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/config/routes.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/config/routes.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/gitignore.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/gitignore)3
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb)2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/railtie.rb)2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%namespaced_name%_tasks.rake.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%namespaced_name%_tasks.rake)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/application.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/rails/application.rb)2
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js)4
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb)0
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt (renamed from railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb)3
-rw-r--r--railties/lib/rails/generators/rails/resource/USAGE2
-rw-r--r--railties/lib/rails/generators/rails/resource/resource_generator.rb4
-rw-r--r--railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt (renamed from railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb)0
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt (renamed from railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb)4
-rw-r--r--railties/lib/rails/generators/rails/task/templates/task.rb.tt (renamed from railties/lib/rails/generators/rails/task/templates/task.rb)0
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb11
-rw-r--r--railties/lib/rails/generators/test_case.rb8
-rw-r--r--railties/lib/rails/generators/test_unit.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/controller/controller_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/generator/generator_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/helper/helper_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/integration/integration_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/job/job_generator.rb9
-rw-r--r--railties/lib/rails/generators/test_unit/job/templates/unit_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/job/templates/unit_test.rb.erb)0
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb4
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt (renamed from railties/lib/rails/generators/test_unit/mailer/templates/preview.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/model/model_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt (renamed from railties/lib/rails/generators/test_unit/model/templates/fixtures.yml)0
-rw-r--r--railties/lib/rails/generators/test_unit/model/templates/unit_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/model/templates/unit_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb6
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/scaffold/templates/system_test.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/system/system_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt (renamed from railties/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb)0
-rw-r--r--railties/lib/rails/generators/test_unit/system/templates/system_test.rb.tt (renamed from railties/lib/rails/generators/test_unit/system/templates/system_test.rb)0
-rw-r--r--railties/lib/rails/generators/testing/behaviour.rb2
-rw-r--r--railties/lib/rails/info.rb2
-rw-r--r--railties/lib/rails/info_controller.rb2
-rw-r--r--railties/lib/rails/mailers_controller.rb14
-rw-r--r--railties/lib/rails/plugin/test.rb4
-rw-r--r--railties/lib/rails/rack/logger.rb6
-rw-r--r--railties/lib/rails/railtie.rb2
-rw-r--r--railties/lib/rails/railtie/configuration.rb4
-rw-r--r--railties/lib/rails/ruby_version_check.rb6
-rw-r--r--railties/lib/rails/secrets.rb18
-rw-r--r--railties/lib/rails/source_annotation_extractor.rb243
-rw-r--r--railties/lib/rails/tasks.rb1
-rw-r--r--railties/lib/rails/tasks/annotations.rake8
-rw-r--r--railties/lib/rails/tasks/dev.rake2
-rw-r--r--railties/lib/rails/tasks/engine.rake9
-rw-r--r--railties/lib/rails/tasks/framework.rake6
-rw-r--r--railties/lib/rails/tasks/routes.rake31
-rw-r--r--railties/lib/rails/tasks/statistics.rake2
-rw-r--r--railties/lib/rails/tasks/yarn.rake2
-rw-r--r--railties/lib/rails/templates/rails/mailers/email.html.erb46
-rw-r--r--railties/lib/rails/test_help.rb7
-rw-r--r--railties/lib/rails/test_unit/railtie.rb2
-rw-r--r--railties/lib/rails/test_unit/reporter.rb10
-rw-r--r--railties/lib/rails/test_unit/runner.rb2
-rw-r--r--railties/lib/rails/test_unit/testing.rake2
-rw-r--r--railties/lib/rails/welcome_controller.rb2
-rw-r--r--railties/railties.gemspec2
-rw-r--r--railties/test/app_loader_test.rb6
-rw-r--r--railties/test/application/asset_debugging_test.rb3
-rw-r--r--railties/test/application/assets_test.rb6
-rw-r--r--railties/test/application/configuration/custom_test.rb2
-rw-r--r--railties/test/application/configuration_test.rb229
-rw-r--r--railties/test/application/console_test.rb6
-rw-r--r--railties/test/application/content_security_policy_test.rb223
-rw-r--r--railties/test/application/dbconsole_test.rb52
-rw-r--r--railties/test/application/generators_test.rb3
-rw-r--r--railties/test/application/initializers/frameworks_test.rb4
-rw-r--r--railties/test/application/initializers/notifications_test.rb1
-rw-r--r--railties/test/application/integration_test_case_test.rb7
-rw-r--r--railties/test/application/loading_test.rb24
-rw-r--r--railties/test/application/mailer_previews_test.rb74
-rw-r--r--railties/test/application/middleware/cache_test.rb4
-rw-r--r--railties/test/application/middleware/cookies_test.rb145
-rw-r--r--railties/test/application/middleware/exceptions_test.rb2
-rw-r--r--railties/test/application/middleware/sendfile_test.rb2
-rw-r--r--railties/test/application/middleware/session_test.rb4
-rw-r--r--railties/test/application/middleware_test.rb6
-rw-r--r--railties/test/application/per_request_digest_cache_test.rb2
-rw-r--r--railties/test/application/rake/dbs_test.rb194
-rw-r--r--railties/test/application/rake/migrations_test.rb421
-rw-r--r--railties/test/application/rake/multi_dbs_test.rb164
-rw-r--r--railties/test/application/rake/notes_test.rb2
-rw-r--r--railties/test/application/rake_test.rb179
-rw-r--r--railties/test/application/rendering_test.rb2
-rw-r--r--railties/test/application/runner_test.rb16
-rw-r--r--railties/test/application/server_test.rb9
-rw-r--r--railties/test/application/test_runner_test.rb157
-rw-r--r--railties/test/application/test_test.rb5
-rw-r--r--railties/test/command/spellchecker_test.rb10
-rw-r--r--railties/test/commands/console_test.rb29
-rw-r--r--railties/test/commands/credentials_test.rb51
-rw-r--r--railties/test/commands/dbconsole_test.rb24
-rw-r--r--railties/test/commands/encrypted_test.rb106
-rw-r--r--railties/test/commands/routes_test.rb175
-rw-r--r--railties/test/commands/secrets_test.rb49
-rw-r--r--railties/test/commands/server_test.rb79
-rw-r--r--railties/test/engine/test_test.rb31
-rw-r--r--railties/test/engine_test.rb2
-rw-r--r--railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml1
-rw-r--r--railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb3
-rw-r--r--railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb3
-rw-r--r--railties/test/generators/actions_test.rb16
-rw-r--r--railties/test/generators/api_app_generator_test.rb21
-rw-r--r--railties/test/generators/app_generator_test.rb260
-rw-r--r--railties/test/generators/argv_scrubber_test.rb3
-rw-r--r--railties/test/generators/channel_generator_test.rb10
-rw-r--r--railties/test/generators/controller_generator_test.rb29
-rw-r--r--railties/test/generators/create_migration_test.rb2
-rw-r--r--railties/test/generators/encrypted_secrets_generator_test.rb44
-rw-r--r--railties/test/generators/generated_attribute_test.rb12
-rw-r--r--railties/test/generators/generators_test_helper.rb4
-rw-r--r--railties/test/generators/job_generator_test.rb10
-rw-r--r--railties/test/generators/model_generator_test.rb35
-rw-r--r--railties/test/generators/named_base_test.rb39
-rw-r--r--railties/test/generators/plugin_generator_test.rb58
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb25
-rw-r--r--railties/test/generators/scaffold_generator_test.rb17
-rw-r--r--railties/test/generators/shared_generator_tests.rb130
-rw-r--r--railties/test/generators_test.rb19
-rw-r--r--railties/test/isolation/abstract_unit.rb118
-rw-r--r--railties/test/minitest/rails_plugin_test.rb42
-rw-r--r--railties/test/paths_test.rb28
-rw-r--r--railties/test/rack_logger_test.rb22
-rw-r--r--railties/test/rails_info_test.rb15
-rw-r--r--railties/test/railties/engine_test.rb82
-rw-r--r--railties/test/railties/railtie_test.rb14
-rw-r--r--railties/test/secrets_test.rb16
-rw-r--r--railties/test/test_unit/reporter_test.rb8
295 files changed, 4163 insertions, 1776 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 ff440b7939..a4d4a87a8b 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,143 +1,68 @@
-* Add `mini_magick` to default `Gemfile` as comment.
-
- *Yoshiyuki Hirano*
-
-* Derive `secret_key_base` from the app name in development and test environments.
-
- Spares away needless secret configs.
-
- *DHH*, *Kasper Timm Hansen*
-
-* Support multiple versions arguments for `gem` method of Generators.
-
- *Yoshiyuki Hirano*
-
-* Add `--skip-yarn` option to the plugin generator.
-
- *bogdanvlviv*
-
-* Optimize routes indentation.
-
- *Yoshiyuki Hirano*
-
-* Optimize indentation for generator actions.
-
- *Yoshiyuki Hirano*
-
-* Skip unused components when running `bin/rails` in Rails plugin.
-
- *Yoshiyuki Hirano*
-
-* Add `git_source` to `Gemfile` for plugin generator.
-
- *Yoshiyuki Hirano*
-
-* Add `--skip-action-cable` option to the plugin generator.
-
- *bogdanvlviv*
-
-* Deprecate support of use `Rails::Application` subclass to start Rails server.
-
- *Yuji Yaginuma*
-
-* Add `ruby x.x.x` version to `Gemfile` and create `.ruby-version`
- root file containing the current Ruby version when new Rails applications are
- created.
-
- *Alberto Almagro*
-
-* Support `-` as a platform-agnostic way to run a script from stdin with
- `rails runner`
-
- *Cody Cutrer*
-
-* Add `bootsnap` to default `Gemfile`.
-
- *Burke Libbey*
-
-* Properly expand shortcuts for environment's name running the `console`
- and `dbconsole` commands.
-
- *Robin Dupret*
-
-* Passing the environment's name as a regular argument to the
- `rails dbconsole` and `rails console` commands is deprecated.
- The `-e` option should be used instead.
+* Make the master.key file read-only for the owner upon generation on
+ POSIX-compliant systems.
Previously:
- $ bin/rails dbconsole production
+ $ ls -l config/master.key
+ -rw-r--r-- 1 owner group 32 Jan 1 00:00 master.key
Now:
- $ bin/rails dbconsole -e production
-
- *Robin Dupret*, *Kasper Timm Hansen*
-
-* Allow passing a custom connection name to the `rails dbconsole`
- command when using a 3-level database configuration.
-
- $ bin/rails dbconsole -c replica
-
- *Robin Dupret*, *Jeremy Daer*
-
-* Skip unused components when running `bin/rails app:update`.
-
- If the initial app generation skipped Action Cable, Active Record etc.,
- the update task honors those skips too.
-
- *Yuji Yaginuma*
-
-* Make Rails' test runner work better with minitest plugins.
-
- By demoting the Rails test runner to just another minitest plugin —
- and thereby not eager loading it — we can co-exist much better with
- other minitest plugins such as pride and minitest-focus.
+ $ ls -l config/master.key
+ -rw------- 1 owner group 32 Jan 1 00:00 master.key
- *Kasper Timm Hansen*
+ Fixes #32604.
-* Load environment file in `dbconsole` command.
+ *Jose Luis Duran*
- Fixes #29717.
+* Deprecate support for using the `HOST` environment to specify the server IP.
- *Yuji Yaginuma*
+ The `BINDING` environment should be used instead.
-* Add `rails secrets:show` command.
+ Fixes #29516.
*Yuji Yaginuma*
-* Allow mounting the same engine several times in different locations.
-
- Fixes #20204.
-
- *David Rodríguez*
+* Deprecate passing Rack server name as a regular argument to `rails server`.
-* Clear screenshot files in `tmp:clear` task.
-
- *Yuji Yaginuma*
+ Previously:
-* Add `railtie.rb` to the plugin generator
+ $ bin/rails server thin
- *Tsukuru Tanimichi*
+ There wasn't an explicit option for the Rack server to use, now we have the
+ `--using` option with the `-u` short switch.
-* Deprecate `capify!` method in generators and templates.
+ Now:
- *Yuji Yaginuma*
+ $ bin/rails server -u thin
-* Allow irb options to be passed from `rails console` command.
+ This change also improves the error message if a missing or mistyped rack
+ server is given.
- Fixes #28988.
+ *Genadi Samokovarov*
- *Yuji Yaginuma*
+* Add "rails routes --expanded" option to output routes in expanded mode like
+ "psql --expanded". Result looks like:
-* Added a shared section to `config/database.yml` that will be loaded for all environments.
+ ```
+ $ rails routes --expanded
+ --[ Route 1 ]------------------------------------------------------------
+ Prefix | high_scores
+ Verb | GET
+ URI | /high_scores(.:format)
+ Controller#Action | high_scores#index
+ --[ Route 2 ]------------------------------------------------------------
+ Prefix | new_high_score
+ Verb | GET
+ URI | /high_scores/new(.:format)
+ Controller#Action | high_scores#new
+ ```
- *Pierre Schambacher*
+ *Benoit Tigeot*
-* Namespace error pages' CSS selectors to stop the styles from bleeding into other pages
- when using Turbolinks.
+* Rails 6 requires Ruby 2.4.1 or newer.
- *Jan Krutisch*
+ *Jeremy Daer*
-Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/railties/CHANGELOG.md) for previous changes.
+Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/railties/CHANGELOG.md) for previous changes.
diff --git a/railties/MIT-LICENSE b/railties/MIT-LICENSE
index f9e4444f07..cce00cbc3a 100644
--- a/railties/MIT-LICENSE
+++ b/railties/MIT-LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2017 David Heinemeier Hansson
+Copyright (c) 2004-2018 David Heinemeier Hansson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/railties/RDOC_MAIN.rdoc b/railties/RDOC_MAIN.rdoc
index c70a9f0ba0..a4a4b6b235 100644
--- a/railties/RDOC_MAIN.rdoc
+++ b/railties/RDOC_MAIN.rdoc
@@ -1,4 +1,6 @@
-== Welcome to \Rails
+= Welcome to \Rails
+
+== What's \Rails
\Rails is a web-application framework that includes everything needed to
create database-backed web applications according to the
@@ -6,43 +8,48 @@ create database-backed web applications according to the
pattern.
Understanding the MVC pattern is key to understanding \Rails. MVC divides your
-application into three layers, each with a specific responsibility.
+application into three layers: Model, View, and Controller, each with a specific responsibility.
+
+== Model layer
-The <em>Model layer</em> represents your domain model (such as Account, Product,
-Person, Post, etc.) and encapsulates the business logic that is specific to
+The <em><b>Model layer</b></em> represents the domain model (such as Account, Product,
+Person, Post, etc.) and encapsulates the business logic specific to
your application. In \Rails, database-backed model classes are derived from
-ActiveRecord::Base. Active Record allows you to present the data from
+<tt>ActiveRecord::Base</tt>. {Active Record}[link:files/activerecord/README_rdoc.html] allows you to present the data from
database rows as objects and embellish these data objects with business logic
-methods. You can read more about Active Record in its {README}[link:files/activerecord/README_rdoc.html].
-Although most \Rails models are backed by a database, models can also be ordinary
+methods. Although most \Rails models are backed by a database, models can also be ordinary
Ruby classes, or Ruby classes that implement a set of interfaces as provided by
-the Active Model module. You can read more about Active Model in its {README}[link:files/activemodel/README_rdoc.html].
+the {Active Model}[link:files/activemodel/README_rdoc.html] module.
+
+== Controller layer
-The <em>Controller layer</em> is responsible for handling incoming HTTP requests and
+The <em><b>Controller layer</b></em> is responsible for handling incoming HTTP requests and
providing a suitable response. Usually this means returning \HTML, but \Rails controllers
can also generate XML, JSON, PDFs, mobile-specific views, and more. Controllers load and
manipulate models, and render view templates in order to generate the appropriate HTTP response.
In \Rails, incoming requests are routed by Action Dispatch to an appropriate controller, and
-controller classes are derived from ActionController::Base. Action Dispatch and Action Controller
-are bundled together in Action Pack. You can read more about Action Pack in its
-{README}[link:files/actionpack/README_rdoc.html].
+controller classes are derived from <tt>ActionController::Base</tt>. Action Dispatch and Action Controller
+are bundled together in {Action Pack}[link:files/actionpack/README_rdoc.html].
-The <em>View layer</em> is composed of "templates" that are responsible for providing
+== View layer
+
+The <em><b>View layer</b></em> is composed of "templates" that are responsible for providing
appropriate representations of your application's resources. Templates can
come in a variety of formats, but most view templates are \HTML with embedded
Ruby code (ERB files). Views are typically rendered to generate a controller response,
-or to generate the body of an email. In \Rails, View generation is handled by Action View.
-You can read more about Action View in its {README}[link:files/actionview/README_rdoc.html].
+or to generate the body of an email. In \Rails, View generation is handled by {Action View}[link:files/actionview/README_rdoc.html].
+
+== Frameworks and libraries
-Active Record, Active Model, Action Pack, and Action View can each be used independently outside \Rails.
-In addition to that, \Rails also comes with Action Mailer ({README}[link:files/actionmailer/README_rdoc.html]), a library
-to generate and send emails; Active Job ({README}[link:files/activejob/README_md.html]), a
+{Active Record}[link:files/activerecord/README_rdoc.html], {Active Model}[link:files/activemodel/README_rdoc.html],
+{Action Pack}[link:files/actionpack/README_rdoc.html], and {Action View}[link:files/actionview/README_rdoc.html] can each be used independently outside \Rails.
+In addition to that, \Rails also comes with {Action Mailer}[link:files/actionmailer/README_rdoc.html], a library
+to generate and send emails; {Active Job}[link:files/activejob/README_md.html], a
framework for declaring jobs and making them run on a variety of queueing
-backends; Action Cable ({README}[link:files/actioncable/README_md.html]), a framework to
-integrate WebSockets with a \Rails application;
-Active Storage ({README}[link:files/activestorage/README_md.html]), a library to attach cloud
-and local files to \Rails applications;
-and Active Support ({README}[link:files/activesupport/README_rdoc.html]), a collection
+backends; {Action Cable}[link:files/actioncable/README_md.html], a framework to
+integrate WebSockets with a \Rails application; {Active Storage}[link:files/activestorage/README_md.html],
+a library to attach cloud and local files to \Rails applications;
+and {Active Support}[link:files/activesupport/README_rdoc.html], a collection
of utility classes and standard library extensions that are useful for \Rails,
and may also be used independently outside \Rails.
diff --git a/railties/lib/minitest/rails_plugin.rb b/railties/lib/minitest/rails_plugin.rb
index 6901b0bbc8..6486fa1798 100644
--- a/railties/lib/minitest/rails_plugin.rb
+++ b/railties/lib/minitest/rails_plugin.rb
@@ -13,7 +13,7 @@ module Minitest
end
def self.plugin_rails_options(opts, options)
- Rails::TestUnit::Runner.attach_before_load_options(opts)
+ ::Rails::TestUnit::Runner.attach_before_load_options(opts)
opts.on("-b", "--backtrace", "Show the complete backtrace") do
options[:full_backtrace] = true
@@ -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.rb b/railties/lib/rails.rb
index 04bb9ba94a..092105d502 100644
--- a/railties/lib/rails.rb
+++ b/railties/lib/rails.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "rails/ruby_version_check"
+require "rails/ruby_version_check"
require "pathname"
@@ -11,8 +11,8 @@ require "active_support/core_ext/module/delegation"
require "active_support/core_ext/array/extract_options"
require "active_support/core_ext/object/blank"
-require_relative "rails/application"
-require_relative "rails/version"
+require "rails/application"
+require "rails/version"
require "active_support/railtie"
require "action_dispatch/railtie"
@@ -50,7 +50,7 @@ module Rails
def backtrace_cleaner
@backtrace_cleaner ||= begin
# Relies on Active Support, so we have to lazy load to postpone definition until Active Support has been loaded
- require_relative "rails/backtrace_cleaner"
+ require "rails/backtrace_cleaner"
Rails::BacktraceCleaner.new
end
end
diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb
index e55b2e2433..f5dccd2381 100644
--- a/railties/lib/rails/all.rb
+++ b/railties/lib/rails/all.rb
@@ -4,12 +4,12 @@ require "rails"
%w(
active_record/railtie
+ active_storage/engine
action_controller/railtie
action_view/railtie
action_mailer/railtie
active_job/railtie
action_cable/engine
- active_storage/engine
rails/test_unit/railtie
sprockets/railtie
).each do |railtie|
diff --git a/railties/lib/rails/api/task.rb b/railties/lib/rails/api/task.rb
index 184f5b14f1..e7f0557584 100644
--- a/railties/lib/rails/api/task.rb
+++ b/railties/lib/rails/api/task.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "rdoc/task"
-require_relative "generator"
+require "rails/api/generator"
module Rails
module API
diff --git a/railties/lib/rails/app_loader.rb b/railties/lib/rails/app_loader.rb
index 3e9b3bd4bb..20eb75d95c 100644
--- a/railties/lib/rails/app_loader.rb
+++ b/railties/lib/rails/app_loader.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "pathname"
-require_relative "version"
+require "rails/version"
module Rails
module AppLoader # :nodoc:
@@ -56,7 +56,7 @@ EOS
$stderr.puts(BUNDLER_WARNING)
Object.const_set(:APP_PATH, File.expand_path("config/application", Dir.pwd))
require File.expand_path("../boot", APP_PATH)
- require_relative "commands"
+ require "rails/commands"
break
end
end
diff --git a/railties/lib/rails/app_updater.rb b/railties/lib/rails/app_updater.rb
index c2436a69f9..a076d082d5 100644
--- a/railties/lib/rails/app_updater.rb
+++ b/railties/lib/rails/app_updater.rb
@@ -21,11 +21,12 @@ module Rails
private
def generator_options
options = { api: !!Rails.application.config.api_only, update: true }
- options[:skip_active_record] = !defined?(ActiveRecord::Railtie)
- options[:skip_action_mailer] = !defined?(ActionMailer::Railtie)
- options[:skip_action_cable] = !defined?(ActionCable::Engine)
- options[:skip_sprockets] = !defined?(Sprockets::Railtie)
- options[:skip_puma] = !defined?(Puma)
+ options[:skip_active_record] = !defined?(ActiveRecord::Railtie)
+ options[:skip_active_storage] = !defined?(ActiveStorage::Engine) || !defined?(ActiveRecord::Railtie)
+ options[:skip_action_mailer] = !defined?(ActionMailer::Railtie)
+ options[:skip_action_cable] = !defined?(ActionCable::Engine)
+ options[:skip_sprockets] = !defined?(Sprockets::Railtie)
+ options[:skip_puma] = !defined?(Puma)
options
end
end
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index abfec90b6d..e346d5cc3a 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -6,8 +6,9 @@ require "active_support/core_ext/object/blank"
require "active_support/key_generator"
require "active_support/message_verifier"
require "active_support/encrypted_configuration"
-require_relative "engine"
-require_relative "secrets"
+require "active_support/deprecation"
+require "rails/engine"
+require "rails/secrets"
module Rails
# An Engine with the responsibility of coordinating the whole boot process.
@@ -173,8 +174,9 @@ module Rails
# team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
@caching_key_generator ||=
if secret_key_base
- ActiveSupport::CachingKeyGenerator.new \
+ ActiveSupport::CachingKeyGenerator.new(
ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
+ )
else
ActiveSupport::LegacyKeyGenerator.new(secrets.secret_token)
end
@@ -259,8 +261,15 @@ module Rails
"action_dispatch.encrypted_cookie_salt" => config.action_dispatch.encrypted_cookie_salt,
"action_dispatch.encrypted_signed_cookie_salt" => config.action_dispatch.encrypted_signed_cookie_salt,
"action_dispatch.authenticated_encrypted_cookie_salt" => config.action_dispatch.authenticated_encrypted_cookie_salt,
+ "action_dispatch.use_authenticated_cookie_encryption" => config.action_dispatch.use_authenticated_cookie_encryption,
+ "action_dispatch.encrypted_cookie_cipher" => config.action_dispatch.encrypted_cookie_cipher,
+ "action_dispatch.signed_cookie_digest" => config.action_dispatch.signed_cookie_digest,
"action_dispatch.cookies_serializer" => config.action_dispatch.cookies_serializer,
- "action_dispatch.cookies_digest" => config.action_dispatch.cookies_digest
+ "action_dispatch.cookies_digest" => config.action_dispatch.cookies_digest,
+ "action_dispatch.cookies_rotations" => config.action_dispatch.cookies_rotations,
+ "action_dispatch.content_security_policy" => config.content_security_policy,
+ "action_dispatch.content_security_policy_report_only" => config.content_security_policy_report_only,
+ "action_dispatch.content_security_policy_nonce_generator" => config.content_security_policy_nonce_generator
)
end
end
@@ -394,6 +403,12 @@ module Rails
# Fallback to config.secret_token if secrets.secret_token isn't set
secrets.secret_token ||= config.secret_token
+ if secrets.secret_token.present?
+ ActiveSupport::Deprecation.warn(
+ "`secrets.secret_token` is deprecated in favor of `secret_key_base` and will be removed in Rails 6.0."
+ )
+ end
+
secrets
end
end
@@ -412,21 +427,55 @@ module Rails
# the correct place to store it is in the encrypted credentials file.
def secret_key_base
if Rails.env.test? || Rails.env.development?
- Digest::MD5.hexdigest self.class.name
+ secrets.secret_key_base || Digest::MD5.hexdigest(self.class.name)
else
- validate_secret_key_base \
+ validate_secret_key_base(
ENV["SECRET_KEY_BASE"] || credentials.secret_key_base || secrets.secret_key_base
+ )
end
end
- # Decrypts the credentials hash as kept in `config/credentials.yml.enc`. This file is encrypted with
- # the Rails master key, which is either taken from ENV["RAILS_MASTER_KEY"] or from loading
- # `config/master.key`.
+ # Decrypts the credentials hash as kept in +config/credentials.yml.enc+. This file is encrypted with
+ # the Rails master key, which is either taken from <tt>ENV["RAILS_MASTER_KEY"]</tt> or from loading
+ # +config/master.key+.
def credentials
- @credentials ||= ActiveSupport::EncryptedConfiguration.new \
- config_path: Rails.root.join("config/credentials.yml.enc"),
- key_path: Rails.root.join("config/master.key"),
- env_key: "RAILS_MASTER_KEY"
+ @credentials ||= encrypted("config/credentials.yml.enc")
+ end
+
+ # Shorthand to decrypt any encrypted configurations or files.
+ #
+ # For any file added with <tt>bin/rails encrypted:edit</tt> call +read+ to decrypt
+ # the file with the master key.
+ # The master key is either stored in +config/master.key+ or <tt>ENV["RAILS_MASTER_KEY"]</tt>.
+ #
+ # Rails.application.encrypted("config/mystery_man.txt.enc").read
+ # # => "We've met before, haven't we?"
+ #
+ # It's also possible to interpret encrypted YAML files with +config+.
+ #
+ # Rails.application.encrypted("config/credentials.yml.enc").config
+ # # => { next_guys_line: "I don't think so. Where was it you think we met?" }
+ #
+ # Any top-level configs are also accessible directly on the return value:
+ #
+ # Rails.application.encrypted("config/credentials.yml.enc").next_guys_line
+ # # => "I don't think so. Where was it you think we met?"
+ #
+ # The files or configs can also be encrypted with a custom key. To decrypt with
+ # a key in the +ENV+, use:
+ #
+ # Rails.application.encrypted("config/special_tokens.yml.enc", env_key: "SPECIAL_TOKENS")
+ #
+ # Or to decrypt with a file, that should be version control ignored, relative to +Rails.root+:
+ #
+ # Rails.application.encrypted("config/special_tokens.yml.enc", key_path: "config/special_tokens.key")
+ def encrypted(path, key_path: "config/master.key", env_key: "RAILS_MASTER_KEY")
+ ActiveSupport::EncryptedConfiguration.new(
+ config_path: Rails.root.join(path),
+ key_path: Rails.root.join(key_path),
+ env_key: env_key,
+ raise_if_missing_key: config.require_master_key
+ )
end
def to_app #:nodoc:
@@ -464,7 +513,7 @@ module Rails
def run_tasks_blocks(app) #:nodoc:
railties.each { |r| r.run_tasks_blocks(app) }
super
- require_relative "tasks"
+ require "rails/tasks"
task :environment do
ActiveSupport.on_load(:before_initialize) { config.eager_load = false }
diff --git a/railties/lib/rails/application/bootstrap.rb b/railties/lib/rails/application/bootstrap.rb
index c24d4573a9..e3c0759f95 100644
--- a/railties/lib/rails/application/bootstrap.rb
+++ b/railties/lib/rails/application/bootstrap.rb
@@ -4,7 +4,7 @@ require "fileutils"
require "active_support/notifications"
require "active_support/dependencies"
require "active_support/descendants_tracker"
-require_relative "../secrets"
+require "rails/secrets"
module Rails
class Application
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index b65289177f..bba573499d 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -2,8 +2,8 @@
require "active_support/core_ext/kernel/reporting"
require "active_support/file_update_checker"
-require_relative "../engine/configuration"
-require_relative "../source_annotation_extractor"
+require "rails/engine/configuration"
+require "rails/source_annotation_extractor"
module Rails
class Application
@@ -16,44 +16,50 @@ module Rails
:ssl_options, :public_file_server,
:session_options, :time_zone, :reload_classes_only_on_change,
:beginning_of_week, :filter_redirect, :x, :enable_dependency_loading,
- :read_encrypted_secrets, :log_level
+ :read_encrypted_secrets, :log_level, :content_security_policy_report_only,
+ :content_security_policy_nonce_generator, :require_master_key
- attr_reader :encoding, :api_only
+ attr_reader :encoding, :api_only, :loaded_config_version
def initialize(*)
super
- self.encoding = Encoding::UTF_8
- @allow_concurrency = nil
- @consider_all_requests_local = false
- @filter_parameters = []
- @filter_redirect = []
- @helpers_paths = []
- @public_file_server = ActiveSupport::OrderedOptions.new
- @public_file_server.enabled = true
- @public_file_server.index_name = "index"
- @force_ssl = false
- @ssl_options = {}
- @session_store = nil
- @time_zone = "UTC"
- @beginning_of_week = :monday
- @log_level = :debug
- @generators = app_generators
- @cache_store = [ :file_store, "#{root}/tmp/cache/" ]
- @railties_order = [:all]
- @relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]
- @reload_classes_only_on_change = true
- @file_watcher = ActiveSupport::FileUpdateChecker
- @exceptions_app = nil
- @autoflush_log = true
- @log_formatter = ActiveSupport::Logger::SimpleFormatter.new
- @eager_load = nil
- @secret_token = nil
- @secret_key_base = nil
- @api_only = false
- @debug_exception_response_format = nil
- @x = Custom.new
- @enable_dependency_loading = false
- @read_encrypted_secrets = false
+ self.encoding = Encoding::UTF_8
+ @allow_concurrency = nil
+ @consider_all_requests_local = false
+ @filter_parameters = []
+ @filter_redirect = []
+ @helpers_paths = []
+ @public_file_server = ActiveSupport::OrderedOptions.new
+ @public_file_server.enabled = true
+ @public_file_server.index_name = "index"
+ @force_ssl = false
+ @ssl_options = {}
+ @session_store = nil
+ @time_zone = "UTC"
+ @beginning_of_week = :monday
+ @log_level = :debug
+ @generators = app_generators
+ @cache_store = [ :file_store, "#{root}/tmp/cache/" ]
+ @railties_order = [:all]
+ @relative_url_root = ENV["RAILS_RELATIVE_URL_ROOT"]
+ @reload_classes_only_on_change = true
+ @file_watcher = ActiveSupport::FileUpdateChecker
+ @exceptions_app = nil
+ @autoflush_log = true
+ @log_formatter = ActiveSupport::Logger::SimpleFormatter.new
+ @eager_load = nil
+ @secret_token = nil
+ @secret_key_base = nil
+ @api_only = false
+ @debug_exception_response_format = nil
+ @x = Custom.new
+ @enable_dependency_loading = false
+ @read_encrypted_secrets = false
+ @content_security_policy = nil
+ @content_security_policy_report_only = false
+ @content_security_policy_nonce_generator = nil
+ @require_master_key = false
+ @loaded_config_version = nil
end
def load_defaults(target_version)
@@ -71,7 +77,6 @@ module Rails
end
self.ssl_options = { hsts: { subdomains: true } }
-
when "5.1"
load_defaults "5.0"
@@ -82,7 +87,6 @@ module Rails
if respond_to?(:action_view)
action_view.form_with_generates_remote_forms = true
end
-
when "5.2"
load_defaults "5.1"
@@ -100,15 +104,27 @@ module Rails
if respond_to?(:active_support)
active_support.use_authenticated_message_encryption = true
+ active_support.use_sha1_digests = true
end
if respond_to?(:action_controller)
action_controller.default_protect_from_forgery = true
end
+ if respond_to?(:action_view)
+ action_view.form_with_generates_ids = true
+ end
+ when "6.0"
+ load_defaults "5.2"
+
+ if respond_to?(:action_view)
+ action_view.default_enforce_utf8 = false
+ end
else
raise "Unknown version #{target_version.to_s.inspect}"
end
+
+ @loaded_config_version = target_version
end
def encoding=(value)
@@ -150,6 +166,18 @@ module Rails
end
end
+ # Loads the database YAML without evaluating ERB. People seem to
+ # write ERB that makes the database configuration depend on
+ # Rails configuration. But we want Rails configuration (specifically
+ # `rake` and `rails` tasks) to be generated based on information in
+ # the database yaml, so we need a method that loads the database
+ # yaml *without* the context of the Rails application.
+ def load_database_yaml # :nodoc:
+ path = paths["config/database"].existent.first
+ return {} unless path
+ YAML.load_file(path.to_s)
+ end
+
# Loads and returns the entire raw configuration of database from
# values stored in <tt>config/database.yml</tt>.
def database_configuration
@@ -225,7 +253,15 @@ module Rails
end
def annotations
- SourceAnnotationExtractor::Annotation
+ Rails::SourceAnnotationExtractor::Annotation
+ end
+
+ def content_security_policy(&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 ea2273c1f2..433a7ab41f 100644
--- a/railties/lib/rails/application/default_middleware_stack.rb
+++ b/railties/lib/rails/application/default_middleware_stack.rb
@@ -63,9 +63,15 @@ module Rails
middleware.use ::ActionDispatch::Flash
end
+ unless config.api_only
+ middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware
+ end
+
middleware.use ::Rack::Head
middleware.use ::Rack::ConditionalGet
middleware.use ::Rack::ETag, "no-cache"
+
+ middleware.use ::Rack::TempfileReaper unless config.api_only
end
end
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 3d938be951..c4b188aeee 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -58,7 +58,7 @@ module Rails
end
# This needs to happen before eager load so it happens
- # in exactly the same point regardless of config.cache_classes
+ # in exactly the same point regardless of config.eager_load
initializer :run_prepare_callbacks do |app|
app.reloader.prepare!
end
diff --git a/railties/lib/rails/application_controller.rb b/railties/lib/rails/application_controller.rb
index fa8793d81a..b3fe822218 100644
--- a/railties/lib/rails/application_controller.rb
+++ b/railties/lib/rails/application_controller.rb
@@ -4,6 +4,13 @@ class Rails::ApplicationController < ActionController::Base # :nodoc:
self.view_paths = File.expand_path("templates", __dir__)
layout "application"
+ before_action :disable_content_security_policy_nonce!
+
+ content_security_policy do |policy|
+ policy.script_src :unsafe_inline
+ policy.style_src :unsafe_inline
+ end
+
private
def require_local!
@@ -15,4 +22,8 @@ class Rails::ApplicationController < ActionController::Base # :nodoc:
def local_request?
Rails.application.config.consider_all_requests_local || request.local?
end
+
+ def disable_content_security_policy_nonce!
+ request.content_security_policy_nonce_generator = nil
+ end
end
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb
index 50a2ed30cf..e56e604fdc 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -1,15 +1,15 @@
# frozen_string_literal: true
-require_relative "app_loader"
+require "rails/app_loader"
# If we are inside a Rails application this method performs an exec and thus
# the rest of this script is not run.
Rails::AppLoader.exec_app
-require_relative "ruby_version_check"
+require "rails/ruby_version_check"
Signal.trap("INT") { puts; exit(1) }
-require_relative "command"
+require "rails/command"
if ARGV.first == "plugin"
ARGV.shift
diff --git a/railties/lib/rails/code_statistics.rb b/railties/lib/rails/code_statistics.rb
index 7ceb86198f..9c447c366f 100644
--- a/railties/lib/rails/code_statistics.rb
+++ b/railties/lib/rails/code_statistics.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "code_statistics_calculator"
+require "rails/code_statistics_calculator"
require "active_support/core_ext/enumerable"
class CodeStatistics #:nodoc:
diff --git a/railties/lib/rails/command.rb b/railties/lib/rails/command.rb
index 812e846837..6d99ac9936 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"
@@ -12,6 +11,7 @@ module Rails
module Command
extend ActiveSupport::Autoload
+ autoload :Spellchecker
autoload :Behavior
autoload :Base
diff --git a/railties/lib/rails/command/base.rb b/railties/lib/rails/command/base.rb
index 8df4f98d3e..fa462ef7e9 100644
--- a/railties/lib/rails/command/base.rb
+++ b/railties/lib/rails/command/base.rb
@@ -6,7 +6,7 @@ require "erb"
require "active_support/core_ext/string/filters"
require "active_support/core_ext/string/inflections"
-require_relative "actions"
+require "rails/command/actions"
module Rails
module Command
diff --git a/railties/lib/rails/command/behavior.rb b/railties/lib/rails/command/behavior.rb
index 7a6dd28e1a..718e2d9ab2 100644
--- a/railties/lib/rails/command/behavior.rb
+++ b/railties/lib/rails/command/behavior.rb
@@ -19,46 +19,6 @@ module Rails
end
private
-
- # This code is based directly on the Text gem implementation.
- # Copyright (c) 2006-2013 Paul Battley, Michael Neumann, Tim Fletcher.
- #
- # Returns a value representing the "cost" of transforming str1 into str2.
- def levenshtein_distance(str1, str2) # :doc:
- s = str1
- t = str2
- n = s.length
- m = t.length
-
- return m if (0 == n)
- return n if (0 == m)
-
- d = (0..m).to_a
- x = nil
-
- # avoid duplicating an enumerable object in the loop
- str2_codepoint_enumerable = str2.each_codepoint
-
- str1.each_codepoint.with_index do |char1, i|
- e = i + 1
-
- str2_codepoint_enumerable.with_index do |char2, j|
- cost = (char1 == char2) ? 0 : 1
- x = [
- d[j + 1] + 1, # insertion
- e + 1, # deletion
- d[j] + cost # substitution
- ].min
- d[j] = e
- e = x
- end
-
- d[m] = x
- end
-
- x
- end
-
# Prints a list of generators.
def print_list(base, namespaces)
return if namespaces.empty?
diff --git a/railties/lib/rails/command/helpers/editor.rb b/railties/lib/rails/command/helpers/editor.rb
new file mode 100644
index 0000000000..6191d97672
--- /dev/null
+++ b/railties/lib/rails/command/helpers/editor.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require "active_support/encrypted_file"
+
+module Rails
+ module Command
+ module Helpers
+ module Editor
+ private
+ def ensure_editor_available(command:)
+ if ENV["EDITOR"].to_s.empty?
+ say "No $EDITOR to open file in. Assign one like this:"
+ say ""
+ say %(EDITOR="mate --wait" #{command})
+ say ""
+ say "For editors that fork and exit immediately, it's important to pass a wait flag,"
+ say "otherwise the credentials will be saved immediately with no chance to edit."
+
+ false
+ else
+ true
+ end
+ end
+
+ def catch_editing_exceptions
+ yield
+ rescue Interrupt
+ say "Aborted changing file: nothing saved."
+ rescue ActiveSupport::EncryptedFile::MissingKeyError => error
+ say error.message
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/command/spellchecker.rb b/railties/lib/rails/command/spellchecker.rb
new file mode 100644
index 0000000000..154358cd45
--- /dev/null
+++ b/railties/lib/rails/command/spellchecker.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Rails
+ module Command
+ module Spellchecker # :nodoc:
+ def self.suggest(word, from:)
+ DidYouMean::SpellChecker.new(dictionary: from.map(&:to_s)).correct(word).first
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb
index 1aea1e1a96..77961a0292 100644
--- a/railties/lib/rails/commands.rb
+++ b/railties/lib/rails/commands.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "command"
+require "rails/command"
aliases = {
"g" => "generate",
diff --git a/railties/lib/rails/commands/application/application_command.rb b/railties/lib/rails/commands/application/application_command.rb
index 13d47a63bc..f77553b830 100644
--- a/railties/lib/rails/commands/application/application_command.rb
+++ b/railties/lib/rails/commands/application/application_command.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "../../generators"
-require_relative "../../generators/rails/app/app_generator"
+require "rails/generators"
+require "rails/generators/rails/app/app_generator"
module Rails
module Generators
diff --git a/railties/lib/rails/commands/console/console_command.rb b/railties/lib/rails/commands/console/console_command.rb
index 5dc695c240..e35faa5b01 100644
--- a/railties/lib/rails/commands/console/console_command.rb
+++ b/railties/lib/rails/commands/console/console_command.rb
@@ -3,7 +3,7 @@
require "irb"
require "irb/completion"
-require_relative "../../command/environment_argument"
+require "rails/command/environment_argument"
module Rails
class Console
diff --git a/railties/lib/rails/commands/credentials/credentials_command.rb b/railties/lib/rails/commands/credentials/credentials_command.rb
index 88fb032d84..fa54c0362a 100644
--- a/railties/lib/rails/commands/credentials/credentials_command.rb
+++ b/railties/lib/rails/commands/credentials/credentials_command.rb
@@ -1,10 +1,13 @@
# frozen_string_literal: true
require "active_support"
+require "rails/command/helpers/editor"
module Rails
module Command
class CredentialsCommand < Rails::Command::Base # :nodoc:
+ include Helpers::Editor
+
no_commands do
def help
say "Usage:\n #{self.class.banner}"
@@ -16,43 +19,27 @@ module Rails
def edit
require_application_and_environment!
- ensure_editor_available || (return)
- ensure_master_key_has_been_added
+ ensure_editor_available(command: "bin/rails credentials:edit") || (return)
+ ensure_master_key_has_been_added if Rails.application.credentials.key.nil?
ensure_credentials_have_been_added
- change_credentials_in_system_editor
+ catch_editing_exceptions do
+ change_credentials_in_system_editor
+ end
say "New credentials encrypted and saved."
- rescue Interrupt
- say "Aborted changing credentials: nothing saved."
- rescue ActiveSupport::EncryptedFile::MissingKeyError => error
- say error.message
end
def show
require_application_and_environment!
- say Rails.application.credentials.read.presence ||
- "No credentials have been added yet. Use bin/rails credentials:edit to change that."
+
+ say Rails.application.credentials.read.presence || missing_credentials_message
end
private
- def ensure_editor_available
- if ENV["EDITOR"].to_s.empty?
- say "No $EDITOR to open credentials in. Assign one like this:"
- say ""
- say %(EDITOR="mate --wait" bin/rails credentials:edit)
- say ""
- say "For editors that fork and exit immediately, it's important to pass a wait flag,"
- say "otherwise the credentials will be saved immediately with no chance to edit."
-
- false
- else
- true
- end
- end
-
def ensure_master_key_has_been_added
master_key_generator.add_master_key_file
+ master_key_generator.ignore_master_key_file
end
def ensure_credentials_have_been_added
@@ -67,18 +54,26 @@ module Rails
def master_key_generator
- require_relative "../../generators"
- require_relative "../../generators/rails/master_key/master_key_generator"
+ require "rails/generators"
+ require "rails/generators/rails/master_key/master_key_generator"
Rails::Generators::MasterKeyGenerator.new
end
def credentials_generator
- require_relative "../../generators"
- require_relative "../../generators/rails/credentials/credentials_generator"
+ require "rails/generators"
+ require "rails/generators/rails/credentials/credentials_generator"
Rails::Generators::CredentialsGenerator.new
end
+
+ def missing_credentials_message
+ if Rails.application.credentials.key.nil?
+ "Missing master key to decrypt credentials. See bin/rails credentials:help"
+ else
+ "No credentials have been added yet. Use bin/rails credentials:edit to change that."
+ end
+ end
end
end
end
diff --git a/railties/lib/rails/commands/dbconsole/dbconsole_command.rb b/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
index 5234969743..806b7de6d6 100644
--- a/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
+++ b/railties/lib/rails/commands/dbconsole/dbconsole_command.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../command/environment_argument"
+require "rails/command/environment_argument"
module Rails
class DBConsole
@@ -97,7 +97,7 @@ module Rails
elsif configurations[environment].blank? && configurations[connection].blank?
raise ActiveRecord::AdapterNotSpecified, "'#{environment}' database is not configured. Available configuration: #{configurations.inspect}"
else
- configurations[environment].presence || configurations[connection]
+ configurations[connection] || configurations[environment].presence
end
end
end
diff --git a/railties/lib/rails/commands/destroy/destroy_command.rb b/railties/lib/rails/commands/destroy/destroy_command.rb
index 686193ddb9..dd432d28fd 100644
--- a/railties/lib/rails/commands/destroy/destroy_command.rb
+++ b/railties/lib/rails/commands/destroy/destroy_command.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../generators"
+require "rails/generators"
module Rails
module Command
diff --git a/railties/lib/rails/commands/encrypted/encrypted_command.rb b/railties/lib/rails/commands/encrypted/encrypted_command.rb
new file mode 100644
index 0000000000..3bc8f76ce4
--- /dev/null
+++ b/railties/lib/rails/commands/encrypted/encrypted_command.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require "pathname"
+require "active_support"
+require "rails/command/helpers/editor"
+
+module Rails
+ module Command
+ class EncryptedCommand < Rails::Command::Base # :nodoc:
+ include Helpers::Editor
+
+ class_option :key, aliases: "-k", type: :string,
+ default: "config/master.key", desc: "The Rails.root relative path to the encryption key"
+
+ no_commands do
+ def help
+ say "Usage:\n #{self.class.banner}"
+ say ""
+ end
+ end
+
+ def edit(file_path)
+ require_application_and_environment!
+ encrypted = Rails.application.encrypted(file_path, key_path: options[:key])
+
+ ensure_editor_available(command: "bin/rails encrypted:edit") || (return)
+ ensure_encryption_key_has_been_added(options[:key]) if encrypted.key.nil?
+ ensure_encrypted_file_has_been_added(file_path, options[:key])
+
+ catch_editing_exceptions do
+ change_encrypted_file_in_system_editor(file_path, options[:key])
+ end
+
+ say "File encrypted and saved."
+ rescue ActiveSupport::MessageEncryptor::InvalidMessage
+ say "Couldn't decrypt #{file_path}. Perhaps you passed the wrong key?"
+ end
+
+ def show(file_path)
+ require_application_and_environment!
+ encrypted = Rails.application.encrypted(file_path, key_path: options[:key])
+
+ say encrypted.read.presence || missing_encrypted_message(key: encrypted.key, key_path: options[:key], file_path: file_path)
+ end
+
+ private
+ def ensure_encryption_key_has_been_added(key_path)
+ encryption_key_file_generator.add_key_file(key_path)
+ encryption_key_file_generator.ignore_key_file(key_path)
+ end
+
+ def ensure_encrypted_file_has_been_added(file_path, key_path)
+ encrypted_file_generator.add_encrypted_file_silently(file_path, key_path)
+ end
+
+ def change_encrypted_file_in_system_editor(file_path, key_path)
+ Rails.application.encrypted(file_path, key_path: key_path).change do |tmp_path|
+ system("#{ENV["EDITOR"]} #{tmp_path}")
+ end
+ end
+
+
+ def encryption_key_file_generator
+ require "rails/generators"
+ require "rails/generators/rails/encryption_key_file/encryption_key_file_generator"
+
+ Rails::Generators::EncryptionKeyFileGenerator.new
+ end
+
+ def encrypted_file_generator
+ require "rails/generators"
+ require "rails/generators/rails/encrypted_file/encrypted_file_generator"
+
+ Rails::Generators::EncryptedFileGenerator.new
+ end
+
+ def missing_encrypted_message(key:, key_path:, file_path:)
+ if key.nil?
+ "Missing '#{key_path}' to decrypt data. See bin/rails encrypted:help"
+ else
+ "File '#{file_path}' does not exist. Use bin/rails encrypted:edit #{file_path} to change that."
+ end
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/generate/generate_command.rb b/railties/lib/rails/commands/generate/generate_command.rb
index 73f627637d..93d7a0ce3a 100644
--- a/railties/lib/rails/commands/generate/generate_command.rb
+++ b/railties/lib/rails/commands/generate/generate_command.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../generators"
+require "rails/generators"
module Rails
module Command
diff --git a/railties/lib/rails/commands/plugin/plugin_command.rb b/railties/lib/rails/commands/plugin/plugin_command.rb
index 5d3dfadf84..2b192abf9b 100644
--- a/railties/lib/rails/commands/plugin/plugin_command.rb
+++ b/railties/lib/rails/commands/plugin/plugin_command.rb
@@ -36,8 +36,8 @@ module Rails
private
def run_plugin_generator(plugin_args)
- require_relative "../../generators"
- require_relative "../../generators/rails/plugin/plugin_generator"
+ require "rails/generators"
+ require "rails/generators/rails/plugin/plugin_generator"
Rails::Generators::PluginGenerator.start plugin_args
end
end
diff --git a/railties/lib/rails/commands/routes/routes_command.rb b/railties/lib/rails/commands/routes/routes_command.rb
new file mode 100644
index 0000000000..b592a5212f
--- /dev/null
+++ b/railties/lib/rails/commands/routes/routes_command.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require "rails/command"
+
+module Rails
+ module Command
+ class RoutesCommand < Base # :nodoc:
+ class_option :controller, aliases: "-c", desc: "Filter by a specific controller, e.g. PostsController or Admin::PostsController."
+ class_option :grep, aliases: "-g", desc: "Grep routes by a specific pattern."
+ class_option :expanded, type: :boolean, aliases: "-E", desc: "Print routes expanded vertically with parts explained."
+
+ def perform(*)
+ require_application_and_environment!
+ require "action_dispatch/routing/inspector"
+
+ say inspector.format(formatter, routes_filter)
+ end
+
+ private
+ def inspector
+ ActionDispatch::Routing::RoutesInspector.new(Rails.application.routes.routes)
+ end
+
+ def formatter
+ if options.key?("expanded")
+ ActionDispatch::Routing::ConsoleFormatter::Expanded.new
+ else
+ ActionDispatch::Routing::ConsoleFormatter::Sheet.new
+ end
+ end
+
+ def routes_filter
+ options.symbolize_keys.slice(:controller, :grep)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/commands/runner/runner_command.rb b/railties/lib/rails/commands/runner/runner_command.rb
index cd9462e08f..30fbf04982 100644
--- a/railties/lib/rails/commands/runner/runner_command.rb
+++ b/railties/lib/rails/commands/runner/runner_command.rb
@@ -32,13 +32,13 @@ module Rails
ARGV.replace(command_argv)
if code_or_file == "-"
- eval($stdin.read, binding, "stdin")
+ eval($stdin.read, TOPLEVEL_BINDING, "stdin")
elsif File.exist?(code_or_file)
$0 = code_or_file
Kernel.load code_or_file
else
begin
- eval(code_or_file, binding, __FILE__, __LINE__)
+ eval(code_or_file, TOPLEVEL_BINDING, __FILE__, __LINE__)
rescue SyntaxError, NameError => error
$stderr.puts "Please specify a valid ruby command or the path of a script to run."
$stderr.puts "Run '#{self.class.executable} -h' for help."
diff --git a/railties/lib/rails/commands/secrets/secrets_command.rb b/railties/lib/rails/commands/secrets/secrets_command.rb
index d93c4de74e..a36ccf314c 100644
--- a/railties/lib/rails/commands/secrets/secrets_command.rb
+++ b/railties/lib/rails/commands/secrets/secrets_command.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "active_support"
-require_relative "../../secrets"
+require "rails/secrets"
module Rails
module Command
@@ -15,7 +15,7 @@ module Rails
end
def setup
- generator.start
+ deprecate_in_favor_of_credentials_and_exit
end
def edit
@@ -42,11 +42,10 @@ module Rails
rescue Rails::Secrets::MissingKeyError => error
say error.message
rescue Errno::ENOENT => error
- raise unless error.message =~ /secrets\.yml\.enc/
-
- Rails::Secrets.read_template_for_editing do |tmp_path|
- system("#{ENV["EDITOR"]} #{tmp_path}")
- generator.skip_secrets_file { setup }
+ if error.message =~ /secrets\.yml\.enc/
+ deprecate_in_favor_of_credentials_and_exit
+ else
+ raise
end
end
@@ -55,11 +54,11 @@ module Rails
end
private
- def generator
- require_relative "../../generators"
- require_relative "../../generators/rails/encrypted_secrets/encrypted_secrets_generator"
+ def deprecate_in_favor_of_credentials_and_exit
+ say "Encrypted secrets is deprecated in favor of credentials. Run:"
+ say "bin/rails credentials:help"
- Rails::Generators::EncryptedSecretsGenerator
+ exit 1
end
end
end
diff --git a/railties/lib/rails/commands/server/server_command.rb b/railties/lib/rails/commands/server/server_command.rb
index 785265d766..77b6c1f65d 100644
--- a/railties/lib/rails/commands/server/server_command.rb
+++ b/railties/lib/rails/commands/server/server_command.rb
@@ -6,7 +6,7 @@ require "action_dispatch"
require "rails"
require "active_support/deprecation"
require "active_support/core_ext/string/filters"
-require_relative "../../dev_caching"
+require "rails/dev_caching"
module Rails
class Server < ::Rack::Server
@@ -27,7 +27,7 @@ module Rails
app = super
if app.is_a?(Class)
ActiveSupport::Deprecation.warn(<<-MSG.squish)
- Use `Rails::Application` subclass to start the server is deprecated and will be removed in Rails 6.0.
+ Using `Rails::Application` subclass to start the server is deprecated and will be removed in Rails 6.0.
Please change `run #{app}` to `run Rails.application` in config.ru.
MSG
end
@@ -43,18 +43,22 @@ module Rails
ENV["RAILS_ENV"] ||= options[:environment]
end
- def start
- print_boot_information
+ def start(after_stop_callback = nil)
trap(:INT) { exit }
create_tmp_directories
setup_dev_caching
log_to_stdout if options[:log_stdout]
- super
+ super()
ensure
- # The '-h' option calls exit before @options is set.
- # If we call 'options' with it unset, we get double help banners.
- puts "Exiting" unless @options && options[:daemonize]
+ after_stop_callback.call if after_stop_callback
+ end
+
+ def serveable? # :nodoc:
+ server
+ true
+ rescue LoadError, NameError
+ false
end
def middleware
@@ -65,6 +69,10 @@ module Rails
super.merge(@default_options)
end
+ def served_url
+ "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}" unless use_puma?
+ end
+
private
def setup_dev_caching
if options[:environment] == "development"
@@ -72,13 +80,6 @@ module Rails
end
end
- def print_boot_information
- url = "on #{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}" unless use_puma?
- puts "=> Booting #{ActiveSupport::Inflector.demodulize(server)}"
- puts "=> Rails #{Rails.version} application starting in #{Rails.env} #{url}"
- puts "=> Run `rails server -h` for more startup options"
- end
-
def create_tmp_directories
%w(cache pids sockets).each do |dir_to_make|
FileUtils.mkdir_p(File.join(Rails.root, "tmp", dir_to_make))
@@ -108,9 +109,15 @@ module Rails
module Command
class ServerCommand < Base # :nodoc:
+ # Hard-coding a bunch of handlers here as we don't have a public way of
+ # querying them from the Rack::Handler registry.
+ RACK_SERVERS = %w(cgi fastcgi webrick lsws scgi thin puma unicorn)
+
DEFAULT_PORT = 3000
DEFAULT_PID_PATH = "tmp/pids/server.pid".freeze
+ argument :using, optional: true
+
class_option :port, aliases: "-p", type: :numeric,
desc: "Runs Rails on the specified port - defaults to 3000.", banner: :port
class_option :binding, aliases: "-b", type: :string,
@@ -122,28 +129,39 @@ module Rails
desc: "Runs server as a Daemon."
class_option :environment, aliases: "-e", type: :string,
desc: "Specifies the environment to run this server under (development/test/production).", banner: :name
+ class_option :using, aliases: "-u", type: :string,
+ desc: "Specifies the Rack server used to run the application (thin/puma/webrick).", banner: :name
class_option :pid, aliases: "-P", type: :string, default: DEFAULT_PID_PATH,
desc: "Specifies the PID file."
class_option "dev-caching", aliases: "-C", type: :boolean, default: nil,
desc: "Specifies whether to perform caching in development."
class_option "restart", type: :boolean, default: nil, hide: true
+ class_option "early_hints", type: :boolean, default: nil, desc: "Enables HTTP/2 early hints."
def initialize(args = [], local_options = {}, config = {})
@original_options = local_options
super
- @server = self.args.shift
+ @using = deprecated_positional_rack_server(using) || options[:using]
@log_stdout = options[:daemon].blank? && (options[:environment] || Rails.env) == "development"
end
def perform
set_application_directory!
prepare_restart
+
Rails::Server.new(server_options).tap do |server|
# Require application after server sets environment to propagate
# the --environment option.
require APP_PATH
Dir.chdir(Rails.application.root)
- server.start
+
+ if server.serveable?
+ print_boot_information(server.server, server.served_url)
+ after_stop_callback = -> { say "Exiting" unless options[:daemon] }
+ server.start(after_stop_callback)
+ else
+ say rack_server_suggestion(using)
+ end
end
end
@@ -151,7 +169,7 @@ module Rails
def server_options
{
user_supplied_options: user_supplied_options,
- server: @server,
+ server: using,
log_stdout: @log_stdout,
Port: port,
Host: host,
@@ -161,7 +179,8 @@ module Rails
daemonize: options[:daemon],
pid: pid,
caching: options["dev-caching"],
- restart_cmd: restart_command
+ restart_cmd: restart_command,
+ early_hints: early_hints
}
end
end
@@ -200,7 +219,7 @@ module Rails
user_supplied_options << name
end
end
- user_supplied_options << :Host if ENV["HOST"]
+ user_supplied_options << :Host if ENV["HOST"] || ENV["BINDING"]
user_supplied_options << :Port if ENV["PORT"]
user_supplied_options.uniq
end
@@ -215,7 +234,17 @@ module Rails
options[:binding]
else
default_host = environment == "development" ? "localhost" : "0.0.0.0"
- ENV.fetch("HOST", default_host)
+
+ if ENV["HOST"] && !ENV["BINDING"]
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ Using the `HOST` environment to specify the IP is deprecated and will be removed in Rails 6.1.
+ Please use `BINDING` environment instead.
+ MSG
+
+ return ENV["HOST"]
+ end
+
+ ENV.fetch("BINDING", default_host)
end
end
@@ -224,7 +253,11 @@ module Rails
end
def restart_command
- "bin/rails server #{@server} #{@original_options.join(" ")} --restart"
+ "bin/rails server #{using} #{@original_options.join(" ")} --restart"
+ end
+
+ def early_hints
+ options[:early_hints]
end
def pid
@@ -232,12 +265,50 @@ module Rails
end
def self.banner(*)
- "rails server [puma, thin etc] [options]"
+ "rails server [thin/puma/webrick] [options]"
end
def prepare_restart
FileUtils.rm_f(options[:pid]) if options[:restart]
end
+
+ def deprecated_positional_rack_server(value)
+ if value
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
+ Passing the Rack server name as a regular argument is deprecated
+ and will be removed in the next Rails version. Please, use the -u
+ option instead.
+ MSG
+ value
+ end
+ end
+
+ def rack_server_suggestion(server)
+ if server.in?(RACK_SERVERS)
+ <<~MSG
+ Could not load server "#{server}". Maybe you need to the add it to the Gemfile?
+
+ gem "#{server}"
+
+ Run `rails server --help` for more options.
+ MSG
+ else
+ suggestions = Rails::Command::Spellchecker.suggest(server, from: RACK_SERVERS)
+
+ <<~MSG
+ Could not find server "#{server}". Maybe you meant #{suggestions.inspect}?
+ Run `rails server --help` for more options.
+ MSG
+ end
+ end
+
+ def print_boot_information(server, url)
+ say <<~MSG
+ => Booting #{ActiveSupport::Inflector.demodulize(server)}
+ => Rails #{Rails.version} application starting in #{Rails.env} #{url}
+ => Run `rails server --help` for more startup options
+ MSG
+ end
end
end
end
diff --git a/railties/lib/rails/commands/test/test_command.rb b/railties/lib/rails/commands/test/test_command.rb
index a2216553ca..00ea9ac4a6 100644
--- a/railties/lib/rails/commands/test/test_command.rb
+++ b/railties/lib/rails/commands/test/test_command.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require_relative "../../command"
-require_relative "../../test_unit/runner"
-require_relative "../../test_unit/reporter"
+require "rails/command"
+require "rails/test_unit/runner"
+require "rails/test_unit/reporter"
module Rails
module Command
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 70815d114d..d3a54d9364 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -2,8 +2,8 @@
require "active_support/ordered_options"
require "active_support/core_ext/object"
-require_relative "paths"
-require_relative "rack"
+require "rails/paths"
+require "rails/rack"
module Rails
module Configuration
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index cc2030d37d..6a13a84108 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "railtie"
-require_relative "engine/railties"
+require "rails/railtie"
+require "rails/engine/railties"
require "active_support/core_ext/module/delegation"
require "pathname"
require "thread"
@@ -439,8 +439,8 @@ module Rails
# Load console and invoke the registered hooks.
# Check <tt>Rails::Railtie.console</tt> for more info.
def load_console(app = self)
- require_relative "console/app"
- require_relative "console/helpers"
+ require "rails/console/app"
+ require "rails/console/helpers"
run_console_blocks(app)
self
end
@@ -463,7 +463,7 @@ module Rails
# Load Rails generators and invoke the registered hooks.
# Check <tt>Rails::Railtie.generators</tt> for more info.
def load_generators(app = self)
- require_relative "generators"
+ require "rails/generators"
run_generators_blocks(app)
Rails::Generators.configure!(app.config.generators)
self
diff --git a/railties/lib/rails/engine/commands.rb b/railties/lib/rails/engine/commands.rb
index 3854907507..05218640c6 100644
--- a/railties/lib/rails/engine/commands.rb
+++ b/railties/lib/rails/engine/commands.rb
@@ -6,4 +6,4 @@ unless defined?(APP_PATH)
end
end
-require_relative "../commands"
+require "rails/commands"
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 16ba7f9eb8..6bf0406b21 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../railtie/configuration"
+require "rails/railtie/configuration"
module Rails
class Engine
diff --git a/railties/lib/rails/engine/updater.rb b/railties/lib/rails/engine/updater.rb
index 21a0fc5562..be7a47124a 100644
--- a/railties/lib/rails/engine/updater.rb
+++ b/railties/lib/rails/engine/updater.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "../generators"
-require_relative "../generators/rails/plugin/plugin_generator"
+require "rails/generators"
+require "rails/generators/rails/plugin/plugin_generator"
module Rails
class Engine
diff --git a/railties/lib/rails/gem_version.rb b/railties/lib/rails/gem_version.rb
index 92b5e0392a..54bfbdd516 100644
--- a/railties/lib/rails/gem_version.rb
+++ b/railties/lib/rails/gem_version.rb
@@ -7,8 +7,8 @@ module Rails
end
module VERSION
- MAJOR = 5
- MINOR = 2
+ MAJOR = 6
+ MINOR = 0
TINY = 0
PRE = "alpha"
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index a630d55e59..f8460bd4ee 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -4,7 +4,7 @@ activesupport_path = File.expand_path("../../../activesupport/lib", __dir__)
$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
require "thor/group"
-require_relative "command"
+require "rails/command"
require "active_support"
require "active_support/core_ext/object/blank"
@@ -218,6 +218,10 @@ module Rails
rails.delete("app")
rails.delete("plugin")
rails.delete("encrypted_secrets")
+ rails.delete("encrypted_file")
+ rails.delete("encryption_key_file")
+ rails.delete("master_key")
+ rails.delete("credentials")
hidden_namespaces.each { |n| groups.delete(n.to_s) }
@@ -272,11 +276,11 @@ module Rails
klass.start(args, config)
else
options = sorted_groups.flat_map(&:last)
- suggestions = options.sort_by { |suggested| levenshtein_distance(namespace.to_s, suggested) }.first(3)
- msg = "Could not find generator '#{namespace}'. ".dup
- msg << "Maybe you meant #{ suggestions.map { |s| "'#{s}'" }.to_sentence(last_word_connector: " or ", locale: :en) }\n"
- msg << "Run `rails generate --help` for more options."
- puts msg
+ suggestion = Rails::Command::Spellchecker.suggest(namespace.to_s, from: options)
+ puts <<~MSG
+ Could not find generator '#{namespace}'. Maybe you meant #{suggestion.inspect}?
+ Run `rails generate --help` for more options.
+ MSG
end
end
diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb
index 9800e5750a..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
@@ -221,6 +223,7 @@ module Rails
# rake("db:migrate")
# rake("db:migrate", env: "production")
# rake("gems:install", sudo: true)
+ # rake("gems:install", capture: true)
def rake(command, options = {})
execute_command :rake, command, options
end
@@ -230,6 +233,7 @@ module Rails
# rails_command("db:migrate")
# rails_command("db:migrate", env: "production")
# rails_command("gems:install", sudo: true)
+ # rails_command("gems:install", capture: true)
def rails_command(command, options = {})
execute_command :rails, command, options
end
@@ -292,7 +296,11 @@ module Rails
log executor, command
env = options[:env] || ENV["RAILS_ENV"] || "development"
sudo = options[:sudo] && !Gem.win_platform? ? "sudo " : ""
- in_root { run("#{sudo}#{extify(executor)} #{command} RAILS_ENV=#{env}", verbose: false) }
+ config = { verbose: false }
+
+ config.merge!(capture: options[:capture]) if options[:capture]
+
+ in_root { run("#{sudo}#{extify(executor)} #{command} RAILS_ENV=#{env}", config) }
end
# Add an extension to the given name based on the platform.
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index c8688fb7f3..f51542f3ec 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -2,11 +2,10 @@
require "fileutils"
require "digest/md5"
-require "active_support/core_ext/string/strip"
-require_relative "../version" unless defined?(Rails::VERSION)
+require "rails/version" unless defined?(Rails::VERSION)
require "open-uri"
require "uri"
-require_relative "../generators"
+require "rails/generators"
require "active_support/core_ext/array/extract_options"
module Rails
@@ -26,75 +25,81 @@ module Rails
end
def self.add_shared_options_for(name)
- class_option :template, type: :string, aliases: "-m",
- desc: "Path to some #{name} template (can be a filesystem path or URL)"
+ class_option :template, type: :string, aliases: "-m",
+ desc: "Path to some #{name} template (can be a filesystem path or URL)"
- class_option :database, type: :string, aliases: "-d", default: "sqlite3",
- desc: "Preconfigure for selected database (options: #{DATABASES.join('/')})"
+ 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_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"
+ class_option :skip_gemfile, type: :boolean, default: false,
+ desc: "Don't create a Gemfile"
- class_option :skip_git, type: :boolean, aliases: "-G", default: false,
- desc: "Skip .gitignore file"
+ class_option :skip_git, type: :boolean, aliases: "-G", default: false,
+ desc: "Skip .gitignore file"
- class_option :skip_keeps, type: :boolean, default: false,
- desc: "Skip source control .keep files"
+ class_option :skip_keeps, type: :boolean, default: false,
+ desc: "Skip source control .keep files"
- class_option :skip_action_mailer, type: :boolean, aliases: "-M",
- default: false,
- desc: "Skip Action Mailer files"
+ class_option :skip_action_mailer, type: :boolean, aliases: "-M",
+ default: false,
+ desc: "Skip Action Mailer files"
- class_option :skip_active_record, type: :boolean, aliases: "-O", default: false,
- desc: "Skip Active Record files"
+ class_option :skip_active_record, type: :boolean, aliases: "-O", default: false,
+ desc: "Skip Active Record files"
- class_option :skip_puma, type: :boolean, aliases: "-P", default: false,
- desc: "Skip Puma related files"
+ class_option :skip_active_storage, type: :boolean, default: false,
+ desc: "Skip Active Storage files"
- class_option :skip_action_cable, type: :boolean, aliases: "-C", default: false,
- desc: "Skip Action Cable files"
+ class_option :skip_puma, type: :boolean, aliases: "-P", default: false,
+ desc: "Skip Puma related files"
- class_option :skip_sprockets, type: :boolean, aliases: "-S", default: false,
- desc: "Skip Sprockets files"
+ class_option :skip_action_cable, type: :boolean, aliases: "-C", default: false,
+ desc: "Skip Action Cable files"
- class_option :skip_spring, type: :boolean, default: false,
- desc: "Don't install Spring application preloader"
+ class_option :skip_sprockets, type: :boolean, aliases: "-S", default: false,
+ desc: "Skip Sprockets files"
- class_option :skip_listen, type: :boolean, default: false,
- desc: "Don't generate configuration that depends on the listen gem"
+ class_option :skip_spring, type: :boolean, default: false,
+ desc: "Don't install Spring application preloader"
- class_option :skip_coffee, type: :boolean, default: false,
- desc: "Don't use CoffeeScript"
+ class_option :skip_listen, type: :boolean, default: false,
+ desc: "Don't generate configuration that depends on the listen gem"
- class_option :skip_javascript, type: :boolean, aliases: "-J", default: false,
- desc: "Skip JavaScript files"
+ class_option :skip_coffee, type: :boolean, default: false,
+ desc: "Don't use CoffeeScript"
- class_option :skip_turbolinks, type: :boolean, default: false,
- desc: "Skip turbolinks gem"
+ class_option :skip_javascript, type: :boolean, aliases: "-J", default: false,
+ desc: "Skip JavaScript files"
- class_option :skip_test, type: :boolean, aliases: "-T", default: false,
- desc: "Skip test files"
+ class_option :skip_turbolinks, type: :boolean, default: false,
+ desc: "Skip turbolinks gem"
- class_option :skip_system_test, type: :boolean, default: false,
- desc: "Skip system test files"
+ class_option :skip_test, type: :boolean, aliases: "-T", default: false,
+ desc: "Skip test files"
- class_option :dev, type: :boolean, default: false,
- desc: "Setup the #{name} with Gemfile pointing to your Rails checkout"
+ class_option :skip_system_test, type: :boolean, default: false,
+ desc: "Skip system test files"
- class_option :edge, type: :boolean, default: false,
- desc: "Setup the #{name} with Gemfile pointing to Rails repository"
+ class_option :skip_bootsnap, type: :boolean, default: false,
+ desc: "Skip bootsnap gem"
- class_option :rc, type: :string, default: nil,
- desc: "Path to file containing extra configuration options for rails command"
+ class_option :dev, type: :boolean, default: false,
+ desc: "Setup the #{name} with Gemfile pointing to your Rails checkout"
- class_option :no_rc, type: :boolean, default: false,
- desc: "Skip loading of extra configuration options from .railsrc file"
+ class_option :edge, type: :boolean, default: false,
+ desc: "Setup the #{name} with Gemfile pointing to Rails repository"
- class_option :help, type: :boolean, aliases: "-h", group: :rails,
- desc: "Show this help message and quit"
+ class_option :rc, type: :string, default: nil,
+ desc: "Path to file containing extra configuration options for rails command"
+
+ class_option :no_rc, type: :boolean, default: false,
+ desc: "Skip loading of extra configuration options from .railsrc file"
+
+ class_option :help, type: :boolean, aliases: "-h", group: :rails,
+ desc: "Show this help message and quit"
end
def initialize(*args)
@@ -189,15 +194,33 @@ module Rails
def webserver_gemfile_entry # :doc:
return [] if options[:skip_puma]
comment = "Use Puma as the app server"
- GemfileEntry.new("puma", "~> 3.7", comment)
+ GemfileEntry.new("puma", "~> 3.11", comment)
end
def include_all_railties? # :doc:
- options.values_at(:skip_active_record, :skip_action_mailer, :skip_test, :skip_sprockets, :skip_action_cable).none?
+ [
+ options.values_at(
+ :skip_active_record,
+ :skip_action_mailer,
+ :skip_test,
+ :skip_sprockets,
+ :skip_action_cable
+ ),
+ skip_active_storage?
+ ].flatten.none?
end
def comment_if(value) # :doc:
- options[value] ? "# " : ""
+ question = "#{value}?"
+
+ comment =
+ if respond_to?(question, true)
+ send(question)
+ else
+ options[value]
+ end
+
+ comment ? "# " : ""
end
def keeps? # :doc:
@@ -208,6 +231,10 @@ module Rails
!options[:skip_active_record] && options[:database] == "sqlite3"
end
+ def skip_active_storage? # :doc:
+ options[:skip_active_storage] || options[:skip_active_record]
+ end
+
class GemfileEntry < Struct.new(:name, :version, :comment, :options, :commented_out)
def initialize(name, version, comment, options = {}, commented_out = false)
super
@@ -241,17 +268,14 @@ module Rails
end
def rails_gemfile_entry
- dev_edge_common = [
- GemfileEntry.github("arel", "rails/arel"),
- ]
if options.dev?
[
GemfileEntry.path("rails", Rails::Generators::RAILS_DEV_PATH)
- ] + dev_edge_common
+ ]
elsif options.edge?
[
GemfileEntry.github("rails", "rails/rails")
- ] + dev_edge_common
+ ]
else
[GemfileEntry.version("rails",
rails_version_specifier,
@@ -275,8 +299,8 @@ module Rails
def gem_for_database
# %w( mysql postgresql sqlite3 oracle frontbase ibm_db sqlserver jdbcmysql jdbcsqlite3 jdbcpostgresql )
case options[:database]
- when "mysql" then ["mysql2", [">= 0.3.18", "< 0.5"]]
- when "postgresql" then ["pg", ["~> 0.18"]]
+ when "mysql" then ["mysql2", [">= 0.4.4", "< 0.6.0"]]
+ when "postgresql" then ["pg", [">= 0.18", "< 2.0"]]
when "oracle" then ["activerecord-oracle_enhanced-adapter", nil]
when "frontbase" then ["ruby-frontbase", nil]
when "sqlserver" then ["activerecord-sqlserver-adapter", nil]
@@ -290,11 +314,13 @@ module Rails
def convert_database_option_for_jruby
if defined?(JRUBY_VERSION)
- case options[:database]
- when "postgresql" then options[:database].replace "jdbcpostgresql"
- when "mysql" then options[:database].replace "jdbcmysql"
- when "sqlite3" then options[:database].replace "jdbcsqlite3"
+ opt = options.dup
+ case opt[:database]
+ when "postgresql" then opt[:database] = "jdbcpostgresql"
+ when "mysql" then opt[:database] = "jdbcmysql"
+ when "sqlite3" then opt[:database] = "jdbcsqlite3"
end
+ self.options = opt.freeze
end
end
@@ -369,7 +395,7 @@ module Rails
return [] if options[:skip_action_cable]
comment = "Use Redis adapter to run Action Cable in production"
gems = []
- gems << GemfileEntry.new("redis", "~> 3.0", comment, {}, true)
+ gems << GemfileEntry.new("redis", "~> 4.0", comment, {}, true)
gems
end
@@ -413,6 +439,10 @@ module Rails
!options[:skip_listen] && os_supports_listen_out_of_the_box?
end
+ def depend_on_bootsnap?
+ !options[:skip_bootsnap] && !options[:dev] && !defined?(JRUBY_VERSION)
+ end
+
def os_supports_listen_out_of_the_box?
RbConfig::CONFIG["host_os"] =~ /darwin|linux/
end
diff --git a/railties/lib/rails/generators/css/assets/assets_generator.rb b/railties/lib/rails/generators/css/assets/assets_generator.rb
index 5f7be769b2..f657d1e50f 100644
--- a/railties/lib/rails/generators/css/assets/assets_generator.rb
+++ b/railties/lib/rails/generators/css/assets/assets_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../named_base"
+require "rails/generators/named_base"
module Css # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb
index 5996cb1483..89c560f382 100644
--- a/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/css/scaffold/scaffold_generator.rb
@@ -1,17 +1,17 @@
# frozen_string_literal: true
-require_relative "../../named_base"
+require "rails/generators/named_base"
module Css # :nodoc:
module Generators # :nodoc:
class ScaffoldGenerator < Rails::Generators::NamedBase # :nodoc:
+ source_root Rails::Generators::ScaffoldGenerator.source_root
+
# In order to allow the Sass generators to pick up the default Rails CSS and
# transform it, we leave it in a standard location for the CSS stylesheet
# generators to handle. For the simple, default case, just copy it over.
def copy_stylesheet
- dir = Rails::Generators::ScaffoldGenerator.source_root
- file = File.join(dir, "scaffold.css")
- create_file "app/assets/stylesheets/scaffold.css", File.read(file)
+ copy_file "scaffold.css", "app/assets/stylesheets/scaffold.css"
end
end
end
diff --git a/railties/lib/rails/generators/erb.rb b/railties/lib/rails/generators/erb.rb
index 2c20834611..ba20bcd32a 100644
--- a/railties/lib/rails/generators/erb.rb
+++ b/railties/lib/rails/generators/erb.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "named_base"
+require "rails/generators/named_base"
module Erb # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/erb/controller/controller_generator.rb b/railties/lib/rails/generators/erb/controller/controller_generator.rb
index 1a6c84288b..8e13744b2a 100644
--- a/railties/lib/rails/generators/erb/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/erb/controller/controller_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../erb"
+require "rails/generators/erb"
module Erb # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/erb/controller/templates/view.html.erb b/railties/lib/rails/generators/erb/controller/templates/view.html.erb.tt
index cd54d13d83..cd54d13d83 100644
--- a/railties/lib/rails/generators/erb/controller/templates/view.html.erb
+++ b/railties/lib/rails/generators/erb/controller/templates/view.html.erb.tt
diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
index 5774d86c8e..997602cb8c 100644
--- a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../erb"
+require "rails/generators/erb"
module Erb # :nodoc:
module Generators # :nodoc:
@@ -35,7 +35,7 @@ module Erb # :nodoc:
end
def file_name
- @_file_name ||= super.gsub(/_mailer/i, "")
+ @_file_name ||= super.sub(/_mailer\z/i, "")
end
end
end
diff --git a/railties/lib/rails/generators/erb/mailer/templates/view.html.erb b/railties/lib/rails/generators/erb/mailer/templates/view.html.erb.tt
index b5045671b3..b5045671b3 100644
--- a/railties/lib/rails/generators/erb/mailer/templates/view.html.erb
+++ b/railties/lib/rails/generators/erb/mailer/templates/view.html.erb.tt
diff --git a/railties/lib/rails/generators/erb/mailer/templates/view.text.erb b/railties/lib/rails/generators/erb/mailer/templates/view.text.erb.tt
index 342285df19..342285df19 100644
--- a/railties/lib/rails/generators/erb/mailer/templates/view.text.erb
+++ b/railties/lib/rails/generators/erb/mailer/templates/view.text.erb.tt
diff --git a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
index e80c6d4b7d..2fc04e4094 100644
--- a/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/erb/scaffold/scaffold_generator.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "../../erb"
-require_relative "../../resource_helpers"
+require "rails/generators/erb"
+require "rails/generators/resource_helpers"
module Erb # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt
index 4f2e84f924..518cb1121e 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt
@@ -1,4 +1,4 @@
-<%%= form_with(model: <%= singular_table_name %>, local: true) do |form| %>
+<%%= form_with(model: <%= model_resource_name %>, local: true) do |form| %>
<%% if <%= singular_table_name %>.errors.any? %>
<div id="error_explanation">
<h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
@@ -15,15 +15,15 @@
<div class="field">
<% if attribute.password_digest? -%>
<%%= form.label :password %>
- <%%= form.password_field :password, id: :<%= field_id(:password) %> %>
+ <%%= form.password_field :password %>
</div>
<div class="field">
<%%= form.label :password_confirmation %>
- <%%= form.password_field :password_confirmation, id: :<%= field_id(:password_confirmation) %> %>
+ <%%= form.password_field :password_confirmation %>
<% else -%>
<%%= form.label :<%= attribute.column_name %> %>
- <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, id: :<%= field_id(attribute.column_name) %> %>
+ <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %> %>
<% end -%>
</div>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt
index 81329473d9..81329473d9 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt
index 5f4904fee1..e1ede7c713 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt
@@ -18,9 +18,9 @@
<% attributes.reject(&:password_digest?).each do |attribute| -%>
<td><%%= <%= singular_table_name %>.<%= attribute.name %> %></td>
<% end -%>
- <td><%%= link_to 'Show', <%= singular_table_name %> %></td>
- <td><%%= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>) %></td>
- <td><%%= link_to 'Destroy', <%= singular_table_name %>, method: :delete, data: { confirm: 'Are you sure?' } %></td>
+ <td><%%= link_to 'Show', <%= model_resource_name %> %></td>
+ <td><%%= link_to 'Edit', edit_<%= singular_route_name %>_path(<%= singular_table_name %>) %></td>
+ <td><%%= link_to 'Destroy', <%= model_resource_name %>, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<%% end %>
</tbody>
@@ -28,4 +28,4 @@
<br>
-<%%= link_to 'New <%= singular_table_name.titleize %>', new_<%= singular_table_name %>_path %>
+<%%= link_to 'New <%= singular_table_name.titleize %>', new_<%= singular_route_name %>_path %>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt
index 9b2b2f4875..9b2b2f4875 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt
index 5e634153be..5e634153be 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb.tt
diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb
index 2728459968..f7fd30a5fb 100644
--- a/railties/lib/rails/generators/generated_attribute.rb
+++ b/railties/lib/rails/generators/generated_attribute.rb
@@ -75,7 +75,7 @@ module Rails
when :date then :date_select
when :text then :text_area
when :boolean then :check_box
- else
+ else
:text_field
end
end
@@ -91,7 +91,7 @@ module Rails
when :text then "MyText"
when :boolean then false
when :references, :belongs_to then nil
- else
+ else
""
end
end
diff --git a/railties/lib/rails/generators/js/assets/assets_generator.rb b/railties/lib/rails/generators/js/assets/assets_generator.rb
index ea151aa04e..9d32c666dc 100644
--- a/railties/lib/rails/generators/js/assets/assets_generator.rb
+++ b/railties/lib/rails/generators/js/assets/assets_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../named_base"
+require "rails/generators/named_base"
module Js # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/migration.rb b/railties/lib/rails/generators/migration.rb
index 7162b8c0b4..5081060895 100644
--- a/railties/lib/rails/generators/migration.rb
+++ b/railties/lib/rails/generators/migration.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require "active_support/concern"
-require_relative "actions/create_migration"
+require "rails/generators/actions/create_migration"
module Rails
module Generators
@@ -63,7 +63,12 @@ module Rails
numbered_destination = File.join(dir, ["%migration_number%", base].join("_"))
create_migration numbered_destination, nil, config do
- ERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
+ match = ERB.version.match(/\Aerb\.rb \[(?<version>[^ ]+) /)
+ if match && match[:version] >= "2.2.0" # Ruby 2.6+
+ ERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer").result(context)
+ else
+ ERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context)
+ end
end
end
end
diff --git a/railties/lib/rails/generators/model_helpers.rb b/railties/lib/rails/generators/model_helpers.rb
index aa3564476a..50078404b3 100644
--- a/railties/lib/rails/generators/model_helpers.rb
+++ b/railties/lib/rails/generators/model_helpers.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "active_model"
+require "rails/generators/active_model"
module Rails
module Generators
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index fe8447be23..d6732f8ff1 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
-require "active_support/core_ext/module/introspection"
-require_relative "base"
-require_relative "generated_attribute"
+require "rails/generators/base"
+require "rails/generators/generated_attribute"
module Rails
module Generators
@@ -32,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.
@@ -100,11 +95,11 @@ module Rails
end
def index_helper # :doc:
- uncountable? ? "#{plural_table_name}_index" : plural_table_name
+ uncountable? ? "#{plural_route_name}_index" : plural_route_name
end
def show_helper # :doc:
- "#{singular_table_name}_url(@#{singular_table_name})"
+ "#{singular_route_name}_url(@#{singular_table_name})"
end
def edit_helper # :doc:
@@ -112,11 +107,7 @@ module Rails
end
def new_helper # :doc:
- "new_#{singular_table_name}_url"
- end
-
- def field_id(attribute_name)
- [singular_table_name, attribute_name].join("_")
+ "new_#{singular_route_name}_url"
end
def singular_table_name # :doc:
@@ -152,6 +143,35 @@ module Rails
end
end
+ def redirect_resource_name # :doc:
+ model_resource_name(prefix: "@")
+ end
+
+ def model_resource_name(prefix: "") # :doc:
+ resource_name = "#{prefix}#{singular_table_name}"
+ if options[:model_name]
+ "[#{controller_class_path.map { |name| ":" + name }.join(", ")}, #{resource_name}]"
+ else
+ resource_name
+ end
+ end
+
+ def singular_route_name # :doc:
+ if options[:model_name]
+ "#{controller_class_path.join('_')}_#{singular_table_name}"
+ else
+ singular_table_name
+ end
+ end
+
+ def plural_route_name # :doc:
+ if options[:model_name]
+ "#{controller_class_path.join('_')}_#{plural_table_name}"
+ else
+ plural_table_name
+ end
+ end
+
def assign_names!(name)
@class_path = name.include?("/") ? name.split("/") : name.split("::")
@class_path.map!(&:underscore)
@@ -193,7 +213,7 @@ module Rails
#
def self.check_class_collision(options = {}) # :doc:
define_method :check_class_collision do
- name = if respond_to?(:controller_class_name) # for ScaffoldBase
+ name = if respond_to?(:controller_class_name) # for ResourceHelpers
controller_class_name
else
class_name
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index ac82ff6633..395ac7ef2f 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../app_base"
+require "rails/generators/app_base"
module Rails
module ActionMethods # :nodoc:
@@ -69,7 +69,7 @@ module Rails
def version_control
if !options[:skip_git] && !options[:pretend]
- run "git init"
+ run "git init", capture: options[:quiet]
end
end
@@ -114,7 +114,7 @@ module Rails
template "cable.yml" unless options[:skip_action_cable]
template "puma.rb" unless options[:skip_puma]
template "spring.rb" if spring_install?
- template "storage.yml"
+ template "storage.yml" unless skip_active_storage?
directory "environments"
directory "initializers"
@@ -128,6 +128,9 @@ module Rails
active_storage_config_exist = File.exist?("config/storage.yml")
rack_cors_config_exist = File.exist?("config/initializers/cors.rb")
assets_config_exist = File.exist?("config/initializers/assets.rb")
+ csp_config_exist = File.exist?("config/initializers/content_security_policy.rb")
+
+ @config_target_version = Rails.application.config.loaded_config_version || "5.0"
config
@@ -139,7 +142,7 @@ module Rails
template "config/cable.yml"
end
- if !active_storage_config_exist
+ if !skip_active_storage? && !active_storage_config_exist
template "config/storage.yml"
end
@@ -155,27 +158,27 @@ module Rails
unless assets_config_exist
remove_file "config/initializers/assets.rb"
end
+
+ unless csp_config_exist
+ remove_file "config/initializers/content_security_policy.rb"
+ end
end
end
def master_key
- return if options[:pretend]
-
- require_relative "../master_key/master_key_generator"
+ return if options[:pretend] || options[:dummy_app]
- after_bundle do
- Rails::Generators::MasterKeyGenerator.new.add_master_key_file
- end
+ require "rails/generators/rails/master_key/master_key_generator"
+ master_key_generator = Rails::Generators::MasterKeyGenerator.new([], quiet: options[:quiet], force: options[:force])
+ master_key_generator.add_master_key_file_silently
+ master_key_generator.ignore_master_key_file_silently
end
def credentials
- return if options[:pretend]
-
- require_relative "../credentials/credentials_generator"
+ return if options[:pretend] || options[:dummy_app]
- after_bundle do
- Rails::Generators::CredentialsGenerator.new.add_credentials_file_silently
- end
+ require "rails/generators/rails/credentials/credentials_generator"
+ Rails::Generators::CredentialsGenerator.new([], quiet: options[:quiet]).add_credentials_file_silently
end
def database_yml
@@ -232,6 +235,10 @@ module Rails
def vendor
empty_directory_with_keep_file "vendor"
end
+
+ def config_target_version
+ defined?(@config_target_version) ? @config_target_version : Rails::VERSION::STRING.to_f
+ end
end
module Generators
@@ -241,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"
@@ -347,6 +354,14 @@ module Rails
build(:public_directory)
end
+ def create_tmp_files
+ build(:tmp)
+ end
+
+ def create_vendor_files
+ build(:vendor)
+ end
+
def create_test_files
build(:test) unless options[:skip_test]
end
@@ -355,12 +370,8 @@ module Rails
build(:system_test) if depends_on_system_test?
end
- def create_tmp_files
- build(:tmp)
- end
-
- def create_vendor_files
- build(:vendor)
+ def create_storage_files
+ build(:storage) unless skip_active_storage?
end
def delete_app_assets_if_api_option
@@ -378,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
@@ -432,6 +447,7 @@ module Rails
def delete_non_api_initializers_if_api_option
if options[:api]
remove_file "config/initializers/cookies_serializer.rb"
+ remove_file "config/initializers/content_security_policy.rb"
end
end
@@ -443,7 +459,7 @@ module Rails
def delete_new_framework_defaults
unless options[:update]
- remove_file "config/initializers/new_framework_defaults_5_2.rb"
+ remove_file "config/initializers/new_framework_defaults_6_0.rb"
end
end
@@ -509,10 +525,6 @@ module Rails
end
end
- def app_secret
- SecureRandom.hex(64)
- end
-
def mysql_socket
@mysql_socket ||= [
"/tmp/mysql.sock", # default
@@ -559,7 +571,7 @@ module Rails
def handle_version_request!(argument)
if ["--version", "-v"].include?(argument)
- require_relative "../../../version"
+ require "rails/version"
puts "Rails #{Rails::VERSION::STRING}"
exit(0)
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
index 770247d8ca..1567333023 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
@@ -20,16 +20,20 @@ ruby <%= "'#{RUBY_VERSION}'" -%>
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
+<% unless skip_active_storage? -%>
# Use ActiveStorage variant
-# gem 'mini_magick', '~> 4.8'
+# gem 'image_processing', '~> 1.2'
+<% end -%>
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
+<% if depend_on_bootsnap? -%>
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
+<%- end -%>
<%- if options.api? -%>
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
# gem 'rack-cors'
@@ -39,11 +43,6 @@ gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
- <%- if depends_on_system_test? -%>
- # Adds support for Capybara system testing and selenium driver
- gem 'capybara', '~> 2.13'
- gem 'selenium-webdriver'
- <%- end -%>
end
group :development do
@@ -66,6 +65,16 @@ group :development do
<% end -%>
<% end -%>
end
+
+<%- if depends_on_system_test? -%>
+group :test do
+ # Adds support for Capybara system testing and selenium driver
+ gem 'capybara', '>= 2.15'
+ gem 'selenium-webdriver'
+ # Easy installation and use of chromedriver to run system tests with Chrome
+ gem 'chromedriver-helper'
+end
+<%- end -%>
<% end -%>
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
diff --git a/railties/lib/rails/generators/rails/app/templates/README.md b/railties/lib/rails/generators/rails/app/templates/README.md.tt
index 7db80e4ca1..7db80e4ca1 100644
--- a/railties/lib/rails/generators/rails/app/templates/README.md
+++ b/railties/lib/rails/generators/rails/app/templates/README.md.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/Rakefile b/railties/lib/rails/generators/rails/app/templates/Rakefile.tt
index e85f913914..e85f913914 100644
--- a/railties/lib/rails/generators/rails/app/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/app/templates/Rakefile.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
index 62fd04f113..5183bcd256 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt
@@ -12,7 +12,9 @@
//
<% unless options[:skip_javascript] -%>
//= require rails-ujs
+<% unless skip_active_storage? -%>
//= require activestorage
+<% end -%>
<% unless options[:skip_turbolinks] -%>
//= require turbolinks
<% end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt
index 739aa5f022..739aa5f022 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt
index d05ea0f511..d05ea0f511 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt
index d672697283..d672697283 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt
index 0ff5442f47..0ff5442f47 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb b/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb.tt
index de6be7945c..de6be7945c 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/helpers/application_helper.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb b/railties/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb.tt
index a009ace51c..a009ace51c 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/jobs/application_job.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb b/railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb.tt
index 286b2239d1..286b2239d1 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/mailers/application_mailer.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb b/railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb.tt
index 10a4cba84d..10a4cba84d 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/models/application_record.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
index 5460155b3e..ef715f1368 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt
@@ -3,6 +3,7 @@
<head>
<title><%= camelized %></title>
<%%= csrf_meta_tags %>
+ <%%= csp_meta_tag %>
<%- if options[:skip_javascript] -%>
<%%= stylesheet_link_tag 'application', media: 'all' %>
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/bundle b/railties/lib/rails/generators/rails/app/templates/bin/bundle.tt
index a84f0afe47..a84f0afe47 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/bundle
+++ b/railties/lib/rails/generators/rails/app/templates/bin/bundle.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/rails b/railties/lib/rails/generators/rails/app/templates/bin/rails.tt
index 513a2e0183..513a2e0183 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/rails
+++ b/railties/lib/rails/generators/rails/app/templates/bin/rails.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/rake b/railties/lib/rails/generators/rails/app/templates/bin/rake.tt
index d14fc8395b..d14fc8395b 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/rake
+++ b/railties/lib/rails/generators/rails/app/templates/bin/rake.tt
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 d744bec32f..70cc71d83b 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/update.tt
+++ b/railties/lib/rails/generators/rails/app/templates/bin/update.tt
@@ -15,6 +15,11 @@ chdir APP_ROOT do
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
+<% unless options.skip_yarn? -%>
+
+ # Install JavaScript dependencies if using Yarn
+ # system('bin/yarn')
+<% end -%>
<% unless options.skip_active_record? -%>
puts "\n== Updating database =="
diff --git a/railties/lib/rails/generators/rails/app/templates/bin/yarn b/railties/lib/rails/generators/rails/app/templates/bin/yarn.tt
index c2f9b6768a..90ddcc520e 100644
--- a/railties/lib/rails/generators/rails/app/templates/bin/yarn
+++ b/railties/lib/rails/generators/rails/app/templates/bin/yarn.tt
@@ -1,7 +1,7 @@
-VENDOR_PATH = File.expand_path('..', __dir__)
-Dir.chdir(VENDOR_PATH) do
+APP_ROOT = File.expand_path('..', __dir__)
+Dir.chdir(APP_ROOT) do
begin
- exec "yarnpkg #{ARGV.join(' ')}"
+ exec "yarnpkg", *ARGV
rescue Errno::ENOENT
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru b/railties/lib/rails/generators/rails/app/templates/config.ru.tt
index f7ba0b527b..f7ba0b527b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config.ru
+++ b/railties/lib/rails/generators/rails/app/templates/config.ru.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb.tt
index dde09edb94..9a427113c7 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb.tt
@@ -8,10 +8,10 @@ require "rails"
require "active_model/railtie"
require "active_job/railtie"
<%= comment_if :skip_active_record %>require "active_record/railtie"
+<%= comment_if :skip_active_storage %>require "active_storage/engine"
require "action_controller/railtie"
<%= comment_if :skip_action_mailer %>require "action_mailer/railtie"
require "action_view/railtie"
-require "active_storage/engine"
<%= comment_if :skip_action_cable %>require "action_cable/engine"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test %>require "rails/test_unit/railtie"
@@ -24,11 +24,12 @@ Bundler.require(*Rails.groups)
module <%= app_const_base %>
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
- config.load_defaults <%= Rails::VERSION::STRING.to_f %>
+ config.load_defaults <%= build(:config_target_version) %>
# Settings in config/environments/* take precedence over those specified here.
- # Application configuration should go into files in config/initializers
- # -- all .rb files in that directory are automatically loaded.
+ # Application configuration can go into files in config/initializers
+ # -- all .rb files in that directory are automatically loaded after loading
+ # the framework and any gems in your application.
<%- if options.api? -%>
# Only loads a smaller set of middleware suitable for API only apps.
diff --git a/railties/lib/rails/generators/rails/app/templates/config/boot.rb b/railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt
index b9e460cef3..42d46b8175 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/boot.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/boot.rb.tt
@@ -1,4 +1,6 @@
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
require 'bundler/setup' # Set up gems listed in the Gemfile.
+<% if depend_on_bootsnap? -%>
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
+<%- end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/cable.yml b/railties/lib/rails/generators/rails/app/templates/config/cable.yml.tt
index 8e53156c71..8e53156c71 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/cable.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/cable.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml.tt
index 917b52e535..917b52e535 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml.tt
index d40117a27f..d40117a27f 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt
index 563be77710..563be77710 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt
index 2a67bdca25..2a67bdca25 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt
index 70df04079d..70df04079d 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt
index 371415e6a8..371415e6a8 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt
index 04afaa0596..04afaa0596 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt
index 6da0601b24..6da0601b24 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt
index 145cfb7f74..145cfb7f74 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt
index 9510568124..9510568124 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt
index 049de65f22..049de65f22 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environment.rb b/railties/lib/rails/generators/rails/app/templates/config/environment.rb.tt
index 426333bb46..426333bb46 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environment.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/environment.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index 98689cc30d..3807c8a9aa 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -14,7 +14,7 @@ Rails.application.configure do
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
- if Rails.root.join('tmp/caching-dev.txt').exist?
+ if Rails.root.join('tmp', 'caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.cache_store = :memory_store
@@ -26,9 +26,11 @@ Rails.application.configure do
config.cache_store = :null_store
end
+ <%- unless skip_active_storage? -%>
- # Store uploaded files on the local file system (see config/storage.yml for options)
+ # Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
+ <%- end -%>
<%- unless options.skip_action_mailer? -%>
# Don't care if the mailer can't send.
@@ -44,6 +46,9 @@ Rails.application.configure do
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
+ # Highlight code that triggered database queries in logs.
+ config.active_record.verbose_query_logs = true
+
<%- end -%>
<%- unless options.skip_sprockets? -%>
# Debug mode disables concatenation and preprocessing of assets.
@@ -55,7 +60,7 @@ Rails.application.configure do
config.assets.quiet = true
<%- end -%>
- # Raises error for missing translations
+ # Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true
# Use an evented file watcher to asynchronously detect changes in source code,
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
index 2e0b555f6f..d646694477 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt
@@ -34,8 +34,6 @@ Rails.application.configure do
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
- # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
-
<%- end -%>
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
@@ -44,11 +42,13 @@ Rails.application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
- # Store uploaded files on the local file system (see config/storage.yml for options)
+ <%- unless skip_active_storage? -%>
+ # Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
+ <%- end -%>
<%- unless options[:skip_action_cable] -%>
- # Mount Action Cable outside main process or domain
+ # Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
# config.action_cable.url = 'wss://example.com/cable'
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
@@ -67,7 +67,7 @@ Rails.application.configure do
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
- # Use a real queuing backend for Active Job (and separate queues per environment)
+ # Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "<%= app_name %>_#{Rails.env}"
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
index a53978bc6e..82f2a8aebe 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt
@@ -28,8 +28,11 @@ Rails.application.configure do
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
- # Store uploaded files on the local file system in a temporary directory
+ <%- unless skip_active_storage? -%>
+ # Store uploaded files on the local file system in a temporary directory.
config.active_storage.service = :test
+
+ <%- end -%>
<%- unless options.skip_action_mailer? -%>
config.action_mailer.perform_caching = false
@@ -37,11 +40,14 @@ Rails.application.configure do
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
- <%- end -%>
+ <%- end -%>
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
- # Raises error for missing translations
+ # Raises error for missing translations.
# config.action_view.raise_on_missing_translations = true
+
+ # Prevent expensive template finalization at end of test suite runs.
+ config.action_view.finalize_compiled_template_methods = false
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb.tt
index 89d2efab2b..89d2efab2b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb.tt
index 59385cdf37..59385cdf37 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/backtrace_silencers.rb.tt
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
new file mode 100644
index 0000000000..d3bcaa5ec8
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt
@@ -0,0 +1,25 @@
+# Be sure to restart your server when you modify this file.
+
+# Define an application-wide content security policy
+# For further information see the following documentation
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
+
+# Rails.application.config.content_security_policy do |policy|
+# policy.default_src :self, :https
+# policy.font_src :self, :https, :data
+# policy.img_src :self, :https, :data
+# policy.object_src :none
+# policy.script_src :self, :https
+# policy.style_src :self, :https
+
+# # Specify URI for violation reports
+# # policy.report_uri "/csp-violation-report-endpoint"
+# end
+
+# If you are using UJS then enable automatic nonce generation
+# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
+
+# Report CSP violations to a specified URI
+# For further information see the following documentation:
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
+# Rails.application.config.content_security_policy_report_only = true
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb.tt
index 5a6a32d371..5a6a32d371 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cookies_serializer.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt
index 3b1c1b5ed1..3b1c1b5ed1 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt
index 4a994e1e7b..4a994e1e7b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb.tt
index ac033bf9dc..ac033bf9dc 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb.tt
index dc1899682b..dc1899682b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/mime_types.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
deleted file mode 100644
index 25dcddb27a..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_5_2.rb.tt
+++ /dev/null
@@ -1,27 +0,0 @@
-# Be sure to restart your server when you modify this file.
-#
-# This file contains migration options to ease your Rails 5.2 upgrade.
-#
-# Once upgraded flip defaults one by one to migrate to the new default.
-#
-# Read the Guide for Upgrading Ruby on Rails for more info on each option.
-
-# Make Active Record use stable #cache_key alongside new #cache_version method.
-# This is needed for recyclable cache keys.
-# Rails.application.config.active_record.cache_versioning = true
-
-# Use AES 256 GCM authenticated encryption for encrypted cookies.
-# Existing cookies will be converted on read then written with the new scheme.
-# Rails.application.config.action_dispatch.use_authenticated_cookie_encryption = true
-
-# Use AES-256-GCM authenticated encryption as default cipher for encrypting messages
-# instead of AES-256-CBC, when use_authenticated_message_encryption is set to true.
-# Rails.application.config.active_support.use_authenticated_message_encryption = true
-
-# Add default protection from forgery to ActionController::Base instead of in
-# ApplicationController.
-# Rails.application.config.action_controller.default_protect_from_forgery = true
-
-# Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and
-# 'f' after migrating old data.
-# Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
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
new file mode 100644
index 0000000000..179b97de4a
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_6_0.rb.tt
@@ -0,0 +1,10 @@
+# Be sure to restart your server when you modify this file.
+#
+# This file contains migration options to ease your Rails 6.0 upgrade.
+#
+# Once upgraded flip defaults one by one to migrate to the new default.
+#
+# Read the Guide for Upgrading Ruby on Rails for more info on each option.
+
+# Don't force requests from old versions of IE to be UTF-8 encoded
+# Rails.application.config.action_view.default_enforce_utf8 = false
diff --git a/railties/lib/rails/generators/rails/app/templates/config/puma.rb b/railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt
index 1e19380dcb..a5eccf816b 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/puma.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt
@@ -26,31 +26,9 @@ environment ENV.fetch("RAILS_ENV") { "development" }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
-# process behavior so workers use less memory. If you use this option
-# you need to make sure to reconnect any threads in the `on_worker_boot`
-# block.
+# process behavior so workers use less memory.
#
# preload_app!
-# If you are preloading your application and using Active Record, it's
-# recommended that you close any connections to the database before workers
-# are forked to prevent connection leakage.
-#
-# before_fork do
-# ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
-# end
-
-# The code in the `on_worker_boot` will be called if you are using
-# clustered mode by specifying a number of `workers`. After each worker
-# process is booted, this block will be run. If you are using the `preload_app!`
-# option, you will want to use this block to reconnect to any threads
-# or connections that may have been created at application boot, as Ruby
-# cannot share connections between processes.
-#
-# on_worker_boot do
-# ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
-# end
-#
-
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
diff --git a/railties/lib/rails/generators/rails/app/templates/config/routes.rb b/railties/lib/rails/generators/rails/app/templates/config/routes.rb.tt
index 787824f888..787824f888 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/routes.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml
deleted file mode 100644
index ea9d47396c..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-# Be sure to restart your server when you modify this file.
-
-# Your secret key is used for verifying the integrity of signed cookies.
-# If you change this key, all old signed cookies will become invalid!
-
-# Make sure the secret is at least 30 characters and all random,
-# no regular words or you'll be exposed to dictionary attacks.
-# You can use `rails secret` to generate a secure secret key.
-
-# Make sure the secrets in this file are kept private
-# if you're sharing your code publicly.
-
-# Shared secrets are available across all environments.
-
-# shared:
-# api_key: a1B2c3D4e5F6
-
-# Environmental secrets are only available for that specific environment.
-
-development:
- secret_key_base: <%= app_secret %>
-
-test:
- secret_key_base: <%= app_secret %>
-
-# Do not keep production secrets in the unencrypted secrets file.
-# Instead, either read values from the environment.
-# Or, use `bin/rails secrets:setup` to configure encrypted secrets
-# and move the `production:` environment over there.
-
-production:
- secret_key_base: <%%= ENV["SECRET_KEY_BASE"] %>
diff --git a/railties/lib/rails/generators/rails/app/templates/config/spring.rb b/railties/lib/rails/generators/rails/app/templates/config/spring.rb.tt
index 9fa7863f99..9fa7863f99 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/spring.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/spring.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/config/storage.yml b/railties/lib/rails/generators/rails/app/templates/config/storage.yml.tt
index 089ed4567a..7207c75086 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/storage.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/storage.yml.tt
@@ -6,11 +6,11 @@ local:
service: Disk
root: <%%= Rails.root.join("storage") %>
-# Use rails secrets:edit to set the AWS secrets (as shared:aws:access_key_id|secret_access_key)
+# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
# service: S3
-# access_key_id: <%%= Rails.application.secrets.dig(:aws, :access_key_id) %>
-# secret_access_key: <%%= Rails.application.secrets.dig(:aws, :secret_access_key) %>
+# access_key_id: <%%= Rails.application.credentials.dig(:aws, :access_key_id) %>
+# secret_access_key: <%%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
# region: us-east-1
# bucket: your_own_bucket
@@ -18,15 +18,14 @@ local:
# google:
# service: GCS
# project: your_project
-# keyfile: <%%= Rails.root.join("path/to/gcs.keyfile") %>
+# credentials: <%%= Rails.root.join("path/to/gcs.keyfile") %>
# bucket: your_own_bucket
-# Use rails secrets:edit to set the Azure Storage secret (as shared:azure_storage:storage_access_key)
+# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
# microsoft:
# service: AzureStorage
-# path: your_azure_storage_path
# storage_account_name: your_account_name
-# storage_access_key: <%%= Rails.application.secrets.dig(:azure_storage, :storage_access_key) %>
+# storage_access_key: <%%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
# container: your_container_name
# mirror:
diff --git a/railties/lib/rails/generators/rails/app/templates/gitignore b/railties/lib/rails/generators/rails/app/templates/gitignore.tt
index 83a7b211aa..4e114fb1d9 100644
--- a/railties/lib/rails/generators/rails/app/templates/gitignore
+++ b/railties/lib/rails/generators/rails/app/templates/gitignore.tt
@@ -21,14 +21,19 @@
!/tmp/.keep
<% end -%>
+<% unless skip_active_storage? -%>
# Ignore uploaded files in development
/storage/*
+<% if keeps? -%>
+!/storage/.keep
+<% end -%>
+<% end -%>
<% unless options.skip_yarn? -%>
/node_modules
/yarn-error.log
-<% end -%>
+<% end -%>
<% unless options.api? -%>
/public/assets
<% end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/package.json b/railties/lib/rails/generators/rails/app/templates/package.json.tt
index 46db57dcbe..46db57dcbe 100644
--- a/railties/lib/rails/generators/rails/app/templates/package.json
+++ b/railties/lib/rails/generators/rails/app/templates/package.json.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/ruby-version b/railties/lib/rails/generators/rails/app/templates/ruby-version
deleted file mode 100644
index c444f33b0f..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/ruby-version
+++ /dev/null
@@ -1 +0,0 @@
-<%= RUBY_VERSION -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/ruby-version.tt b/railties/lib/rails/generators/rails/app/templates/ruby-version.tt
new file mode 100644
index 0000000000..19f0d7f202
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/ruby-version.tt
@@ -0,0 +1 @@
+<%= "#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}" -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb b/railties/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt
index d19212abd5..d19212abd5 100644
--- a/railties/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt
diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt
index 6ad1f11781..c918b57eca 100644
--- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt
@@ -1,7 +1,15 @@
+ENV['RAILS_ENV'] ||= 'test'
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/assets/templates/stylesheet.css b/railties/lib/rails/generators/rails/assets/templates/stylesheet.css
index 7594abf268..afad32db02 100644
--- a/railties/lib/rails/generators/rails/assets/templates/stylesheet.css
+++ b/railties/lib/rails/generators/rails/assets/templates/stylesheet.css
@@ -1,4 +1,4 @@
-/*
+/*
Place all the styles related to the matching controller here.
They will automatically be included in application.css.
*/
diff --git a/railties/lib/rails/generators/rails/controller/controller_generator.rb b/railties/lib/rails/generators/rails/controller/controller_generator.rb
index 6d45d6e8f8..eb75e7e661 100644
--- a/railties/lib/rails/generators/rails/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/rails/controller/controller_generator.rb
@@ -16,13 +16,24 @@ module Rails
def add_routes
return if options[:skip_routes]
+ return if actions.empty?
route generate_routing_code
end
- hook_for :template_engine, :test_framework, :helper, :assets
+ hook_for :template_engine, :test_framework, :helper, :assets do |generator|
+ invoke generator, [ remove_possible_suffix(name), actions ]
+ end
private
+ def file_name
+ @_file_name ||= remove_possible_suffix(super)
+ end
+
+ def remove_possible_suffix(name)
+ name.sub(/_?controller$/i, "")
+ end
+
# This method creates nested route entry for namespaced resources.
# For eg. rails g controller foo/bar/baz index show
# Will generate -
diff --git a/railties/lib/rails/generators/rails/controller/templates/controller.rb b/railties/lib/rails/generators/rails/controller/templates/controller.rb.tt
index 633e0b3177..633e0b3177 100644
--- a/railties/lib/rails/generators/rails/controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/controller/templates/controller.rb.tt
diff --git a/railties/lib/rails/generators/rails/credentials/credentials_generator.rb b/railties/lib/rails/generators/rails/credentials/credentials_generator.rb
index ddcccd5ce5..719e0c1e4c 100644
--- a/railties/lib/rails/generators/rails/credentials/credentials_generator.rb
+++ b/railties/lib/rails/generators/rails/credentials/credentials_generator.rb
@@ -1,20 +1,17 @@
# frozen_string_literal: true
-require_relative "../../base"
-require_relative "../master_key/master_key_generator"
+require "rails/generators/base"
+require "rails/generators/rails/master_key/master_key_generator"
require "active_support/encrypted_configuration"
module Rails
module Generators
- class CredentialsGenerator < Base
- CONFIG_PATH = "config/credentials.yml.enc"
- KEY_PATH = "config/master.key"
-
+ class CredentialsGenerator < Base # :nodoc:
def add_credentials_file
- unless File.exist?(CONFIG_PATH)
+ unless credentials.content_path.exist?
template = credentials_template
- say "Adding #{CONFIG_PATH} to store encrypted credentials."
+ say "Adding #{credentials.content_path} to store encrypted credentials."
say ""
say "The following content has been encrypted with the Rails master key:"
say ""
@@ -29,17 +26,30 @@ module Rails
end
def add_credentials_file_silently(template = nil)
- unless File.exist?(CONFIG_PATH)
- setup = { config_path: CONFIG_PATH, key_path: KEY_PATH, env_key: "RAILS_MASTER_KEY" }
- ActiveSupport::EncryptedConfiguration.new(setup).write(credentials_template)
+ unless credentials.content_path.exist?
+ credentials.write(credentials_template)
end
end
private
+ def credentials
+ ActiveSupport::EncryptedConfiguration.new(
+ config_path: "config/credentials.yml.enc",
+ key_path: "config/master.key",
+ env_key: "RAILS_MASTER_KEY",
+ raise_if_missing_key: true
+ )
+ end
+
def credentials_template
- "# amazon:\n# access_key_id: 123\n# secret_access_key: 345\n\n" +
- "# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.\n" +
- "secret_key_base: #{SecureRandom.hex(64)}"
+ <<~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)}
+ YAML
end
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
new file mode 100644
index 0000000000..867e28c6db
--- /dev/null
+++ b/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require "rails/generators/base"
+require "active_support/encrypted_file"
+
+module Rails
+ module Generators
+ class EncryptedFileGenerator < Base # :nodoc:
+ def add_encrypted_file_silently(file_path, key_path, template = encrypted_file_template)
+ unless File.exist?(file_path)
+ setup = { content_path: file_path, key_path: key_path, env_key: "RAILS_MASTER_KEY", raise_if_missing_key: true }
+ ActiveSupport::EncryptedFile.new(setup).write(template)
+ end
+ end
+
+ private
+ def encrypted_file_template
+ <<~YAML
+ # aws:
+ # access_key_id: 123
+ # secret_access_key: 345
+
+ YAML
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/rails/encrypted_secrets/encrypted_secrets_generator.rb b/railties/lib/rails/generators/rails/encrypted_secrets/encrypted_secrets_generator.rb
deleted file mode 100644
index d054e8cad2..0000000000
--- a/railties/lib/rails/generators/rails/encrypted_secrets/encrypted_secrets_generator.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: true
-
-require_relative "../../base"
-require_relative "../../../secrets"
-
-module Rails
- module Generators
- class EncryptedSecretsGenerator < Base
- def add_secrets_key_file
- unless File.exist?("config/secrets.yml.key") || File.exist?("config/secrets.yml.enc")
- key = Rails::Secrets.generate_key
-
- say "Adding config/secrets.yml.key to store the encryption key: #{key}"
- say ""
- say "Save this in a password manager your team can access."
- say ""
- say "If you lose the key, no one, including you, can access any encrypted secrets."
-
- say ""
- create_file "config/secrets.yml.key", key
- say ""
- end
- end
-
- def ignore_key_file
- if File.exist?(".gitignore")
- unless File.read(".gitignore").include?(key_ignore)
- say "Ignoring config/secrets.yml.key so it won't end up in Git history:"
- say ""
- append_to_file ".gitignore", key_ignore
- say ""
- end
- else
- say "IMPORTANT: Don't commit config/secrets.yml.key. Add this to your ignore file:"
- say key_ignore, :on_green
- say ""
- end
- end
-
- def add_encrypted_secrets_file
- unless (defined?(@@skip_secrets_file) && @@skip_secrets_file) || File.exist?("config/secrets.yml.enc")
- say "Adding config/secrets.yml.enc to store secrets that needs to be encrypted."
- say ""
- say "For now the file contains this but it's been encrypted with the generated key:"
- say ""
- say Secrets.template, :on_green
- say ""
-
- Secrets.write(Secrets.template)
-
- say "You can edit encrypted secrets with `bin/rails secrets:edit`."
- say ""
- end
-
- say "Add this to your config/environments/production.rb:"
- say "config.read_encrypted_secrets = true"
- end
-
- def self.skip_secrets_file
- @@skip_secrets_file = true
- yield
- ensure
- @@skip_secrets_file = false
- end
-
- private
- def key_ignore
- [ "", "# Ignore encrypted secrets key file.", "config/secrets.yml.key", "" ].join("\n")
- end
- end
- end
-end
diff --git a/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb b/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb
new file mode 100644
index 0000000000..e2359e9ded
--- /dev/null
+++ b/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+require "pathname"
+require "rails/generators/base"
+require "active_support/encrypted_file"
+
+module Rails
+ module Generators
+ class EncryptionKeyFileGenerator < Base # :nodoc:
+ def add_key_file(key_path)
+ key_path = Pathname.new(key_path)
+
+ unless key_path.exist?
+ key = ActiveSupport::EncryptedFile.generate_key
+
+ log "Adding #{key_path} to store the encryption key: #{key}"
+ log ""
+ log "Save this in a password manager your team can access."
+ log ""
+ log "If you lose the key, no one, including you, can access anything encrypted with it."
+
+ log ""
+ add_key_file_silently(key_path, key)
+ log ""
+ end
+ end
+
+ def add_key_file_silently(key_path, key = nil)
+ create_file key_path, key || ActiveSupport::EncryptedFile.generate_key
+ key_path.chmod 0600
+ end
+
+ def ignore_key_file(key_path, ignore: key_ignore(key_path))
+ if File.exist?(".gitignore")
+ unless File.read(".gitignore").include?(ignore)
+ log "Ignoring #{key_path} so it won't end up in Git history:"
+ log ""
+ append_to_file ".gitignore", ignore
+ log ""
+ end
+ else
+ log "IMPORTANT: Don't commit #{key_path}. Add this to your ignore file:"
+ log ignore, :on_green
+ log ""
+ end
+ end
+
+ def ignore_key_file_silently(key_path, ignore: key_ignore(key_path))
+ append_to_file ".gitignore", ignore if File.exist?(".gitignore")
+ end
+
+ private
+ def key_ignore(key_path)
+ [ "", "/#{key_path}", "" ].join("\n")
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/rails/helper/templates/helper.rb b/railties/lib/rails/generators/rails/helper/templates/helper.rb.tt
index b4173151b4..b4173151b4 100644
--- a/railties/lib/rails/generators/rails/helper/templates/helper.rb
+++ b/railties/lib/rails/generators/rails/helper/templates/helper.rb.tt
diff --git a/railties/lib/rails/generators/rails/master_key/master_key_generator.rb b/railties/lib/rails/generators/rails/master_key/master_key_generator.rb
index e49d3b39e0..21664ea86d 100644
--- a/railties/lib/rails/generators/rails/master_key/master_key_generator.rb
+++ b/railties/lib/rails/generators/rails/master_key/master_key_generator.rb
@@ -1,46 +1,48 @@
# frozen_string_literal: true
-require_relative "../../base"
require "pathname"
+require "rails/generators/base"
+require "rails/generators/rails/encryption_key_file/encryption_key_file_generator"
require "active_support/encrypted_file"
module Rails
module Generators
- class MasterKeyGenerator < Base
+ class MasterKeyGenerator < Base # :nodoc:
MASTER_KEY_PATH = Pathname.new("config/master.key")
def add_master_key_file
unless MASTER_KEY_PATH.exist?
key = ActiveSupport::EncryptedFile.generate_key
- say "Adding #{MASTER_KEY_PATH} to store the master encryption key: #{key}"
- say ""
- say "Save this in a password manager your team can access."
- say ""
- say "If you lose the key, no one, including you, can access anything encrypted with it."
+ log "Adding #{MASTER_KEY_PATH} to store the master encryption key: #{key}"
+ log ""
+ log "Save this in a password manager your team can access."
+ log ""
+ log "If you lose the key, no one, including you, can access anything encrypted with it."
- say ""
- create_file MASTER_KEY_PATH, key
- say ""
+ log ""
+ add_master_key_file_silently(key)
+ log ""
+ end
+ end
- ignore_master_key_file
+ def add_master_key_file_silently(key = nil)
+ unless MASTER_KEY_PATH.exist?
+ key_file_generator.add_key_file_silently(MASTER_KEY_PATH, key)
end
end
+ def ignore_master_key_file
+ key_file_generator.ignore_key_file(MASTER_KEY_PATH, ignore: key_ignore)
+ end
+
+ def ignore_master_key_file_silently
+ key_file_generator.ignore_key_file_silently(MASTER_KEY_PATH, ignore: key_ignore)
+ end
+
private
- def ignore_master_key_file
- if File.exist?(".gitignore")
- unless File.read(".gitignore").include?(key_ignore)
- say "Ignoring #{MASTER_KEY_PATH} so it won't end up in Git history:"
- say ""
- append_to_file ".gitignore", key_ignore
- say ""
- end
- else
- say "IMPORTANT: Don't commit #{MASTER_KEY_PATH}. Add this to your ignore file:"
- say key_ignore, :on_green
- say ""
- end
+ def key_file_generator
+ EncryptionKeyFileGenerator.new([], options)
end
def key_ignore
diff --git a/railties/lib/rails/generators/rails/model/model_generator.rb b/railties/lib/rails/generators/rails/model/model_generator.rb
index 1dca03e0bb..de4de2cae2 100644
--- a/railties/lib/rails/generators/rails/model/model_generator.rb
+++ b/railties/lib/rails/generators/rails/model/model_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../model_helpers"
+require "rails/generators/model_helpers"
module Rails
module Generators
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index eb941adf95..a83c911806 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
-require "active_support/core_ext/hash/slice"
-require_relative "../app/app_generator"
+require "rails/generators/rails/app/app_generator"
require "date"
module Rails
@@ -88,17 +87,18 @@ task default: :test
end
PASSTHROUGH_OPTIONS = [
- :skip_active_record, :skip_action_mailer, :skip_javascript, :skip_action_cable, :skip_sprockets, :database,
+ :skip_active_record, :skip_active_storage, :skip_action_mailer, :skip_javascript, :skip_action_cable, :skip_sprockets, :database,
:javascript, :skip_yarn, :api, :quiet, :pretend, :skip
]
def generate_test_dummy(force = false)
- opts = (options || {}).slice(*PASSTHROUGH_OPTIONS)
+ opts = (options.dup || {}).keep_if { |k, _| PASSTHROUGH_OPTIONS.map(&:to_s).include?(k) }
opts[:force] = force
opts[:skip_bundle] = true
opts[:skip_listen] = true
opts[:skip_git] = true
opts[:skip_turbolinks] = true
+ opts[:dummy_app] = true
invoke Rails::Generators::AppGenerator,
[ File.expand_path(dummy_path, destination_root) ], opts
@@ -167,7 +167,7 @@ task default: :test
gemfile_in_app_path = File.join(rails_app_path, "Gemfile")
if File.exist? gemfile_in_app_path
- entry = "gem '#{name}', path: '#{relative_path}'"
+ entry = "\ngem '#{name}', path: '#{relative_path}'"
append_file gemfile_in_app_path, entry
end
end
@@ -263,6 +263,10 @@ task default: :test
public_task :apply_rails_template
def run_after_bundle_callbacks
+ unless @after_bundle_callbacks.empty?
+ ActiveSupport::Deprecation.warn("`after_bundle` is deprecated and will be removed in the next version of Rails. ")
+ end
+
@after_bundle_callbacks.each do |callback|
callback.call
end
diff --git a/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt
index 9a8c4bf098..9a8c4bf098 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec
+++ b/railties/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Gemfile b/railties/lib/rails/generators/rails/plugin/templates/Gemfile.tt
index 290259b4db..290259b4db 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/plugin/templates/Gemfile.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt
index ff2fb3ba4e..ff2fb3ba4e 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE
+++ b/railties/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/README.md b/railties/lib/rails/generators/rails/plugin/templates/README.md.tt
index 1632409bea..1632409bea 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/README.md
+++ b/railties/lib/rails/generators/rails/plugin/templates/README.md.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Rakefile b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
index f3efe21cf1..f3efe21cf1 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
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/app/views/layouts/%namespaced_name%/application.html.erb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt
index 6bc480161d..6e54a1ce9d 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/app/views/layouts/%namespaced_name%/application.html.erb.tt
@@ -2,9 +2,13 @@
<html>
<head>
<title><%= humanized %></title>
+ <%%= csrf_meta_tags %>
+ <%%= csp_meta_tag %>
+
<%%= stylesheet_link_tag "<%= namespaced_name %>/application", media: "all" %>
+ <%- unless options[:skip_javascript] -%>
<%%= javascript_include_tag "<%= namespaced_name %>/application" %>
- <%%= csrf_meta_tags %>
+ <%- end -%>
</head>
<body>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt b/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt
index b3264509fc..ee8e469da2 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/bin/rails.tt
@@ -19,10 +19,10 @@ require "rails"
require "active_model/railtie"
require "active_job/railtie"
<%= comment_if :skip_active_record %>require "active_record/railtie"
+<%= comment_if :skip_active_storage %>require "active_storage/engine"
require "action_controller/railtie"
<%= comment_if :skip_action_mailer %>require "action_mailer/railtie"
require "action_view/railtie"
-require "active_storage/engine"
<%= comment_if :skip_action_cable %>require "action_cable/engine"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test %>require "rails/test_unit/railtie"
diff --git a/railties/lib/rails/generators/rails/plugin/templates/config/routes.rb b/railties/lib/rails/generators/rails/plugin/templates/config/routes.rb.tt
index 154452bfe5..154452bfe5 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/config/routes.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/config/routes.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/gitignore b/railties/lib/rails/generators/rails/plugin/templates/gitignore.tt
index e15863d860..7a68da5c4b 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/gitignore
+++ b/railties/lib/rails/generators/rails/plugin/templates/gitignore.tt
@@ -11,5 +11,8 @@ pkg/
<%= dummy_path %>/node_modules/
<%= dummy_path %>/yarn-error.log
<% end -%>
+<% unless skip_active_storage? -%>
+<%= dummy_path %>/storage/
+<% end -%>
<%= dummy_path %>/tmp/
<% end -%>
diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb.tt
index 3285055eb7..3285055eb7 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/engine.rb 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
+++ 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 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
+++ 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/rails/plugin/templates/lib/%namespaced_name%/version.rb b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb.tt
index b08f4ef9ae..b08f4ef9ae 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/lib/%namespaced_name%/version.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%namespaced_name%_tasks.rake b/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%namespaced_name%_tasks.rake.tt
index 88a2c4120f..88a2c4120f 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%namespaced_name%_tasks.rake
+++ b/railties/lib/rails/generators/rails/plugin/templates/lib/tasks/%namespaced_name%_tasks.rake.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb.tt
index 47b56ae3df..06ffe2f1ed 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb.tt
@@ -8,10 +8,10 @@ require "rails"
require "active_model/railtie"
require "active_job/railtie"
<%= comment_if :skip_active_record %>require "active_record/railtie"
+<%= comment_if :skip_active_storage %>require "active_storage/engine"
require "action_controller/railtie"
<%= comment_if :skip_action_mailer %>require "action_mailer/railtie"
require "action_view/railtie"
-require "active_storage/engine"
<%= comment_if :skip_action_cable %>require "action_cable/engine"
<%= comment_if :skip_sprockets %>require "sprockets/railtie"
<%= comment_if :skip_test %>require "rails/test_unit/railtie"
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt
index c9aef85d40..c9aef85d40 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/boot.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js b/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt
index 03937cf8ff..03937cf8ff 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/dummy_manifest.js.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js b/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt
index 2f23844f5e..2f23844f5e 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/engine_manifest.js.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt
index e54c6461cc..51049826bf 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/javascripts.js.tt
@@ -10,4 +10,8 @@
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
+//= require rails-ujs
+<% unless skip_active_storage? -%>
+//= require activestorage
+<% end -%>
//= require_tree .
diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb.tt
index 694510edc0..694510edc0 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/rails/routes.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb b/railties/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb.tt
index 1ee05d7871..1ee05d7871 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/%namespaced_name%_test.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb b/railties/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt
index d19212abd5..d19212abd5 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb b/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb.tt
index 29e59d8407..29e59d8407 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/integration/navigation_test.rb.tt
diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt
index 7fa9973931..755d19ef5d 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb
+++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt
@@ -1,3 +1,6 @@
+# Configure Rails Environment
+ENV["RAILS_ENV"] = "test"
+
require_relative "<%= File.join('..', options[:dummy_path], 'config/environment') -%>"
<% unless options[:skip_active_record] -%>
ActiveRecord::Migrator.migrations_paths = [File.expand_path("../<%= options[:dummy_path] -%>/db/migrate", __dir__)]
diff --git a/railties/lib/rails/generators/rails/resource/USAGE b/railties/lib/rails/generators/rails/resource/USAGE
index e359cd574f..66d0ee546a 100644
--- a/railties/lib/rails/generators/rails/resource/USAGE
+++ b/railties/lib/rails/generators/rails/resource/USAGE
@@ -1,6 +1,6 @@
Description:
Stubs out a new resource including an empty model and controller suitable
- for a restful, resource-oriented application. Pass the singular model name,
+ for a RESTful, resource-oriented application. Pass the singular model name,
either CamelCased or under_scored, as the first argument, and an optional
list of attribute pairs.
diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb
index 74b1574863..3ba25ef0fe 100644
--- a/railties/lib/rails/generators/rails/resource/resource_generator.rb
+++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "../../resource_helpers"
-require_relative "../model/model_generator"
+require "rails/generators/resource_helpers"
+require "rails/generators/rails/model/model_generator"
module Rails
module Generators
diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
index c0fb873d36..8beb7416c0 100644
--- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../resource/resource_generator"
+require "rails/generators/rails/resource/resource_generator"
module Rails
module Generators
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
index 601a4b3a6e..7030561a33 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../resource_helpers"
+require "rails/generators/resource_helpers"
module Rails
module Generators
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt
index 400afec6dc..400afec6dc 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/api_controller.rb.tt
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt
index 42b9e34274..05f1c2b2d3 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt
@@ -29,7 +29,7 @@ class <%= controller_class_name %>Controller < ApplicationController
@<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
if @<%= orm_instance.save %>
- redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully created.'" %>
+ redirect_to <%= redirect_resource_name %>, notice: <%= "'#{human_name} was successfully created.'" %>
else
render :new
end
@@ -38,7 +38,7 @@ class <%= controller_class_name %>Controller < ApplicationController
# PATCH/PUT <%= route_url %>/1
def update
if @<%= orm_instance.update("#{singular_table_name}_params") %>
- redirect_to @<%= singular_table_name %>, notice: <%= "'#{human_name} was successfully updated.'" %>
+ redirect_to <%= redirect_resource_name %>, notice: <%= "'#{human_name} was successfully updated.'" %>
else
render :edit
end
diff --git a/railties/lib/rails/generators/rails/task/templates/task.rb b/railties/lib/rails/generators/rails/task/templates/task.rb.tt
index 1e3ed5f158..1e3ed5f158 100644
--- a/railties/lib/rails/generators/rails/task/templates/task.rb
+++ b/railties/lib/rails/generators/rails/task/templates/task.rb.tt
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index 8bd5110940..5675faff70 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "active_model"
-require_relative "model_helpers"
+require "rails/generators/active_model"
+require "rails/generators/model_helpers"
module Rails
module Generators
@@ -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/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb
index 9c06eed95a..5c71bf0be9 100644
--- a/railties/lib/rails/generators/test_case.rb
+++ b/railties/lib/rails/generators/test_case.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-require_relative "../generators"
-require_relative "testing/behaviour"
-require_relative "testing/setup_and_teardown"
-require_relative "testing/assertions"
+require "rails/generators"
+require "rails/generators/testing/behaviour"
+require "rails/generators/testing/setup_and_teardown"
+require "rails/generators/testing/assertions"
require "fileutils"
module Rails
diff --git a/railties/lib/rails/generators/test_unit.rb b/railties/lib/rails/generators/test_unit.rb
index 1aa03ace99..1005ac557c 100644
--- a/railties/lib/rails/generators/test_unit.rb
+++ b/railties/lib/rails/generators/test_unit.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "named_base"
+require "rails/generators/named_base"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/controller/controller_generator.rb b/railties/lib/rails/generators/test_unit/controller/controller_generator.rb
index 3947b74205..1a9ac6bf2a 100644
--- a/railties/lib/rails/generators/test_unit/controller/controller_generator.rb
+++ b/railties/lib/rails/generators/test_unit/controller/controller_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb.tt
index ff41fef9e9..ff41fef9e9 100644
--- a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/generator/generator_generator.rb b/railties/lib/rails/generators/test_unit/generator/generator_generator.rb
index 9f79e9eee1..19be4f2f51 100644
--- a/railties/lib/rails/generators/test_unit/generator/generator_generator.rb
+++ b/railties/lib/rails/generators/test_unit/generator/generator_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb b/railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt
index a7f1fc4fba..a7f1fc4fba 100644
--- a/railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb
+++ b/railties/lib/rails/generators/test_unit/generator/templates/generator_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb
index 1c60c3573f..77308dcf7d 100644
--- a/railties/lib/rails/generators/test_unit/helper/helper_generator.rb
+++ b/railties/lib/rails/generators/test_unit/helper/helper_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/integration/integration_generator.rb b/railties/lib/rails/generators/test_unit/integration/integration_generator.rb
index c859ba5e4e..ae307c5cd9 100644
--- a/railties/lib/rails/generators/test_unit/integration/integration_generator.rb
+++ b/railties/lib/rails/generators/test_unit/integration/integration_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb.tt
index 118e0f1271..118e0f1271 100644
--- a/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb
+++ b/railties/lib/rails/generators/test_unit/integration/templates/integration_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/job/job_generator.rb b/railties/lib/rails/generators/test_unit/job/job_generator.rb
index cbbcd1cd4e..1dae3cb6a5 100644
--- a/railties/lib/rails/generators/test_unit/job/job_generator.rb
+++ b/railties/lib/rails/generators/test_unit/job/job_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
@@ -8,8 +8,13 @@ module TestUnit # :nodoc:
check_class_collision suffix: "JobTest"
def create_test_file
- template "unit_test.rb.erb", File.join("test/jobs", class_path, "#{file_name}_job_test.rb")
+ template "unit_test.rb", File.join("test/jobs", class_path, "#{file_name}_job_test.rb")
end
+
+ private
+ def file_name
+ @_file_name ||= super.sub(/_job\z/i, "")
+ end
end
end
end
diff --git a/railties/lib/rails/generators/test_unit/job/templates/unit_test.rb.erb b/railties/lib/rails/generators/test_unit/job/templates/unit_test.rb.tt
index f5351d0ec6..f5351d0ec6 100644
--- a/railties/lib/rails/generators/test_unit/job/templates/unit_test.rb.erb
+++ b/railties/lib/rails/generators/test_unit/job/templates/unit_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
index 45f82158e9..ab8331f31c 100644
--- a/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/mailer_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
@@ -21,7 +21,7 @@ module TestUnit # :nodoc:
private
def file_name
- @_file_name ||= super.gsub(/_mailer/i, "")
+ @_file_name ||= super.sub(/_mailer\z/i, "")
end
end
end
diff --git a/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt
index a2f2d30de5..a2f2d30de5 100644
--- a/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/templates/functional_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/mailer/templates/preview.rb b/railties/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt
index b063cbc47b..b063cbc47b 100644
--- a/railties/lib/rails/generators/test_unit/mailer/templates/preview.rb
+++ b/railties/lib/rails/generators/test_unit/mailer/templates/preview.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/model/model_generator.rb b/railties/lib/rails/generators/test_unit/model/model_generator.rb
index 2b1cc50c20..02d7502592 100644
--- a/railties/lib/rails/generators/test_unit/model/model_generator.rb
+++ b/railties/lib/rails/generators/test_unit/model/model_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt
index 0681780c97..0681780c97 100644
--- a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml
+++ b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml.tt
diff --git a/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb b/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb.tt
index c9bc7d5b90..c9bc7d5b90 100644
--- a/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb
+++ b/railties/lib/rails/generators/test_unit/model/templates/unit_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb b/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb
index 10fe27b2c3..0657bc2389 100644
--- a/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/test_unit/plugin/plugin_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
index 23d5c63614..e2e8b18eab 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
-require_relative "../../resource_helpers"
+require "rails/generators/test_unit"
+require "rails/generators/resource_helpers"
module TestUnit # :nodoc:
module Generators # :nodoc:
@@ -23,7 +23,7 @@ module TestUnit # :nodoc:
template template_file,
File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb")
- unless options.api? || options[:system_tests].nil?
+ if !options.api? && options[:system_tests]
template "system_test.rb", File.join("test/system", class_path, "#{file_name.pluralize}_test.rb")
end
end
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt
index f21861d8e6..f21861d8e6 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt
index 195d60be20..195d60be20 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/system_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt
index f83f5a5c62..f83f5a5c62 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/system_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/system/system_generator.rb b/railties/lib/rails/generators/test_unit/system/system_generator.rb
index d3acbfd738..08504d4124 100644
--- a/railties/lib/rails/generators/test_unit/system/system_generator.rb
+++ b/railties/lib/rails/generators/test_unit/system/system_generator.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../../test_unit"
+require "rails/generators/test_unit"
module TestUnit # :nodoc:
module Generators # :nodoc:
diff --git a/railties/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb b/railties/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt
index d19212abd5..d19212abd5 100644
--- a/railties/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb
+++ b/railties/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt
diff --git a/railties/lib/rails/generators/test_unit/system/templates/system_test.rb b/railties/lib/rails/generators/test_unit/system/templates/system_test.rb.tt
index b5ce2ba5c8..b5ce2ba5c8 100644
--- a/railties/lib/rails/generators/test_unit/system/templates/system_test.rb
+++ b/railties/lib/rails/generators/test_unit/system/templates/system_test.rb.tt
diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb
index 97a09c1166..6ab88bd59f 100644
--- a/railties/lib/rails/generators/testing/behaviour.rb
+++ b/railties/lib/rails/generators/testing/behaviour.rb
@@ -6,7 +6,7 @@ require "active_support/core_ext/hash/reverse_merge"
require "active_support/core_ext/kernel/reporting"
require "active_support/testing/stream"
require "active_support/concern"
-require_relative "../../generators"
+require "rails/generators"
module Rails
module Generators
diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb
index d8f361f524..d5c9973c6b 100644
--- a/railties/lib/rails/info.rb
+++ b/railties/lib/rails/info.rb
@@ -99,7 +99,7 @@ module Rails
end
property "Database schema version" do
- ActiveRecord::Migrator.current_version rescue nil
+ ActiveRecord::Base.connection.migration_context.current_version rescue nil
end
end
end
diff --git a/railties/lib/rails/info_controller.rb b/railties/lib/rails/info_controller.rb
index 6535b5b6ad..b4f4a5922a 100644
--- a/railties/lib/rails/info_controller.rb
+++ b/railties/lib/rails/info_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "application_controller"
+require "rails/application_controller"
require "action_dispatch/routing/inspector"
class Rails::InfoController < Rails::ApplicationController # :nodoc:
diff --git a/railties/lib/rails/mailers_controller.rb b/railties/lib/rails/mailers_controller.rb
index 6bd3161fdd..0b0e802358 100644
--- a/railties/lib/rails/mailers_controller.rb
+++ b/railties/lib/rails/mailers_controller.rb
@@ -1,14 +1,14 @@
# frozen_string_literal: true
-require_relative "application_controller"
+require "rails/application_controller"
class Rails::MailersController < Rails::ApplicationController # :nodoc:
prepend_view_path ActionDispatch::DebugExceptions::RESCUES_TEMPLATE_PATH
before_action :require_local!, unless: :show_previews?
- before_action :find_preview, only: :preview
+ before_action :find_preview, :set_locale, only: :preview
- helper_method :part_query
+ helper_method :part_query, :locale_query
def index
@previews = ActionMailer::Preview.all
@@ -84,4 +84,12 @@ class Rails::MailersController < Rails::ApplicationController # :nodoc:
def part_query(mime_type)
request.query_parameters.merge(part: mime_type).to_query
end
+
+ def locale_query(locale)
+ request.query_parameters.merge(locale: locale).to_query
+ end
+
+ def set_locale
+ I18n.locale = params[:locale] || I18n.default_locale
+ end
end
diff --git a/railties/lib/rails/plugin/test.rb b/railties/lib/rails/plugin/test.rb
index 2426521e35..18b6fd1757 100644
--- a/railties/lib/rails/plugin/test.rb
+++ b/railties/lib/rails/plugin/test.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-require_relative "../test_unit/runner"
-require_relative "../test_unit/reporter"
+require "rails/test_unit/runner"
+require "rails/test_unit/reporter"
Rails::TestUnitReporter.executable = "bin/test"
diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb
index ec5212ee76..4ea7e40319 100644
--- a/railties/lib/rails/rack/logger.rb
+++ b/railties/lib/rails/rack/logger.rb
@@ -35,9 +35,9 @@ module Rails
instrumenter = ActiveSupport::Notifications.instrumenter
instrumenter.start "request.action_dispatch", request: request
logger.info { started_request_message(request) }
- resp = @app.call(env)
- resp[2] = ::Rack::BodyProxy.new(resp[2]) { finish(request) }
- resp
+ status, headers, body = @app.call(env)
+ body = ::Rack::BodyProxy.new(body) { finish(request) }
+ [status, headers, body]
rescue Exception
finish(request)
raise
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index 42c4a82b1b..88dd932370 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "initializable"
+require "rails/initializable"
require "active_support/inflector"
require "active_support/core_ext/module/introspection"
require "active_support/core_ext/module/delegation"
diff --git a/railties/lib/rails/railtie/configuration.rb b/railties/lib/rails/railtie/configuration.rb
index d9997759f2..70274b948c 100644
--- a/railties/lib/rails/railtie/configuration.rb
+++ b/railties/lib/rails/railtie/configuration.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../configuration"
+require "rails/configuration"
module Rails
class Railtie
@@ -55,7 +55,7 @@ module Rails
ActiveSupport.on_load(:before_configuration, yield: true, &block)
end
- # Third configurable block to run. Does not run if +config.cache_classes+
+ # Third configurable block to run. Does not run if +config.eager_load+
# set to false.
def before_eager_load(&block)
ActiveSupport.on_load(:before_eager_load, yield: true, &block)
diff --git a/railties/lib/rails/ruby_version_check.rb b/railties/lib/rails/ruby_version_check.rb
index 76b6b80d28..b2d44d9b8e 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 Gem::Version.new(RUBY_VERSION) < Gem::Version.new("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 aea72b2d01..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. 😘
@@ -32,23 +31,10 @@ module Rails
end
end
- def generate_key
- SecureRandom.hex(OpenSSL::Cipher.new(@cipher).key_len)
- end
-
def key
ENV["RAILS_MASTER_KEY"] || read_key_file || handle_missing_key
end
- def template
- <<-end_of_template.strip_heredoc
- # See `secrets.yml` for tips on generating suitable keys.
- # production:
- # external_api_key: 1466aac22e6a869134be3d09b9e89232fc2c2289
-
- end_of_template
- end
-
def encrypt(data)
encryptor.encrypt_and_sign(data)
end
@@ -70,10 +56,6 @@ module Rails
writing(read, &block)
end
- def read_template_for_editing(&block)
- writing(template, &block)
- end
-
private
def handle_missing_key
raise MissingKeyError
diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb
index 1db6c98537..7257aaeaae 100644
--- a/railties/lib/rails/source_annotation_extractor.rb
+++ b/railties/lib/rails/source_annotation_extractor.rb
@@ -1,141 +1,150 @@
# frozen_string_literal: true
-# Implements the logic behind the rake tasks for annotations like
-#
-# rails notes
-# rails notes:optimize
-#
-# and friends. See <tt>rails -T notes</tt> and <tt>railties/lib/rails/tasks/annotations.rake</tt>.
-#
-# Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
-# represent the line where the annotation lives, its tag, and its text. Note
-# the filename is not stored.
-#
-# Annotations are looked for in comments and modulus whitespace they have to
-# start with the tag optionally followed by a colon. Everything up to the end
-# of the line (or closing ERB comment tag) is considered to be their text.
-class SourceAnnotationExtractor
- Annotation = Struct.new(:line, :tag, :text) do
- def self.directories
- @@directories ||= %w(app config db lib test) + (ENV["SOURCE_ANNOTATION_DIRECTORIES"] || "").split(",")
- end
+require "active_support/deprecation"
- # Registers additional directories to be included
- # SourceAnnotationExtractor::Annotation.register_directories("spec", "another")
- def self.register_directories(*dirs)
- directories.push(*dirs)
- end
+# Remove this deprecated class in the next minor version
+#:nodoc:
+SourceAnnotationExtractor = ActiveSupport::Deprecation::DeprecatedConstantProxy.
+ new("SourceAnnotationExtractor", "Rails::SourceAnnotationExtractor")
- def self.extensions
- @@extensions ||= {}
- end
+module Rails
+ # Implements the logic behind the rake tasks for annotations like
+ #
+ # rails notes
+ # rails notes:optimize
+ #
+ # and friends. See <tt>rails -T notes</tt> and <tt>railties/lib/rails/tasks/annotations.rake</tt>.
+ #
+ # Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
+ # represent the line where the annotation lives, its tag, and its text. Note
+ # the filename is not stored.
+ #
+ # Annotations are looked for in comments and modulus whitespace they have to
+ # start with the tag optionally followed by a colon. Everything up to the end
+ # of the line (or closing ERB comment tag) is considered to be their text.
+ class SourceAnnotationExtractor
+ class Annotation < Struct.new(:line, :tag, :text)
+ def self.directories
+ @@directories ||= %w(app config db lib test) + (ENV["SOURCE_ANNOTATION_DIRECTORIES"] || "").split(",")
+ end
- # Registers new Annotations File Extensions
- # SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
- def self.register_extensions(*exts, &block)
- extensions[/\.(#{exts.join("|")})$/] = block
- end
+ # Registers additional directories to be included
+ # Rails::SourceAnnotationExtractor::Annotation.register_directories("spec", "another")
+ def self.register_directories(*dirs)
+ directories.push(*dirs)
+ end
- register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ }
- register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
- register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ }
+ def self.extensions
+ @@extensions ||= {}
+ end
- # Returns a representation of the annotation that looks like this:
+ # Registers new Annotations File Extensions
+ # Rails::SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
+ def self.register_extensions(*exts, &block)
+ extensions[/\.(#{exts.join("|")})$/] = block
+ end
+
+ register_extensions("builder", "rb", "rake", "yml", "yaml", "ruby") { |tag| /#\s*(#{tag}):?\s*(.*)$/ }
+ register_extensions("css", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
+ register_extensions("erb") { |tag| /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/ }
+
+ # Returns a representation of the annotation that looks like this:
+ #
+ # [126] [TODO] This algorithm is simple and clearly correct, make it faster.
+ #
+ # If +options+ has a flag <tt>:tag</tt> the tag is shown as in the example above.
+ # Otherwise the string contains just line and text.
+ def to_s(options = {})
+ s = "[#{line.to_s.rjust(options[:indent])}] ".dup
+ s << "[#{tag}] " if options[:tag]
+ s << text
+ end
+ end
+
+ # Prints all annotations with tag +tag+ under the root directories +app+,
+ # +config+, +db+, +lib+, and +test+ (recursively).
#
- # [126] [TODO] This algorithm is simple and clearly correct, make it faster.
+ # Additional directories may be added using a comma-delimited list set using
+ # <tt>ENV['SOURCE_ANNOTATION_DIRECTORIES']</tt>.
#
- # If +options+ has a flag <tt>:tag</tt> the tag is shown as in the example above.
- # Otherwise the string contains just line and text.
- def to_s(options = {})
- s = "[#{line.to_s.rjust(options[:indent])}] ".dup
- s << "[#{tag}] " if options[:tag]
- s << text
+ # Directories may also be explicitly set using the <tt>:dirs</tt> key in +options+.
+ #
+ # Rails::SourceAnnotationExtractor.enumerate 'TODO|FIXME', dirs: %w(app lib), tag: true
+ #
+ # If +options+ has a <tt>:tag</tt> flag, it will be passed to each annotation's +to_s+.
+ #
+ # See <tt>#find_in</tt> for a list of file extensions that will be taken into account.
+ #
+ # This class method is the single entry point for the rake tasks.
+ def self.enumerate(tag, options = {})
+ extractor = new(tag)
+ dirs = options.delete(:dirs) || Annotation.directories
+ extractor.display(extractor.find(dirs), options)
end
- end
- # Prints all annotations with tag +tag+ under the root directories +app+,
- # +config+, +db+, +lib+, and +test+ (recursively).
- #
- # Additional directories may be added using a comma-delimited list set using
- # <tt>ENV['SOURCE_ANNOTATION_DIRECTORIES']</tt>.
- #
- # Directories may also be explicitly set using the <tt>:dirs</tt> key in +options+.
- #
- # SourceAnnotationExtractor.enumerate 'TODO|FIXME', dirs: %w(app lib), tag: true
- #
- # If +options+ has a <tt>:tag</tt> flag, it will be passed to each annotation's +to_s+.
- #
- # See <tt>#find_in</tt> for a list of file extensions that will be taken into account.
- #
- # This class method is the single entry point for the rake tasks.
- def self.enumerate(tag, options = {})
- extractor = new(tag)
- dirs = options.delete(:dirs) || Annotation.directories
- extractor.display(extractor.find(dirs), options)
- end
-
- attr_reader :tag
-
- def initialize(tag)
- @tag = tag
- end
+ attr_reader :tag
- # Returns a hash that maps filenames under +dirs+ (recursively) to arrays
- # with their annotations.
- def find(dirs)
- dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
- end
+ def initialize(tag)
+ @tag = tag
+ end
- # Returns a hash that maps filenames under +dir+ (recursively) to arrays
- # with their annotations. Only files with annotations are included. Files
- # with extension +.builder+, +.rb+, +.rake+, +.yml+, +.yaml+, +.ruby+,
- # +.css+, +.js+ and +.erb+ are taken into account.
- def find_in(dir)
- results = {}
-
- Dir.glob("#{dir}/*") do |item|
- next if File.basename(item)[0] == ?.
-
- if File.directory?(item)
- results.update(find_in(item))
- else
- extension = Annotation.extensions.detect do |regexp, _block|
- regexp.match(item)
- end
+ # Returns a hash that maps filenames under +dirs+ (recursively) to arrays
+ # with their annotations.
+ def find(dirs)
+ dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
+ end
- if extension
- pattern = extension.last.call(tag)
- results.update(extract_annotations_from(item, pattern)) if pattern
+ # Returns a hash that maps filenames under +dir+ (recursively) to arrays
+ # with their annotations. Files with extensions registered in
+ # <tt>Rails::SourceAnnotationExtractor::Annotation.extensions</tt> are
+ # taken into account. Only files with annotations are included.
+ def find_in(dir)
+ results = {}
+
+ Dir.glob("#{dir}/*") do |item|
+ next if File.basename(item)[0] == ?.
+
+ if File.directory?(item)
+ results.update(find_in(item))
+ else
+ extension = Annotation.extensions.detect do |regexp, _block|
+ regexp.match(item)
+ end
+
+ if extension
+ pattern = extension.last.call(tag)
+ results.update(extract_annotations_from(item, pattern)) if pattern
+ end
end
end
- end
- results
- end
+ results
+ end
- # If +file+ is the filename of a file that contains annotations this method returns
- # a hash with a single entry that maps +file+ to an array of its annotations.
- # Otherwise it returns an empty hash.
- def extract_annotations_from(file, pattern)
- lineno = 0
- result = File.readlines(file, encoding: Encoding::BINARY).inject([]) do |list, line|
- lineno += 1
- next list unless line =~ pattern
- list << Annotation.new(lineno, $1, $2)
+ # If +file+ is the filename of a file that contains annotations this method returns
+ # a hash with a single entry that maps +file+ to an array of its annotations.
+ # Otherwise it returns an empty hash.
+ def extract_annotations_from(file, pattern)
+ lineno = 0
+ result = File.readlines(file, encoding: Encoding::BINARY).inject([]) do |list, line|
+ lineno += 1
+ next list unless line =~ pattern
+ list << Annotation.new(lineno, $1, $2)
+ end
+ result.empty? ? {} : { file => result }
end
- result.empty? ? {} : { file => result }
- end
- # Prints the mapping from filenames to annotations in +results+ ordered by filename.
- # The +options+ hash is passed to each annotation's +to_s+.
- def display(results, options = {})
- options[:indent] = results.flat_map { |f, a| a.map(&:line) }.max.to_s.size
- results.keys.sort.each do |file|
- puts "#{file}:"
- results[file].each do |note|
- puts " * #{note.to_s(options)}"
+ # Prints the mapping from filenames to annotations in +results+ ordered by filename.
+ # The +options+ hash is passed to each annotation's +to_s+.
+ def display(results, options = {})
+ options[:indent] = results.flat_map { |f, a| a.map(&:line) }.max.to_s.size
+ results.keys.sort.each do |file|
+ puts "#{file}:"
+ results[file].each do |note|
+ puts " * #{note.to_s(options)}"
+ end
+ puts
end
- puts
end
end
end
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index 2f644a20c9..56f2eba312 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -12,7 +12,6 @@ require "rake"
middleware
misc
restart
- routes
tmp
yarn
).tap { |arr|
diff --git a/railties/lib/rails/tasks/annotations.rake b/railties/lib/rails/tasks/annotations.rake
index 931f81ac7e..60bcdc5e1b 100644
--- a/railties/lib/rails/tasks/annotations.rake
+++ b/railties/lib/rails/tasks/annotations.rake
@@ -1,22 +1,22 @@
# frozen_string_literal: true
-require_relative "../source_annotation_extractor"
+require "rails/source_annotation_extractor"
desc "Enumerate all annotations (use notes:optimize, :fixme, :todo for focus)"
task :notes do
- SourceAnnotationExtractor.enumerate "OPTIMIZE|FIXME|TODO", tag: true
+ Rails::SourceAnnotationExtractor.enumerate "OPTIMIZE|FIXME|TODO", tag: true
end
namespace :notes do
["OPTIMIZE", "FIXME", "TODO"].each do |annotation|
# desc "Enumerate all #{annotation} annotations"
task annotation.downcase.intern do
- SourceAnnotationExtractor.enumerate annotation
+ Rails::SourceAnnotationExtractor.enumerate annotation
end
end
desc "Enumerate a custom annotation, specify with ANNOTATION=CUSTOM"
task :custom do
- SourceAnnotationExtractor.enumerate ENV["ANNOTATION"]
+ Rails::SourceAnnotationExtractor.enumerate ENV["ANNOTATION"]
end
end
diff --git a/railties/lib/rails/tasks/dev.rake b/railties/lib/rails/tasks/dev.rake
index 90fd3ccd8b..5aea6f7dc5 100644
--- a/railties/lib/rails/tasks/dev.rake
+++ b/railties/lib/rails/tasks/dev.rake
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "../dev_caching"
+require "rails/dev_caching"
namespace :dev do
desc "Toggle development mode caching on/off"
diff --git a/railties/lib/rails/tasks/engine.rake b/railties/lib/rails/tasks/engine.rake
index 3ce49a1641..8d77904210 100644
--- a/railties/lib/rails/tasks/engine.rake
+++ b/railties/lib/rails/tasks/engine.rake
@@ -8,7 +8,7 @@ task "load_app" do
task update: [ "update:bin" ]
namespace :update do
- require_relative "../engine/updater"
+ require "rails/engine/updater"
# desc "Adds new executables to the engine bin/ directory"
task :bin do
Rails::Engine::Updater.run(:create_bin_files)
@@ -53,7 +53,7 @@ namespace :db do
desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
app_task "rollback"
- desc "Create a db/schema.rb file that can be portably used against any DB supported by Active Record"
+ desc "Create a db/schema.rb file that can be portably used against any database supported by Active Record"
app_task "schema:dump"
desc "Load a schema.rb file into the database"
@@ -62,7 +62,7 @@ namespace :db do
desc "Load the seed data from db/seeds.rb"
app_task "seed"
- desc "Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)"
+ desc "Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the database first)"
app_task "setup"
desc "Dump the database structure to an SQL file"
@@ -70,6 +70,9 @@ namespace :db do
desc "Retrieves the current schema version number"
app_task "version"
+
+ # desc 'Load the test schema'
+ app_task "test:prepare"
end
def find_engine_path(path)
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 8931aabcda..7dfcd14bd0 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -9,8 +9,8 @@ namespace :app do
template = ENV["LOCATION"]
raise "No LOCATION value given. Please set LOCATION either as path to a file or a URL" if template.blank?
template = File.expand_path(template) if template !~ %r{\A[A-Za-z][A-Za-z0-9+\-\.]*://}
- require_relative "../generators"
- require_relative "../generators/rails/app/app_generator"
+ require "rails/generators"
+ require "rails/generators/rails/app/app_generator"
generator = Rails::Generators::AppGenerator.new [Rails.root], {}, { destination_root: Rails.root }
generator.apply template, verbose: false
end
@@ -38,7 +38,7 @@ namespace :app do
end
namespace :update do
- require_relative "../app_updater"
+ require "rails/app_updater"
# desc "Update config/boot.rb from your current rails install"
task :configs do
diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake
deleted file mode 100644
index 403286d280..0000000000
--- a/railties/lib/rails/tasks/routes.rake
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-require "optparse"
-
-desc "Print out all defined routes in match order, with names. Target specific controller with -c option, or grep routes using -g option"
-task routes: :environment do
- all_routes = Rails.application.routes.routes
- require "action_dispatch/routing/inspector"
- inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
-
- routes_filter = nil
-
- OptionParser.new do |opts|
- opts.banner = "Usage: rails routes [options]"
-
- Rake.application.standard_rake_options.each { |args| opts.on(*args) }
-
- opts.on("-c CONTROLLER") do |controller|
- routes_filter = { controller: controller }
- end
-
- opts.on("-g PATTERN") do |pattern|
- routes_filter = pattern
- end
-
- end.parse!(ARGV.reject { |x| x == "routes" })
-
- puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, routes_filter)
-
- exit 0 # ensure extra arguments aren't interpreted as Rake tasks
-end
diff --git a/railties/lib/rails/tasks/statistics.rake b/railties/lib/rails/tasks/statistics.rake
index 0449a13586..594db91eec 100644
--- a/railties/lib/rails/tasks/statistics.rake
+++ b/railties/lib/rails/tasks/statistics.rake
@@ -26,6 +26,6 @@ end.select { |name, dir| File.directory?(dir) }
desc "Report code statistics (KLOCs, etc) from the application or engine"
task :stats do
- require_relative "../code_statistics"
+ require "rails/code_statistics"
CodeStatistics.new(*STATS_DIRECTORIES).to_s
end
diff --git a/railties/lib/rails/tasks/yarn.rake b/railties/lib/rails/tasks/yarn.rake
index 48da7ffc51..10703a1808 100644
--- a/railties/lib/rails/tasks/yarn.rake
+++ b/railties/lib/rails/tasks/yarn.rake
@@ -3,7 +3,7 @@
namespace :yarn do
desc "Install all JavaScript dependencies as specified via Yarn"
task :install do
- system("./bin/yarn install --no-progress --production")
+ system("./bin/yarn install --no-progress --frozen-lockfile --production")
end
end
diff --git a/railties/lib/rails/templates/rails/mailers/email.html.erb b/railties/lib/rails/templates/rails/mailers/email.html.erb
index 89c1129f90..2a41c29602 100644
--- a/railties/lib/rails/templates/rails/mailers/email.html.erb
+++ b/railties/lib/rails/templates/rails/mailers/email.html.erb
@@ -95,11 +95,25 @@
</dd>
<% end %>
+ <dt>Format:</dt>
<% if @email.multipart? %>
<dd>
- <select onchange="formatChanged(this);">
- <option <%= request.format == Mime[:html] ? 'selected' : '' %> value="?<%= part_query('text/html') %>">View as HTML email</option>
- <option <%= request.format == Mime[:text] ? 'selected' : '' %> value="?<%= part_query('text/plain') %>">View as plain-text email</option>
+ <select id="part" onchange="refreshBody();">
+ <option <%= request.format == Mime[:html] ? 'selected' : '' %> value="<%= part_query('text/html') %>">View as HTML email</option>
+ <option <%= request.format == Mime[:text] ? 'selected' : '' %> value="<%= part_query('text/plain') %>">View as plain-text email</option>
+ </select>
+ </dd>
+ <% else %>
+ <dd id="mime_type" data-mime-type="<%= part_query(@email.mime_type) %>"><%= @email.mime_type == 'text/html' ? 'HTML email' : 'plain-text email' %></dd>
+ <% end %>
+
+ <% if I18n.available_locales.count > 1 %>
+ <dt>Locale:</dt>
+ <dd>
+ <select id="locale" onchange="refreshBody();">
+ <% I18n.available_locales.each do |locale| %>
+ <option <%= I18n.locale == locale ? 'selected' : '' %> value="<%= locale_query(locale) %>"><%= locale %></option>
+ <% end %>
</select>
</dd>
<% end %>
@@ -116,15 +130,27 @@
<% end %>
<script>
- function formatChanged(form) {
- var part_name = form.options[form.selectedIndex].value
- var iframe =document.getElementsByName('messageBody')[0];
- iframe.contentWindow.location.replace(part_name);
+ function refreshBody() {
+ var part_select = document.querySelector('select#part');
+ var locale_select = document.querySelector('select#locale');
+ var iframe = document.getElementsByName('messageBody')[0];
+ var part_param = part_select ?
+ part_select.options[part_select.selectedIndex].value :
+ document.querySelector('#mime_type').dataset.mimeType;
+ var locale_param = locale_select ? locale_select.options[locale_select.selectedIndex].value : null;
+ var fresh_location;
+ if (locale_param) {
+ fresh_location = '?' + part_param + '&' + locale_param;
+ } else {
+ fresh_location = '?' + part_param;
+ }
+ iframe.contentWindow.location = fresh_location;
if (history.replaceState) {
- var url = location.pathname.replace(/\.(txt|html)$/, '');
- var format = /html/.test(part_name) ? '.html' : '.txt';
- window.history.replaceState({}, '', url + format);
+ var url = location.pathname.replace(/\.(txt|html)$/, '');
+ var format = /html/.test(part_param) ? '.html' : '.txt';
+ var state_to_replace = locale_param ? (url + format + '?' + locale_param) : (url + format);
+ window.history.replaceState({}, '', state_to_replace);
}
}
</script>
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index f755474488..4bd7d74b04 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -8,7 +8,7 @@ require "active_support/test_case"
require "action_controller"
require "action_controller/test_case"
require "action_dispatch/testing/integration"
-require_relative "generators/test_case"
+require "rails/generators/test_case"
require "active_support/testing/autorun"
@@ -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"
@@ -29,10 +30,6 @@ if defined?(ActiveRecord::Base)
end
ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
-
- def create_fixtures(*fixture_set_names, &block)
- FixtureSet.create_fixtures(ActiveSupport::TestCase.fixture_path, fixture_set_names, {}, &block)
- end
end
# :enddoc:
diff --git a/railties/lib/rails/test_unit/railtie.rb b/railties/lib/rails/test_unit/railtie.rb
index 05f9a177d0..42b6daa3d1 100644
--- a/railties/lib/rails/test_unit/railtie.rb
+++ b/railties/lib/rails/test_unit/railtie.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "line_filtering"
+require "rails/test_unit/line_filtering"
if defined?(Rake.application) && Rake.application.top_level_tasks.grep(/^(default$|test(:|$))/).any?
ENV["RAILS_ENV"] ||= Rake.application.options.show_tasks ? "development" : "test"
diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb
index 7d3164f1eb..28b93cee5a 100644
--- a/railties/lib/rails/test_unit/reporter.rb
+++ b/railties/lib/rails/test_unit/reporter.rb
@@ -64,11 +64,17 @@ module Rails
end
def format_line(result)
- "%s#%s = %.2f s = %s" % [result.class, result.name, result.time, result.result_code]
+ klass = result.respond_to?(:klass) ? result.klass : result.class
+ "%s#%s = %.2f s = %s" % [klass, result.name, result.time, result.result_code]
end
def format_rerun_snippet(result)
- location, line = result.method(result.name).source_location
+ location, line = if result.respond_to?(:source_location)
+ result.source_location
+ else
+ result.method(result.name).source_location
+ end
+
"#{executable} #{relative_path_for(location)}:#{line}"
end
diff --git a/railties/lib/rails/test_unit/runner.rb b/railties/lib/rails/test_unit/runner.rb
index 5c2f6451e2..de5744c662 100644
--- a/railties/lib/rails/test_unit/runner.rb
+++ b/railties/lib/rails/test_unit/runner.rb
@@ -13,7 +13,7 @@ module Rails
class << self
def attach_before_load_options(opts)
opts.on("--warnings", "-w", "Run with Ruby warnings enabled") {}
- opts.on("--environment", "-e", "Run tests in the ENV environment") {}
+ opts.on("-e", "--environment ENV", "Run tests in the ENV environment") {}
end
def parse_options(argv)
diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake
index 18d699f806..32ac27a135 100644
--- a/railties/lib/rails/test_unit/testing.rake
+++ b/railties/lib/rails/test_unit/testing.rake
@@ -2,7 +2,7 @@
gem "minitest"
require "minitest"
-require_relative "runner"
+require "rails/test_unit/runner"
task default: :test
diff --git a/railties/lib/rails/welcome_controller.rb b/railties/lib/rails/welcome_controller.rb
index 0cb43e0f31..5b84b57679 100644
--- a/railties/lib/rails/welcome_controller.rb
+++ b/railties/lib/rails/welcome_controller.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require_relative "application_controller"
+require "rails/application_controller"
class Rails::WelcomeController < Rails::ApplicationController # :nodoc:
layout false
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/app_loader_test.rb b/railties/test/app_loader_test.rb
index bb556f1968..c7a6bdee1b 100644
--- a/railties/test/app_loader_test.rb
+++ b/railties/test/app_loader_test.rb
@@ -40,13 +40,13 @@ class AppLoaderTest < ActiveSupport::TestCase
test "is not in a Rails application if #{exe} is not found in the current or parent directories" do
def loader.find_executables; end
- assert !loader.exec_app
+ assert_not loader.exec_app
end
test "is not in a Rails application if #{exe} exists but is a folder" do
FileUtils.mkdir_p(exe)
- assert !loader.exec_app
+ assert_not loader.exec_app
end
["APP_PATH", "ENGINE_PATH"].each do |keyword|
@@ -61,7 +61,7 @@ class AppLoaderTest < ActiveSupport::TestCase
test "is not in a Rails application if #{exe} exists but doesn't contain #{keyword}" do
write exe
- assert !loader.exec_app
+ assert_not loader.exec_app
end
test "is in a Rails application if parent directory has #{exe} containing #{keyword} and chdirs to the root directory" do
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..9ef123c5b6 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -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 c1a80eaeaf..84606d3b90 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"
@@ -487,6 +487,32 @@ module ApplicationTests
assert_equal "some_value", Rails.application.message_verifier(:sensitive_value).verify(message)
end
+ test "config.secret_token is deprecated" do
+ app_file "config/initializers/secret_token.rb", <<-RUBY
+ Rails.application.config.secret_token = "b3c631c314c0bbca50c1b2843150fe33"
+ RUBY
+
+ app "production"
+
+ assert_deprecated(/secret_token/) do
+ app.secrets
+ end
+ end
+
+ test "secrets.secret_token is deprecated" do
+ app_file "config/secrets.yml", <<-YAML
+ production:
+ secret_token: "b3c631c314c0bbca50c1b2843150fe33"
+ YAML
+
+ app "production"
+
+ assert_deprecated(/secret_token/) do
+ app.secrets
+ end
+ end
+
+
test "raises when secret_key_base is blank" do
app_file "config/initializers/secret_token.rb", <<-RUBY
Rails.application.credentials.secret_key_base = nil
@@ -550,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
@@ -681,6 +708,14 @@ module ApplicationTests
assert_match(/Missing.*RAILS_MASTER_KEY/, error)
end
+ test "credentials does not raise error when require_master_key is false and master key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = false"
+ app "development"
+
+ assert_not app.credentials.secret_key_base
+ end
+
test "protect from forgery is the default in a new app" do
make_basic_app
@@ -731,6 +766,68 @@ module ApplicationTests
assert_match(/label/, last_response.body)
end
+ test "form_with can be configured with form_with_generates_ids" do
+ app_file "config/initializers/form_builder.rb", <<-RUBY
+ Rails.configuration.action_view.form_with_generates_ids = false
+ RUBY
+
+ app_file "app/models/post.rb", <<-RUBY
+ class Post
+ include ActiveModel::Model
+ attr_accessor :name
+ end
+ RUBY
+
+ app_file "app/controllers/posts_controller.rb", <<-RUBY
+ class PostsController < ApplicationController
+ def index
+ render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
+ end
+ end
+ RUBY
+
+ add_to_config <<-RUBY
+ routes.prepend do
+ resources :posts
+ end
+ RUBY
+
+ app "development"
+
+ get "/posts"
+
+ assert_no_match(/id=('|")post_name('|")/, last_response.body)
+ end
+
+ test "form_with outputs ids by default" do
+ app_file "app/models/post.rb", <<-RUBY
+ class Post
+ include ActiveModel::Model
+ attr_accessor :name
+ end
+ RUBY
+
+ app_file "app/controllers/posts_controller.rb", <<-RUBY
+ class PostsController < ApplicationController
+ def index
+ render inline: "<%= begin; form_with(model: Post.new) {|f| f.text_field(:name)}; rescue => e; e.to_s; end %>"
+ end
+ end
+ RUBY
+
+ add_to_config <<-RUBY
+ routes.prepend do
+ resources :posts
+ end
+ RUBY
+
+ app "development"
+
+ get "/posts"
+
+ assert_match(/id=('|")post_name('|")/, last_response.body)
+ end
+
test "form_with can be configured with form_with_generates_remote_forms" do
app_file "config/initializers/form_builder.rb", <<-RUBY
Rails.configuration.action_view.form_with_generates_remote_forms = false
@@ -1229,7 +1326,7 @@ module ApplicationTests
assert_equal 200, last_response.status
end
- test "config.action_controller.action_on_unpermitted_parameters is :log by default on development" do
+ test "config.action_controller.action_on_unpermitted_parameters is :log by default in development" do
app "development"
force_lazy_load_hooks { ActionController::Base }
@@ -1238,7 +1335,7 @@ module ApplicationTests
assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
end
- test "config.action_controller.action_on_unpermitted_parameters is :log by default on test" do
+ test "config.action_controller.action_on_unpermitted_parameters is :log by default in test" do
app "test"
force_lazy_load_hooks { ActionController::Base }
@@ -1247,7 +1344,7 @@ module ApplicationTests
assert_equal :log, ActionController::Parameters.action_on_unpermitted_parameters
end
- test "config.action_controller.action_on_unpermitted_parameters is false by default on production" do
+ test "config.action_controller.action_on_unpermitted_parameters is false by default in production" do
app "production"
force_lazy_load_hooks { ActionController::Base }
@@ -1320,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
@@ -1382,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
@@ -1394,12 +1491,18 @@ module ApplicationTests
assert_not ActiveRecord::Base.dump_schema_after_migration
end
- test "config.active_record.dump_schema_after_migration is true by default on development" do
+ test "config.active_record.dump_schema_after_migration is true by default in development" do
app "development"
assert ActiveRecord::Base.dump_schema_after_migration
end
+ test "config.active_record.verbose_query_logs is false by default in development" do
+ app "development"
+
+ assert_not ActiveRecord::Base.verbose_query_logs
+ end
+
test "config.annotations wrapping SourceAnnotationExtractor::Annotation class" do
make_basic_app do |application|
application.config.annotations.register_extensions("coffee") do |tag|
@@ -1407,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
@@ -1637,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
@@ -1666,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
@@ -1731,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
@@ -1788,6 +1889,96 @@ module ApplicationTests
assert_equal "https://example.org/", last_response.location
end
+ 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 "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"
+
+ 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
+
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
new file mode 100644
index 0000000000..0d28df16f8
--- /dev/null
+++ b/railties/test/application/content_security_policy_test.rb
@@ -0,0 +1,223 @@
+# frozen_string_literal: true
+
+require "isolation/abstract_unit"
+require "rack/test"
+
+module ApplicationTests
+ class ContentSecurityPolicyTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
+
+ def setup
+ build_app
+ end
+
+ def teardown
+ teardown_app
+ end
+
+ test "default content security policy is nil" do
+ controller :pages, <<-RUBY
+ class PagesController < ApplicationController
+ def index
+ render html: "<h1>Welcome to Rails!</h1>"
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ root to: "pages#index"
+ end
+ RUBY
+
+ app("development")
+
+ get "/"
+ 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
+ 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|
+ p.default_src :self, :https
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ root to: "pages#index"
+ end
+ RUBY
+
+ app("development")
+
+ get "/"
+ assert_policy "default-src 'self' https:"
+ end
+
+ test "global report only content security policy in an initializer" 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|
+ p.default_src :self, :https
+ end
+
+ Rails.application.config.content_security_policy_report_only = true
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ root to: "pages#index"
+ end
+ RUBY
+
+ app("development")
+
+ get "/"
+ assert_policy "default-src 'self' https:", report_only: true
+ end
+
+ test "override content security policy in a controller" do
+ controller :pages, <<-RUBY
+ class PagesController < ApplicationController
+ content_security_policy do |p|
+ p.default_src "https://example.com"
+ end
+
+ 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|
+ p.default_src :self, :https
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ root to: "pages#index"
+ end
+ RUBY
+
+ app("development")
+
+ get "/"
+ assert_policy "default-src https://example.com"
+ end
+
+ test "override content security policy to report only in a controller" do
+ controller :pages, <<-RUBY
+ class PagesController < ApplicationController
+ content_security_policy_report_only
+
+ 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|
+ p.default_src :self, :https
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ root to: "pages#index"
+ end
+ RUBY
+
+ app("development")
+
+ get "/"
+ assert_policy "default-src 'self' https:", report_only: true
+ end
+
+ test "global content security policy added to rack app" do
+ app_file "config/initializers/content_security_policy.rb", <<-RUBY
+ Rails.application.config.content_security_policy do |p|
+ p.default_src :self, :https
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+
+ app = ->(env) {
+ [200, { "Content-Type" => "text/html" }, ["<p>Hello, World!</p>"]]
+ }
+
+ root to: app
+ end
+ RUBY
+
+ app("development")
+
+ get "/"
+ assert_policy "default-src 'self' https:"
+ end
+
+ private
+
+ def assert_policy(expected, report_only: false)
+ assert_equal 200, last_response.status
+
+ if report_only
+ expected_header = "Content-Security-Policy-Report-Only"
+ unexpected_header = "Content-Security-Policy"
+ else
+ expected_header = "Content-Security-Policy"
+ unexpected_header = "Content-Security-Policy-Report-Only"
+ end
+
+ assert_nil last_response.headers[unexpected_header]
+ assert_equal expected, last_response.headers[expected_header]
+ end
+ end
+end
diff --git a/railties/test/application/dbconsole_test.rb b/railties/test/application/dbconsole_test.rb
index ba04c81b4d..8eb293c179 100644
--- a/railties/test/application/dbconsole_test.rb
+++ b/railties/test/application/dbconsole_test.rb
@@ -19,21 +19,19 @@ module ApplicationTests
end
def test_use_value_defined_in_environment_file_in_database_yml
- Dir.chdir(app_path) do
- app_file "config/database.yml", <<-YAML
- development:
- database: <%= Rails.application.config.database %>
- adapter: sqlite3
- pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
- timeout: 5000
- YAML
+ app_file "config/database.yml", <<-YAML
+ development:
+ database: <%= Rails.application.config.database %>
+ adapter: sqlite3
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+ timeout: 5000
+ YAML
- app_file "config/environments/development.rb", <<-RUBY
- Rails.application.configure do
- config.database = "db/development.sqlite3"
- end
- RUBY
- end
+ app_file "config/environments/development.rb", <<-RUBY
+ Rails.application.configure do
+ config.database = "db/development.sqlite3"
+ end
+ RUBY
master, slave = PTY.open
spawn_dbconsole(slave)
@@ -43,22 +41,20 @@ module ApplicationTests
end
def test_respect_environment_option
- Dir.chdir(app_path) do
- app_file "config/database.yml", <<-YAML
- default: &default
- adapter: sqlite3
- pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
- timeout: 5000
+ app_file "config/database.yml", <<-YAML
+ default: &default
+ adapter: sqlite3
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+ timeout: 5000
- development:
- <<: *default
- database: db/development.sqlite3
+ development:
+ <<: *default
+ database: db/development.sqlite3
- production:
- <<: *default
- database: db/production.sqlite3
- YAML
- end
+ production:
+ <<: *default
+ database: db/production.sqlite3
+ YAML
master, slave = PTY.open
spawn_dbconsole(slave, "-e production")
diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb
index 47c815d221..e5e557d204 100644
--- a/railties/test/application/generators_test.rb
+++ b/railties/test/application/generators_test.rb
@@ -188,10 +188,11 @@ module ApplicationTests
Rails::Command.send(:remove_const, "APP_PATH")
end
- test "help does not show hidden namespaces" do
+ test "help does not show hidden namespaces and hidden commands" do
FileUtils.cd(rails_root) do
output = rails("generate", "--help")
assert_no_match "active_record:migration", output
+ assert_no_match "credentials", output
output = rails("destroy", "--help")
assert_no_match "active_record:migration", output
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/initializers/notifications_test.rb b/railties/test/application/initializers/notifications_test.rb
index 23b20d578c..c65c955734 100644
--- a/railties/test/application/initializers/notifications_test.rb
+++ b/railties/test/application/initializers/notifications_test.rb
@@ -32,6 +32,7 @@ module ApplicationTests
logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new
ActiveRecord::Base.logger = logger
+ ActiveRecord::Base.verbose_query_logs = false
# Mimic Active Record notifications
instrument "sql.active_record", name: "SQL", sql: "SHOW tables"
diff --git a/railties/test/application/integration_test_case_test.rb b/railties/test/application/integration_test_case_test.rb
index 9edc907fce..c08761092b 100644
--- a/railties/test/application/integration_test_case_test.rb
+++ b/railties/test/application/integration_test_case_test.rb
@@ -1,10 +1,11 @@
# frozen_string_literal: true
require "isolation/abstract_unit"
+require "env_helpers"
module ApplicationTests
class IntegrationTestCaseTest < ActiveSupport::TestCase
- include ActiveSupport::Testing::Isolation
+ include ActiveSupport::Testing::Isolation, EnvHelpers
setup do
build_app
@@ -39,13 +40,14 @@ module ApplicationTests
end
RUBY
+ with_rails_env("test") { rails("db:migrate") }
output = rails("test")
assert_match(/0 failures, 0 errors/, output)
end
end
class IntegrationTestDefaultApp < ActiveSupport::TestCase
- include ActiveSupport::Testing::Isolation
+ include ActiveSupport::Testing::Isolation, EnvHelpers
setup do
build_app
@@ -66,6 +68,7 @@ module ApplicationTests
end
RUBY
+ with_rails_env("test") { rails("db:migrate") }
output = rails("test")
assert_match(/0 failures, 0 errors/, output)
end
diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb
index 11c886e991..889ad16fb8 100644
--- a/railties/test/application/loading_test.rb
+++ b/railties/test/application/loading_test.rb
@@ -300,7 +300,7 @@ class LoadingTest < ActiveSupport::TestCase
end
MIGRATION
- Dir.chdir(app_path) { `rake db:migrate` }
+ rails("db:migrate")
require "#{rails_root}/config/environment"
get "/title"
@@ -314,7 +314,7 @@ class LoadingTest < ActiveSupport::TestCase
end
MIGRATION
- Dir.chdir(app_path) { `rake db:migrate` }
+ rails("db:migrate")
get "/body"
assert_equal "BODY", last_response.body
@@ -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 &#39;notifier&#39; 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 &#39;bar&#39; 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 &#39;text/html&#39; 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&amp;part=text%2Fhtml">', last_response.body
- assert_match '<option selected value="?name=Ruby&amp;part=text%2Fhtml">', last_response.body
- assert_match '<option value="?name=Ruby&amp;part=text%2Fplain">', last_response.body
+ assert_match '<option selected value="name=Ruby&amp;part=text%2Fhtml">', last_response.body
+ assert_match '<option value="name=Ruby&amp;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/cookies_test.rb b/railties/test/application/middleware/cookies_test.rb
index 23f1ec3e35..ecb4ee3446 100644
--- a/railties/test/application/middleware/cookies_test.rb
+++ b/railties/test/application/middleware/cookies_test.rb
@@ -1,10 +1,12 @@
# frozen_string_literal: true
require "isolation/abstract_unit"
+require "rack/test"
module ApplicationTests
class CookiesTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
+ include Rack::Test::Methods
def new_app
File.expand_path("#{app_path}/../new_app")
@@ -15,6 +17,10 @@ module ApplicationTests
FileUtils.rm_rf("#{app_path}/config/environments")
end
+ def app
+ Rails.application
+ end
+
def teardown
teardown_app
FileUtils.rm_rf(new_app) if File.directory?(new_app)
@@ -44,5 +50,144 @@ module ApplicationTests
require "#{app_path}/config/environment"
assert_equal false, ActionDispatch::Cookies::CookieJar.always_write_cookie
end
+
+ test "signed cookies with SHA512 digest and rotated out SHA256 and SHA1 digests" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get ':controller(/:action)'
+ post ':controller(/:action)'
+ end
+ RUBY
+
+ controller :foo, <<-RUBY
+ class FooController < ActionController::Base
+ protect_from_forgery with: :null_session
+
+ def write_raw_cookie_sha1
+ cookies[:signed_cookie] = TestVerifiers.sha1.generate("signed cookie")
+ head :ok
+ end
+
+ def write_raw_cookie_sha256
+ cookies[:signed_cookie] = TestVerifiers.sha256.generate("signed cookie")
+ head :ok
+ end
+
+ def read_signed
+ render plain: cookies.signed[:signed_cookie].inspect
+ end
+
+ def read_raw_cookie
+ render plain: cookies[:signed_cookie]
+ end
+ end
+ RUBY
+
+ add_to_config <<-RUBY
+ sha1_secret = Rails.application.key_generator.generate_key("sha1")
+ sha256_secret = Rails.application.key_generator.generate_key("sha256")
+
+ ::TestVerifiers = Class.new do
+ class_attribute :sha1, default: ActiveSupport::MessageVerifier.new(sha1_secret, digest: "SHA1")
+ class_attribute :sha256, default: ActiveSupport::MessageVerifier.new(sha256_secret, digest: "SHA256")
+ end
+
+ config.action_dispatch.signed_cookie_digest = "SHA512"
+ config.action_dispatch.signed_cookie_salt = "sha512 salt"
+
+ config.action_dispatch.cookies_rotations.tap do |cookies|
+ cookies.rotate :signed, sha1_secret, digest: "SHA1"
+ cookies.rotate :signed, sha256_secret, digest: "SHA256"
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ verifier_sha512 = ActiveSupport::MessageVerifier.new(app.key_generator.generate_key("sha512 salt"), digest: :SHA512)
+
+ get "/foo/write_raw_cookie_sha1"
+ get "/foo/read_signed"
+ assert_equal "signed cookie".inspect, last_response.body
+
+ get "/foo/read_raw_cookie"
+ assert_equal "signed cookie", verifier_sha512.verify(last_response.body)
+
+ get "/foo/write_raw_cookie_sha256"
+ get "/foo/read_signed"
+ assert_equal "signed cookie".inspect, last_response.body
+
+ get "/foo/read_raw_cookie"
+ assert_equal "signed cookie", verifier_sha512.verify(last_response.body)
+ end
+
+ test "encrypted cookies rotating multiple encryption keys" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get ':controller(/:action)'
+ post ':controller(/:action)'
+ end
+ RUBY
+
+ controller :foo, <<-RUBY
+ class FooController < ActionController::Base
+ protect_from_forgery with: :null_session
+
+ def write_raw_cookie_one
+ cookies[:encrypted_cookie] = TestEncryptors.first_gcm.encrypt_and_sign("encrypted cookie")
+ head :ok
+ end
+
+ def write_raw_cookie_two
+ cookies[:encrypted_cookie] = TestEncryptors.second_gcm.encrypt_and_sign("encrypted cookie")
+ head :ok
+ end
+
+ def read_encrypted
+ render plain: cookies.encrypted[:encrypted_cookie].inspect
+ end
+
+ def read_raw_cookie
+ render plain: cookies[:encrypted_cookie]
+ end
+ end
+ RUBY
+
+ add_to_config <<-RUBY
+ first_secret = Rails.application.key_generator.generate_key("first", 32)
+ second_secret = Rails.application.key_generator.generate_key("second", 32)
+
+ ::TestEncryptors = Class.new do
+ class_attribute :first_gcm, default: ActiveSupport::MessageEncryptor.new(first_secret, cipher: "aes-256-gcm")
+ class_attribute :second_gcm, default: ActiveSupport::MessageEncryptor.new(second_secret, cipher: "aes-256-gcm")
+ end
+
+ config.action_dispatch.use_authenticated_cookie_encryption = true
+ config.action_dispatch.encrypted_cookie_cipher = "aes-256-gcm"
+ config.action_dispatch.authenticated_encrypted_cookie_salt = "salt"
+
+ config.action_dispatch.cookies_rotations.tap do |cookies|
+ cookies.rotate :encrypted, first_secret
+ cookies.rotate :encrypted, second_secret
+ end
+ RUBY
+
+ require "#{app_path}/config/environment"
+
+ encryptor = ActiveSupport::MessageEncryptor.new(app.key_generator.generate_key("salt", 32), cipher: "aes-256-gcm")
+
+ get "/foo/write_raw_cookie_one"
+ get "/foo/read_encrypted"
+ assert_equal "encrypted cookie".inspect, last_response.body
+
+ get "/foo/read_raw_cookie"
+ assert_equal "encrypted cookie", encryptor.decrypt_and_verify(last_response.body)
+
+ get "/foo/write_raw_cookie_sha256"
+ get "/foo/read_encrypted"
+ assert_equal "encrypted cookie".inspect, last_response.body
+
+ get "/foo/read_raw_cookie"
+ assert_equal "encrypted cookie", encryptor.decrypt_and_verify(last_response.body)
+ end
end
end
diff --git a/railties/test/application/middleware/exceptions_test.rb b/railties/test/application/middleware/exceptions_test.rb
index 75afeec905..2d659ade8d 100644
--- a/railties/test/application/middleware/exceptions_test.rb
+++ b/railties/test/application/middleware/exceptions_test.rb
@@ -102,7 +102,7 @@ module ApplicationTests
end
end
- test "routing to an nonexistent controller when action_dispatch.show_exceptions and consider_all_requests_local are set shows diagnostics" do
+ test "routing to a nonexistent controller when action_dispatch.show_exceptions and consider_all_requests_local are set shows diagnostics" do
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
resources :articles
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 0a5a524692..5efaf841d4 100644
--- a/railties/test/application/middleware_test.rb
+++ b/railties/test/application/middleware_test.rb
@@ -42,9 +42,11 @@ module ApplicationTests
"ActionDispatch::Cookies",
"ActionDispatch::Session::CookieStore",
"ActionDispatch::Flash",
+ "ActionDispatch::ContentSecurityPolicy::Middleware",
"Rack::Head",
"Rack::ConditionalGet",
- "Rack::ETag"
+ "Rack::ETag",
+ "Rack::TempfileReaper"
], middleware
end
@@ -248,7 +250,7 @@ module ApplicationTests
test "can't change middleware after it's built" do
boot!
- assert_raise RuntimeError do
+ assert_raise frozen_error_class do
app.config.middleware.use Rack::Config
end
end
diff --git a/railties/test/application/per_request_digest_cache_test.rb b/railties/test/application/per_request_digest_cache_test.rb
index e9bc91785c..10d3313f6e 100644
--- a/railties/test/application/per_request_digest_cache_test.rb
+++ b/railties/test/application/per_request_digest_cache_test.rb
@@ -59,7 +59,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/rake/dbs_test.rb b/railties/test/application/rake/dbs_test.rb
index 391676aa31..0594236b1f 100644
--- a/railties/test/application/rake/dbs_test.rb
+++ b/railties/test/application/rake/dbs_test.rb
@@ -26,15 +26,15 @@ module ApplicationTests
FileUtils.rm_rf("#{app_path}/config/database.yml")
end
- def db_create_and_drop(expected_database)
+ def db_create_and_drop(expected_database, environment_loaded: true)
Dir.chdir(app_path) do
output = rails("db:create")
assert_match(/Created database/, output)
assert File.exist?(expected_database)
- assert_equal expected_database, ActiveRecord::Base.connection_config[:database]
+ 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
@@ -49,6 +49,22 @@ module ApplicationTests
db_create_and_drop database_url_db_name
end
+ test "db:create and db:drop respect environment setting" do
+ app_file "config/database.yml", <<-YAML
+ development:
+ database: <%= Rails.application.config.database %>
+ adapter: sqlite3
+ YAML
+
+ app_file "config/environments/development.rb", <<-RUBY
+ Rails.application.configure do
+ config.database = "db/development.sqlite3"
+ end
+ RUBY
+
+ db_create_and_drop "db/development.sqlite3", environment_loaded: false
+ end
+
def with_database_existing
Dir.chdir(app_path) do
set_database_url
@@ -82,13 +98,25 @@ module ApplicationTests
end
end
- test "db:drop failure because database does not exist" do
- Dir.chdir(app_path) do
- output = rails("db:drop:_unsafe", "--trace")
- assert_match(/does not exist/, output)
+ test "db:create works when schema cache exists and database does not exist" do
+ use_postgresql
+
+ begin
+ rails %w(db:create db:migrate db:schema:cache:dump)
+
+ rails "db:drop"
+ rails "db:create"
+ assert_equal 0, $?.exitstatus
+ ensure
+ rails "db:drop" rescue nil
end
end
+ test "db:drop failure because database does not exist" do
+ output = rails("db:drop:_unsafe", "--trace")
+ assert_match(/does not exist/, output)
+ end
+
test "db:drop failure because bad permissions" do
with_database_existing do
with_bad_permissions do
@@ -100,13 +128,11 @@ module ApplicationTests
end
def db_migrate_and_status(expected_database)
- Dir.chdir(app_path) do
- rails "generate", "model", "book", "title:string"
- rails "db:migrate"
- output = rails("db:migrate:status")
- assert_match(%r{database:\s+\S*#{Regexp.escape(expected_database)}}, output)
- assert_match(/up\s+\d{14}\s+Create books/, output)
- end
+ rails "generate", "model", "book", "title:string"
+ rails "db:migrate"
+ output = rails("db:migrate:status")
+ assert_match(%r{database:\s+\S*#{Regexp.escape(expected_database)}}, output)
+ assert_match(/up\s+\d{14}\s+Create books/, output)
end
test "db:migrate and db:migrate:status without database_url" do
@@ -161,12 +187,11 @@ module ApplicationTests
test "db:fixtures:load with namespaced fixture" do
require "#{app_path}/config/environment"
- Dir.chdir(app_path) do
- rails "generate", "model", "admin::book", "title:string"
- rails "db:migrate", "db:fixtures:load"
- require "#{app_path}/app/models/admin/book"
- assert_equal 2, Admin::Book.count
- end
+
+ rails "generate", "model", "admin::book", "title:string"
+ rails "db:migrate", "db:fixtures:load"
+ require "#{app_path}/app/models/admin/book"
+ assert_equal 2, Admin::Book.count
end
def db_structure_dump_and_load(expected_database)
@@ -178,7 +203,7 @@ module ApplicationTests
rails "environment", "db:drop", "db:structure:load"
assert_match expected_database, ActiveRecord::Base.connection_config[:database]
require "#{app_path}/app/models/book"
- #if structure is not loaded correctly, exception would be raised
+ # if structure is not loaded correctly, exception would be raised
assert_equal 0, Book.count
end
end
@@ -194,6 +219,14 @@ module ApplicationTests
db_structure_dump_and_load database_url_db_name
end
+ test "db:structure:dump and db:structure:load set ar_internal_metadata" do
+ require "#{app_path}/config/environment"
+ db_structure_dump_and_load ActiveRecord::Base.configurations[Rails.env]["database"]
+
+ assert_equal "test", rails("runner", "-e", "test", "puts ActiveRecord::InternalMetadata[:environment]").strip
+ assert_equal "development", rails("runner", "puts ActiveRecord::InternalMetadata[:environment]").strip
+ end
+
test "db:structure:dump does not dump schema information when no migrations are used" do
# create table without migrations
rails "runner", "ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }"
@@ -205,56 +238,52 @@ module ApplicationTests
end
test "db:schema:load and db:structure:load do not purge the existing database" do
- Dir.chdir(app_path) do
- rails "runner", "ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }"
+ rails "runner", "ActiveRecord::Base.connection.create_table(:posts) {|t| t.string :title }"
- app_file "db/schema.rb", <<-RUBY
- ActiveRecord::Schema.define(version: 20140423102712) do
- create_table(:comments) {}
- end
- RUBY
+ app_file "db/schema.rb", <<-RUBY
+ ActiveRecord::Schema.define(version: 20140423102712) do
+ create_table(:comments) {}
+ end
+ RUBY
- list_tables = lambda { rails("runner", "p ActiveRecord::Base.connection.tables").strip }
+ list_tables = lambda { rails("runner", "p ActiveRecord::Base.connection.tables").strip }
- assert_equal '["posts"]', list_tables[]
- rails "db:schema:load"
- assert_equal '["posts", "comments", "schema_migrations", "ar_internal_metadata"]', list_tables[]
+ assert_equal '["posts"]', list_tables[]
+ rails "db:schema:load"
+ assert_equal '["posts", "comments", "schema_migrations", "ar_internal_metadata"]', list_tables[]
- app_file "db/structure.sql", <<-SQL
- CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
- SQL
+ app_file "db/structure.sql", <<-SQL
+ CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255));
+ SQL
- rails "db:structure:load"
- assert_equal '["posts", "comments", "schema_migrations", "ar_internal_metadata", "users"]', list_tables[]
- end
+ rails "db:structure:load"
+ assert_equal '["posts", "comments", "schema_migrations", "ar_internal_metadata", "users"]', list_tables[]
end
test "db:schema:load with inflections" do
- Dir.chdir(app_path) do
- app_file "config/initializers/inflection.rb", <<-RUBY
- ActiveSupport::Inflector.inflections do |inflect|
- inflect.irregular 'goose', 'geese'
- end
- RUBY
- app_file "config/initializers/primary_key_table_name.rb", <<-RUBY
- ActiveRecord::Base.primary_key_prefix_type = :table_name
- RUBY
- app_file "db/schema.rb", <<-RUBY
- ActiveRecord::Schema.define(version: 20140423102712) do
- create_table("goose".pluralize) do |t|
- t.string :name
- end
+ app_file "config/initializers/inflection.rb", <<-RUBY
+ ActiveSupport::Inflector.inflections do |inflect|
+ inflect.irregular 'goose', 'geese'
+ end
+ RUBY
+ app_file "config/initializers/primary_key_table_name.rb", <<-RUBY
+ ActiveRecord::Base.primary_key_prefix_type = :table_name
+ RUBY
+ app_file "db/schema.rb", <<-RUBY
+ ActiveRecord::Schema.define(version: 20140423102712) do
+ create_table("goose".pluralize) do |t|
+ t.string :name
end
- RUBY
+ end
+ RUBY
- rails "db:schema:load"
+ rails "db:schema:load"
- tables = rails("runner", "p ActiveRecord::Base.connection.tables").strip
- assert_match(/"geese"/, tables)
+ tables = rails("runner", "p ActiveRecord::Base.connection.tables").strip
+ assert_match(/"geese"/, tables)
- columns = rails("runner", "p ActiveRecord::Base.connection.columns('geese').map(&:name)").strip
- assert_equal columns, '["gooseid", "name"]'
- end
+ columns = rails("runner", "p ActiveRecord::Base.connection.columns('geese').map(&:name)").strip
+ assert_equal columns, '["gooseid", "name"]'
end
test "db:schema:load fails if schema.rb doesn't exist yet" do
@@ -269,7 +298,7 @@ module ApplicationTests
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
ActiveRecord::Base.establish_connection :test
require "#{app_path}/app/models/book"
- #if structure is not loaded correctly, exception would be raised
+ # if structure is not loaded correctly, exception would be raised
assert_equal 0, Book.count
assert_match ActiveRecord::Base.configurations["test"]["database"],
ActiveRecord::Base.connection_config[:database]
@@ -300,15 +329,52 @@ module ApplicationTests
puts ActiveRecord::Base.connection_config[:database]
RUBY
- Dir.chdir(app_path) do
- database_path = rails("db:setup")
- assert_equal "development.sqlite3", File.basename(database_path.strip)
- end
+ database_path = rails("db:setup")
+ assert_equal "development.sqlite3", File.basename(database_path.strip)
ensure
ENV["RAILS_ENV"] = @old_rails_env
ENV["RACK_ENV"] = @old_rack_env
end
end
+
+ test "db:setup sets ar_internal_metadata" do
+ app_file "db/schema.rb", ""
+ rails "db:setup"
+
+ test_environment = lambda { rails("runner", "-e", "test", "puts ActiveRecord::InternalMetadata[:environment]").strip }
+ development_environment = lambda { rails("runner", "puts ActiveRecord::InternalMetadata[:environment]").strip }
+
+ assert_equal "test", test_environment.call
+ assert_equal "development", development_environment.call
+
+ app_file "db/structure.sql", ""
+ app_file "config/initializers/enable_sql_schema_format.rb", <<-RUBY
+ Rails.application.config.active_record.schema_format = :sql
+ RUBY
+
+ rails "db:setup"
+
+ assert_equal "test", test_environment.call
+ assert_equal "development", development_environment.call
+ end
+
+ test "db:test:prepare sets test ar_internal_metadata" do
+ app_file "db/schema.rb", ""
+ rails "db:test:prepare"
+
+ test_environment = lambda { rails("runner", "-e", "test", "puts ActiveRecord::InternalMetadata[:environment]").strip }
+
+ assert_equal "test", test_environment.call
+
+ app_file "db/structure.sql", ""
+ app_file "config/initializers/enable_sql_schema_format.rb", <<-RUBY
+ Rails.application.config.active_record.schema_format = :sql
+ RUBY
+
+ rails "db:test:prepare"
+
+ assert_equal "test", test_environment.call
+ end
end
end
end
diff --git a/railties/test/application/rake/migrations_test.rb b/railties/test/application/rake/migrations_test.rb
index b0d51eb22e..bf5b07afbd 100644
--- a/railties/test/application/rake/migrations_test.rb
+++ b/railties/test/application/rake/migrations_test.rb
@@ -15,69 +15,166 @@ module ApplicationTests
end
test "running migrations with given scope" do
- Dir.chdir(app_path) do
- rails "generate", "model", "user", "username:string", "password:string"
+ rails "generate", "model", "user", "username:string", "password:string"
- app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION
- class AMigration < ActiveRecord::Migration::Current
- end
- MIGRATION
+ app_file "db/migrate/01_a_migration.bukkits.rb", <<-MIGRATION
+ class AMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
- output = rails("db:migrate", "SCOPE=bukkits")
- assert_no_match(/create_table\(:users\)/, output)
- assert_no_match(/CreateUsers/, output)
- assert_no_match(/add_column\(:users, :email, :string\)/, output)
+ output = rails("db:migrate", "SCOPE=bukkits")
+ assert_no_match(/create_table\(:users\)/, output)
+ assert_no_match(/CreateUsers/, output)
+ assert_no_match(/add_column\(:users, :email, :string\)/, output)
- assert_match(/AMigration: migrated/, output)
+ assert_match(/AMigration: 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)
+ # run all the migrations to test scope for down
+ output = rails("db:migrate")
+ assert_match(/CreateUsers: migrated/, output)
- assert_match(/AMigration: reverted/, output)
- end
+ 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
+ app_file "db/migrate/01_one_migration.rb", <<-MIGRATION
+ class OneMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ app_file "db/migrate/02_two_migration.rb", <<-MIGRATION
+ class TwoMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ app_file "db/migrate/03_three_migration.rb", <<-MIGRATION
+ class ThreeMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ rails "db:migrate"
+
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
+ assert_match(/up\s+003\s+Three migration/, output)
+
+ rails "db:migrate", "VERSION=01_one_migration.rb"
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/down\s+002\s+Two migration/, output)
+ assert_match(/down\s+003\s+Three migration/, output)
+
+ rails "db:migrate", "VERSION=3"
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
+ assert_match(/up\s+003\s+Three migration/, output)
+
+ rails "db:migrate", "VERSION=001"
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/down\s+002\s+Two migration/, output)
+ assert_match(/down\s+003\s+Three migration/, output)
end
test "migration with empty version" do
- Dir.chdir(app_path) do
- output = rails("db:migrate", "VERSION=", allow_failure: true)
- assert_match(/Empty VERSION provided/, output)
+ app_file "db/migrate/01_one_migration.rb", <<-MIGRATION
+ class OneMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
- output = rails("db:migrate:redo", "VERSION=", allow_failure: true)
- assert_match(/Empty VERSION provided/, output)
+ app_file "db/migrate/02_two_migration.rb", <<-MIGRATION
+ class TwoMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
- output = rails("db:migrate:up", "VERSION=", allow_failure: true)
- assert_match(/VERSION is required/, output)
+ rails("db:migrate", "VERSION=")
- output = rails("db:migrate:up", allow_failure: true)
- assert_match(/VERSION is required/, output)
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
- output = rails("db:migrate:down", "VERSION=", allow_failure: true)
- assert_match(/VERSION is required - To go down one migration, use db:rollback/, output)
+ output = rails("db:migrate:redo", "VERSION=", allow_failure: true)
+ assert_match(/Empty VERSION provided/, output)
- output = rails("db:migrate:down", allow_failure: true)
- assert_match(/VERSION is required - To go down one migration, use db:rollback/, output)
- end
+ output = rails("db:migrate:up", "VERSION=", allow_failure: true)
+ assert_match(/VERSION is required/, output)
+
+ output = rails("db:migrate:up", allow_failure: true)
+ assert_match(/VERSION is required/, output)
+
+ output = rails("db:migrate:down", "VERSION=", allow_failure: true)
+ assert_match(/VERSION is required - To go down one migration, use db:rollback/, output)
+
+ output = rails("db:migrate:down", allow_failure: true)
+ assert_match(/VERSION is required - To go down one migration, use db:rollback/, output)
+
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
end
- test "model and migration generator with change syntax" do
- Dir.chdir(app_path) do
- rails "generate", "model", "user", "username:string", "password:string"
- rails "generate", "migration", "add_email_to_users", "email:string"
+ test "migration with 0 version" do
+ app_file "db/migrate/01_one_migration.rb", <<-MIGRATION
+ class OneMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
- output = rails("db:migrate")
- assert_match(/create_table\(:users\)/, output)
- assert_match(/CreateUsers: migrated/, output)
- assert_match(/add_column\(:users, :email, :string\)/, output)
- assert_match(/AddEmailToUsers: migrated/, output)
-
- output = rails("db:rollback", "STEP=2")
- assert_match(/drop_table\(:users\)/, output)
- assert_match(/CreateUsers: reverted/, output)
- assert_match(/remove_column\(:users, :email, :string\)/, output)
- assert_match(/AddEmailToUsers: reverted/, output)
- end
+ app_file "db/migrate/02_two_migration.rb", <<-MIGRATION
+ class TwoMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ rails "db:migrate"
+
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
+
+ rails "db:migrate", "VERSION=0"
+
+ output = rails("db:migrate:status")
+ assert_match(/down\s+001\s+One migration/, output)
+ assert_match(/down\s+002\s+Two migration/, output)
+ end
+
+ test "model and migration generator with change syntax" do
+ rails "generate", "model", "user", "username:string", "password:string"
+ rails "generate", "migration", "add_email_to_users", "email:string"
+
+ output = rails("db:migrate")
+ assert_match(/create_table\(:users\)/, output)
+ assert_match(/CreateUsers: migrated/, output)
+ assert_match(/add_column\(:users, :email, :string\)/, output)
+ assert_match(/AddEmailToUsers: migrated/, output)
+
+ output = rails("db:rollback", "STEP=2")
+ assert_match(/drop_table\(:users\)/, output)
+ assert_match(/CreateUsers: reverted/, output)
+ assert_match(/remove_column\(:users, :email, :string\)/, output)
+ assert_match(/AddEmailToUsers: reverted/, output)
end
test "migration status when schema migrations table is not present" do
@@ -86,93 +183,85 @@ module ApplicationTests
end
test "migration status" do
- Dir.chdir(app_path) do
- rails "generate", "model", "user", "username:string", "password:string"
- rails "generate", "migration", "add_email_to_users", "email:string"
- rails "db:migrate"
+ rails "generate", "model", "user", "username:string", "password:string"
+ rails "generate", "migration", "add_email_to_users", "email:string"
+ rails "db:migrate"
- output = rails("db:migrate:status")
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
- rails "db:rollback", "STEP=1"
- output = rails("db:migrate:status")
+ rails "db:rollback", "STEP=1"
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/down\s+\d{14}\s+Add email to users/, output)
- end
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/down\s+\d{14}\s+Add email to users/, output)
end
test "migration status without timestamps" do
add_to_config("config.active_record.timestamped_migrations = false")
- Dir.chdir(app_path) do
- rails "generate", "model", "user", "username:string", "password:string"
- rails "generate", "migration", "add_email_to_users", "email:string"
- rails "db:migrate"
+ rails "generate", "model", "user", "username:string", "password:string"
+ rails "generate", "migration", "add_email_to_users", "email:string"
+ rails "db:migrate"
- output = rails("db:migrate:status")
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/up\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/up\s+\d{3,}\s+Add email to users/, output)
- rails "db:rollback", "STEP=1"
- output = rails("db:migrate:status")
+ rails "db:rollback", "STEP=1"
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/down\s+\d{3,}\s+Add email to users/, output)
- end
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/down\s+\d{3,}\s+Add email to users/, output)
end
test "migration status after rollback and redo" do
- Dir.chdir(app_path) do
- rails "generate", "model", "user", "username:string", "password:string"
- rails "generate", "migration", "add_email_to_users", "email:string"
- rails "db:migrate"
+ rails "generate", "model", "user", "username:string", "password:string"
+ rails "generate", "migration", "add_email_to_users", "email:string"
+ rails "db:migrate"
- output = rails("db:migrate:status")
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
- rails "db:rollback", "STEP=2"
- output = rails("db:migrate:status")
+ rails "db:rollback", "STEP=2"
+ output = rails("db:migrate:status")
- assert_match(/down\s+\d{14}\s+Create users/, output)
- assert_match(/down\s+\d{14}\s+Add email to users/, output)
+ assert_match(/down\s+\d{14}\s+Create users/, output)
+ assert_match(/down\s+\d{14}\s+Add email to users/, output)
- rails "db:migrate:redo"
- output = rails("db:migrate:status")
+ rails "db:migrate:redo"
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
- end
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
end
test "migration status after rollback and forward" do
- Dir.chdir(app_path) do
- rails "generate", "model", "user", "username:string", "password:string"
- rails "generate", "migration", "add_email_to_users", "email:string"
- rails "db:migrate"
+ rails "generate", "model", "user", "username:string", "password:string"
+ rails "generate", "migration", "add_email_to_users", "email:string"
+ rails "db:migrate"
- output = rails("db:migrate:status")
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
- rails "db:rollback", "STEP=2"
- output = rails("db:migrate:status")
+ rails "db:rollback", "STEP=2"
+ output = rails("db:migrate:status")
- assert_match(/down\s+\d{14}\s+Create users/, output)
- assert_match(/down\s+\d{14}\s+Add email to users/, output)
+ assert_match(/down\s+\d{14}\s+Create users/, output)
+ assert_match(/down\s+\d{14}\s+Add email to users/, output)
- rails "db:forward", "STEP=2"
- output = rails("db:migrate:status")
+ rails "db:forward", "STEP=2"
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{14}\s+Create users/, output)
- assert_match(/up\s+\d{14}\s+Add email to users/, output)
- end
+ assert_match(/up\s+\d{14}\s+Create users/, output)
+ assert_match(/up\s+\d{14}\s+Add email to users/, output)
end
test "raise error on any move when current migration does not exist" do
@@ -206,53 +295,117 @@ module ApplicationTests
end
end
+ test "raise error on any move when target migration does not exist" do
+ app_file "db/migrate/01_one_migration.rb", <<-MIGRATION
+ class OneMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ app_file "db/migrate/02_two_migration.rb", <<-MIGRATION
+ class TwoMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
+
+ rails "db:migrate"
+
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
+
+ output = rails("db:migrate", "VERSION=3", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/ActiveRecord::UnknownMigrationVersionError:/, output)
+ assert_match(/No migration with version number 3/, output)
+
+ output = rails("db:migrate:status")
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
+ end
+
+ test "raise error on any move when VERSION has invalid format" do
+ output = rails("db:migrate", "VERSION=unknown", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate", "VERSION=0.1.11", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate", "VERSION=1.1.11", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate", "VERSION='0 '", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate", "VERSION=1.", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate", "VERSION=1_", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate", "VERSION=1_name", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate:redo", "VERSION=unknown", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate:up", "VERSION=unknown", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+
+ output = rails("db:migrate:down", "VERSION=unknown", allow_failure: true)
+ assert_match(/rails aborted!/, output)
+ assert_match(/Invalid format of target version/, output)
+ end
+
test "migration status after rollback and redo without timestamps" do
add_to_config("config.active_record.timestamped_migrations = false")
- Dir.chdir(app_path) do
- rails "generate", "model", "user", "username:string", "password:string"
- rails "generate", "migration", "add_email_to_users", "email:string"
- rails "db:migrate"
+ rails "generate", "model", "user", "username:string", "password:string"
+ rails "generate", "migration", "add_email_to_users", "email:string"
+ rails "db:migrate"
- output = rails("db:migrate:status")
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/up\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/up\s+\d{3,}\s+Add email to users/, output)
- rails "db:rollback", "STEP=2"
- output = rails("db:migrate:status")
+ rails "db:rollback", "STEP=2"
+ output = rails("db:migrate:status")
- assert_match(/down\s+\d{3,}\s+Create users/, output)
- assert_match(/down\s+\d{3,}\s+Add email to users/, output)
+ assert_match(/down\s+\d{3,}\s+Create users/, output)
+ assert_match(/down\s+\d{3,}\s+Add email to users/, output)
- rails "db:migrate:redo"
- output = rails("db:migrate:status")
+ rails "db:migrate:redo"
+ output = rails("db:migrate:status")
- assert_match(/up\s+\d{3,}\s+Create users/, output)
- assert_match(/up\s+\d{3,}\s+Add email to users/, output)
- end
+ assert_match(/up\s+\d{3,}\s+Create users/, output)
+ assert_match(/up\s+\d{3,}\s+Add email to users/, output)
end
test "running migrations with not timestamp head migration files" do
- Dir.chdir(app_path) do
-
- app_file "db/migrate/1_one_migration.rb", <<-MIGRATION
- class OneMigration < ActiveRecord::Migration::Current
- end
- MIGRATION
+ app_file "db/migrate/1_one_migration.rb", <<-MIGRATION
+ class OneMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
- app_file "db/migrate/02_two_migration.rb", <<-MIGRATION
- class TwoMigration < ActiveRecord::Migration::Current
- end
- MIGRATION
+ app_file "db/migrate/02_two_migration.rb", <<-MIGRATION
+ class TwoMigration < ActiveRecord::Migration::Current
+ end
+ MIGRATION
- rails "db:migrate"
+ rails "db:migrate"
- output = rails("db:migrate:status")
+ output = rails("db:migrate:status")
- assert_match(/up\s+001\s+One migration/, output)
- assert_match(/up\s+002\s+Two migration/, output)
- end
+ assert_match(/up\s+001\s+One migration/, output)
+ assert_match(/up\s+002\s+Two migration/, output)
end
test "schema generation when dump_schema_after_migration is set" do
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..d73e5cdfa3 100644
--- a/railties/test/application/rake/notes_test.rb
+++ b/railties/test/application/rake/notes_test.rb
@@ -101,7 +101,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
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 76bc0ce1d7..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
@@ -40,9 +39,9 @@ module ApplicationTests
with_rails_env "test" do
rails "generate", "model", "product", "name:string"
rails "db:create", "db:migrate"
- output = Dir.chdir(app_path) { rails("db:test:prepare", "test") }
+ output = rails("db:test:prepare", "test")
- refute_match(/ActiveRecord::ProtectedEnvironmentError/, output)
+ assert_no_match(/ActiveRecord::ProtectedEnvironmentError/, output)
end
end
@@ -101,6 +100,7 @@ module ApplicationTests
add_to_config <<-RUBY
rake_tasks do
task do_nothing: :environment do
+ puts 'There is nothing'
end
end
RUBY
@@ -113,10 +113,8 @@ module ApplicationTests
raise 'should not be pre-required for rake even eager_load=true'
RUBY
- Dir.chdir(app_path) do
- assert system("bin/rails do_nothing RAILS_ENV=production"),
- "should not be pre-required for rake even eager_load=true"
- end
+ output = rails("do_nothing", "RAILS_ENV=production")
+ assert_match "There is nothing", output
end
def test_code_statistics_sanity
@@ -124,138 +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
- 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", allow_failure: true)
- assert_equal <<-MESSAGE.strip_heredoc, output
- Prefix Verb URI Pattern Controller#Action
- cart GET /cart(.:format) cart#show
- MESSAGE
-
- output = rails("routes", "-g", "POST")
- assert_equal <<-MESSAGE.strip_heredoc, output
- Prefix Verb URI Pattern Controller#Action
- POST /cart(.:format) cart#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")
- You don't have any routes defined!
-
- Please add some routes in config/routes.rb.
-
- For more information about routes, see the Rails guide: http://guides.rubyonrails.org/routing.html.
- 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
- MESSAGE
- end
-
def test_logger_is_flushed_when_exiting_production_rake_tasks
add_to_config <<-RUBY
rake_tasks do
@@ -294,9 +160,8 @@ module ApplicationTests
def test_scaffold_tests_pass_by_default
rails "generate", "scaffold", "user", "username:string", "password:string"
- output = Dir.chdir(app_path) do
- `RAILS_ENV=test bin/rails db:migrate test`
- end
+ with_rails_env("test") { rails("db:migrate") }
+ output = rails("test")
assert_match(/7 runs, 9 assertions, 0 failures, 0 errors/, output)
assert_no_match(/Errors running/, output)
@@ -313,9 +178,8 @@ module ApplicationTests
RUBY
rails "generate", "scaffold", "user", "username:string", "password:string"
- output = Dir.chdir(app_path) do
- `RAILS_ENV=test bin/rails db:migrate test`
- end
+ with_rails_env("test") { rails("db:migrate") }
+ output = rails("test")
assert_match(/5 runs, 7 assertions, 0 failures, 0 errors/, output)
assert_no_match(/Errors running/, output)
@@ -325,9 +189,8 @@ module ApplicationTests
rails "generate", "model", "Product"
rails "generate", "model", "Cart"
rails "generate", "scaffold", "LineItems", "product:references", "cart:belongs_to"
- output = Dir.chdir(app_path) do
- `RAILS_ENV=test bin/rails db:migrate test`
- end
+ with_rails_env("test") { rails("db:migrate") }
+ output = rails("test")
assert_match(/7 runs, 9 assertions, 0 failures, 0 errors/, output)
assert_no_match(/Errors running/, output)
@@ -337,9 +200,7 @@ module ApplicationTests
add_to_config "config.active_record.schema_format = :sql"
rails "generate", "scaffold", "user", "username:string"
rails "db:migrate"
- output = with_rails_env("test") do
- rails "db:test:prepare", "--trace"
- end
+ output = rails("db:test:prepare", "--trace")
assert_match(/Execute db:test:load_structure/, output)
end
@@ -368,18 +229,16 @@ 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
- Dir.chdir(app_path) do
- rails "app:templates:copy"
- %w(controller mailer scaffold).each do |dir|
- assert File.exist?(File.join(app_path, "lib", "templates", "erb", dir))
- end
- %w(controller helper scaffold_controller assets).each do |dir|
- assert File.exist?(File.join(app_path, "lib", "templates", "rails", dir))
- end
+ rails "app:templates:copy"
+ %w(controller mailer scaffold).each do |dir|
+ assert File.exist?(File.join(app_path, "lib", "templates", "erb", dir))
+ end
+ %w(controller helper scaffold_controller assets).each do |dir|
+ assert File.exist?(File.join(app_path, "lib", "templates", "rails", dir))
end
end
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 64c46c4b45..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
@@ -128,5 +128,17 @@ module ApplicationTests
assert_match "production", rails("runner", "puts Rails.env")
end
end
+
+ def test_can_call_same_name_class_as_defined_in_thor
+ app_file "app/models/task.rb", <<-MODEL
+ class Task
+ def self.count
+ 42
+ end
+ end
+ MODEL
+
+ assert_match "42", rails("runner", "puts Task.count")
+ end
end
end
diff --git a/railties/test/application/server_test.rb b/railties/test/application/server_test.rb
index 6db9a3b9e8..f3a7e00a4d 100644
--- a/railties/test/application/server_test.rb
+++ b/railties/test/application/server_test.rb
@@ -29,12 +29,17 @@ 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 "require 'bundler/setup'"
+ end
+
master, slave = PTY.open
pid = nil
@@ -42,7 +47,7 @@ module ApplicationTests
pid = Process.spawn("#{app_path}/bin/rails server -P tmp/dummy.pid", in: slave, out: slave, err: slave)
assert_output("Listening", master)
- Dir.chdir(app_path) { system("bin/rails restart") }
+ rails("restart")
assert_output("Restarting", master)
assert_output("Inherited", master)
diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb
index e92a0466dd..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)
@@ -569,6 +590,40 @@ module ApplicationTests
assert_match "AccountTest#test_truth", output, "passing TEST= should run selected test"
end
+ def test_running_with_ruby_gets_test_env_by_default
+ # Subshells inherit `ENV`, so we need to ensure `RAILS_ENV` is set to
+ # nil before we run the tests in the test app.
+ re, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], nil
+
+ file = create_test_for_env("test")
+ results = Dir.chdir(app_path) {
+ `ruby -Ilib:test #{file}`.each_line.map { |line| JSON.parse line }
+ }
+ assert_equal 1, results.length
+ failures = results.first["failures"]
+ flunk(failures.first) unless failures.empty?
+
+ ensure
+ ENV["RAILS_ENV"] = re
+ end
+
+ def test_running_with_ruby_can_set_env_via_cmdline
+ # Subshells inherit `ENV`, so we need to ensure `RAILS_ENV` is set to
+ # nil before we run the tests in the test app.
+ re, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], nil
+
+ file = create_test_for_env("development")
+ results = Dir.chdir(app_path) {
+ `RAILS_ENV=development ruby -Ilib:test #{file}`.each_line.map { |line| JSON.parse line }
+ }
+ assert_equal 1, results.length
+ failures = results.first["failures"]
+ flunk(failures.first) unless failures.empty?
+
+ ensure
+ ENV["RAILS_ENV"] = re
+ end
+
def test_rake_passes_multiple_TESTOPTS_to_minitest
create_test_file :models, "account"
output = Dir.chdir(app_path) { `bin/rake test TESTOPTS='-v --seed=1234'` }
@@ -684,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
@@ -727,19 +782,109 @@ module ApplicationTests
app_file "db/schema.rb", ""
end
- def create_test_file(path = :unit, name = "test", pass: true)
+ def create_test_for_env(env)
+ app_file "test/models/environment_test.rb", <<-RUBY
+ require 'test_helper'
+ class JSONReporter < Minitest::AbstractReporter
+ def record(result)
+ puts JSON.dump(klass: result.class.name,
+ name: result.name,
+ failures: result.failures,
+ assertions: result.assertions,
+ time: result.time)
+ end
+ end
+
+ def Minitest.plugin_json_reporter_init(opts)
+ Minitest.reporter.reporters.clear
+ Minitest.reporter.reporters << JSONReporter.new
+ end
+
+ Minitest.extensions << "rails"
+ Minitest.extensions << "json_reporter"
+
+ # Minitest uses RubyGems to find plugins, and since RubyGems
+ # doesn't know about the Rails installation we're pointing at,
+ # Minitest won't require the Rails minitest plugin when we run
+ # these integration tests. So we have to manually require the
+ # Minitest plugin here.
+ require 'minitest/rails_plugin'
+
+ class EnvironmentTest < ActiveSupport::TestCase
+ def test_environment
+ test_db = ActiveRecord::Base.configurations[#{env.dump}]["database"]
+ db_file = ActiveRecord::Base.connection_config[:database]
+ assert_match(test_db, db_file)
+ assert_equal #{env.dump}, ENV["RAILS_ENV"]
+ end
+ end
+ RUBY
+ end
+
+ 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/command/spellchecker_test.rb b/railties/test/command/spellchecker_test.rb
new file mode 100644
index 0000000000..e6a7a3957c
--- /dev/null
+++ b/railties/test/command/spellchecker_test.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "rails/command/spellchecker"
+
+class Rails::Command::SpellcheckerTest < ActiveSupport::TestCase
+ test "suggests a word correction from dictionary" do
+ assert_equal "thin", Rails::Command::Spellchecker.suggest("tin", from: %w(puma thin cgi))
+ end
+end
diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb
index 7eb26c355c..b7cdb8229e 100644
--- a/railties/test/commands/console_test.rb
+++ b/railties/test/commands/console_test.rb
@@ -20,30 +20,30 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
def test_sandbox_option
console = Rails::Console.new(app, parse_arguments(["--sandbox"]))
- assert console.sandbox?
+ assert_predicate console, :sandbox?
end
def test_short_version_of_sandbox_option
console = Rails::Console.new(app, parse_arguments(["-s"]))
- assert console.sandbox?
+ assert_predicate console, :sandbox?
end
def test_no_options
console = Rails::Console.new(app, parse_arguments([]))
- assert !console.sandbox?
+ assert_not_predicate console, :sandbox?
end
def test_start
start
- assert app.console.started?
+ assert_predicate app.console, :started?
assert_match(/Loading \w+ environment \(Rails/, output)
end
def test_start_with_sandbox
start ["--sandbox"]
- assert app.console.started?
+ assert_predicate app.console, :started?
assert app.sandbox
assert_match(/Loading \w+ environment in sandbox \(Rails/, output)
end
@@ -172,21 +172,8 @@ class Rails::ConsoleTest < ActiveSupport::TestCase
end
def parse_arguments(args)
- Rails::Command::ConsoleCommand.class_eval do
- alias_method :old_perform, :perform
- define_method(:perform) do
- extract_environment_option_from_argument
-
- options
- end
- end
-
- Rails::Command.invoke(:console, args)
- ensure
- Rails::Command::ConsoleCommand.class_eval do
- undef_method :perform
- alias_method :perform, :old_perform
- undef_method :old_perform
- end
+ command = Rails::Command::ConsoleCommand.new([], args)
+ command.send(:extract_environment_option_from_argument)
+ command.options
end
end
diff --git a/railties/test/commands/credentials_test.rb b/railties/test/commands/credentials_test.rb
index 743fb5f788..663ee73bcd 100644
--- a/railties/test/commands/credentials_test.rb
+++ b/railties/test/commands/credentials_test.rb
@@ -13,7 +13,10 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
teardown { teardown_app }
test "edit without editor gives hint" do
- assert_match "No $EDITOR to open credentials in", run_edit_command(editor: "")
+ run_edit_command(editor: "").tap do |output|
+ assert_match "No $EDITOR to open file in", output
+ assert_match "bin/rails credentials:edit", output
+ end
end
test "edit credentials" do
@@ -23,10 +26,6 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
end
end
- test "show credentials" do
- assert_match(/access_key_id: 123/, run_show_command)
- end
-
test "edit command does not add master key to gitignore when already exist" do
run_edit_command
@@ -36,6 +35,44 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
end
end
+ test "edit command does not overwrite by default if credentials already exists" do
+ run_edit_command(editor: "eval echo api_key: abc >")
+ assert_match(/api_key: abc/, run_show_command)
+
+ run_edit_command
+ assert_match(/api_key: abc/, run_show_command)
+ end
+
+ test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do
+ Dir.chdir(app_path) do
+ key = IO.binread("config/master.key").strip
+ FileUtils.rm("config/master.key")
+
+ switch_env("RAILS_MASTER_KEY", key) do
+ run_edit_command
+ assert_not File.exist?("config/master.key")
+ end
+ end
+ end
+
+ test "show credentials" do
+ assert_match(/access_key_id: 123/, run_show_command)
+ end
+
+ test "show command raise error when require_master_key is specified and key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = true"
+
+ assert_match(/Missing encryption key to decrypt file with/, run_show_command(allow_failure: true))
+ end
+
+ test "show command does not raise error when require_master_key is false and master key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = false"
+
+ assert_match(/Missing master key to decrypt credentials/, run_show_command)
+ end
+
private
def run_edit_command(editor: "cat")
switch_env("EDITOR", editor) do
@@ -43,7 +80,7 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
end
end
- def run_show_command
- rails "credentials:show"
+ def run_show_command(**options)
+ rails "credentials:show", **options
end
end
diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb
index 6ad96b28c7..0aea21051a 100644
--- a/railties/test/commands/dbconsole_test.rb
+++ b/railties/test/commands/dbconsole_test.rb
@@ -123,31 +123,31 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
def test_mysql
start(adapter: "mysql2", database: "db")
- assert !aborted
+ assert_not aborted
assert_equal [%w[mysql mysql5], "db"], dbconsole.find_cmd_and_exec_args
end
def test_mysql_full
start(adapter: "mysql2", database: "db", host: "locahost", port: 1234, socket: "socket", username: "user", password: "qwerty", encoding: "UTF-8")
- assert !aborted
+ assert_not aborted
assert_equal [%w[mysql mysql5], "--host=locahost", "--port=1234", "--socket=socket", "--user=user", "--default-character-set=UTF-8", "-p", "db"], dbconsole.find_cmd_and_exec_args
end
def test_mysql_include_password
start({ adapter: "mysql2", database: "db", username: "user", password: "qwerty" }, ["-p"])
- assert !aborted
+ assert_not aborted
assert_equal [%w[mysql mysql5], "--user=user", "--password=qwerty", "db"], dbconsole.find_cmd_and_exec_args
end
def test_postgresql
start(adapter: "postgresql", database: "db")
- assert !aborted
+ assert_not aborted
assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args
end
def test_postgresql_full
start(adapter: "postgresql", database: "db", username: "user", password: "q1w2e3", host: "host", port: 5432)
- assert !aborted
+ assert_not aborted
assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args
assert_equal "user", ENV["PGUSER"]
assert_equal "host", ENV["PGHOST"]
@@ -157,7 +157,7 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
def test_postgresql_include_password
start({ adapter: "postgresql", database: "db", username: "user", password: "q1w2e3" }, ["-p"])
- assert !aborted
+ assert_not aborted
assert_equal ["psql", "db"], dbconsole.find_cmd_and_exec_args
assert_equal "user", ENV["PGUSER"]
assert_equal "q1w2e3", ENV["PGPASSWORD"]
@@ -165,13 +165,13 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
def test_sqlite3
start(adapter: "sqlite3", database: "db.sqlite3")
- assert !aborted
+ assert_not aborted
assert_equal ["sqlite3", Rails.root.join("db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args
end
def test_sqlite3_mode
start({ adapter: "sqlite3", database: "db.sqlite3" }, ["--mode", "html"])
- assert !aborted
+ assert_not aborted
assert_equal ["sqlite3", "-html", Rails.root.join("db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args
end
@@ -182,27 +182,27 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase
def test_sqlite3_db_absolute_path
start(adapter: "sqlite3", database: "/tmp/db.sqlite3")
- assert !aborted
+ assert_not aborted
assert_equal ["sqlite3", "/tmp/db.sqlite3"], dbconsole.find_cmd_and_exec_args
end
def test_sqlite3_db_without_defined_rails_root
Rails.stub(:respond_to?, false) do
start(adapter: "sqlite3", database: "config/db.sqlite3")
- assert !aborted
+ assert_not aborted
assert_equal ["sqlite3", Rails.root.join("../config/db.sqlite3").to_s], dbconsole.find_cmd_and_exec_args
end
end
def test_oracle
start(adapter: "oracle", database: "db", username: "user", password: "secret")
- assert !aborted
+ assert_not aborted
assert_equal ["sqlplus", "user@db"], dbconsole.find_cmd_and_exec_args
end
def test_oracle_include_password
start({ adapter: "oracle", database: "db", username: "user", password: "secret" }, ["-p"])
- assert !aborted
+ assert_not aborted
assert_equal ["sqlplus", "user/secret@db"], dbconsole.find_cmd_and_exec_args
end
diff --git a/railties/test/commands/encrypted_test.rb b/railties/test/commands/encrypted_test.rb
new file mode 100644
index 0000000000..9fc73d5f18
--- /dev/null
+++ b/railties/test/commands/encrypted_test.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+require "isolation/abstract_unit"
+require "env_helpers"
+require "rails/command"
+require "rails/commands/encrypted/encrypted_command"
+
+class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation, EnvHelpers
+
+ setup :build_app
+ teardown :teardown_app
+
+ test "edit without editor gives hint" do
+ run_edit_command("config/tokens.yml.enc", editor: "").tap do |output|
+ assert_match "No $EDITOR to open file in", output
+ assert_match "bin/rails encrypted:edit", output
+ end
+ end
+
+ test "edit encrypted file" do
+ # Run twice to ensure file can be reread after first edit pass.
+ 2.times do
+ assert_match(/access_key_id: 123/, run_edit_command("config/tokens.yml.enc"))
+ end
+ end
+
+ test "edit command does not add master key to gitignore when already exist" do
+ run_edit_command("config/tokens.yml.enc")
+
+ Dir.chdir(app_path) do
+ assert_match "/config/master.key", File.read(".gitignore")
+ end
+ end
+
+ test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do
+ Dir.chdir(app_path) do
+ key = IO.binread("config/master.key").strip
+ FileUtils.rm("config/master.key")
+
+ switch_env("RAILS_MASTER_KEY", key) do
+ run_edit_command("config/tokens.yml.enc")
+ assert_not File.exist?("config/master.key")
+ end
+ end
+ end
+
+ test "edit encrypts file with custom key" do
+ run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")
+
+ Dir.chdir(app_path) do
+ assert File.exist?("config/tokens.yml.enc")
+ assert File.exist?("config/tokens.key")
+
+ assert_match "/config/tokens.key", File.read(".gitignore")
+ end
+
+ assert_match(/access_key_id: 123/, run_edit_command("config/tokens.yml.enc", key: "config/tokens.key"))
+ end
+
+ test "show encrypted file with custom key" do
+ run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")
+
+ assert_match(/access_key_id: 123/, run_show_command("config/tokens.yml.enc", key: "config/tokens.key"))
+ end
+
+ test "show command raise error when require_master_key is specified and key does not exist" do
+ add_to_config "config.require_master_key = true"
+
+ assert_match(/Missing encryption key to decrypt file with/,
+ run_show_command("config/tokens.yml.enc", key: "unexist.key", allow_failure: true))
+ end
+
+ test "show command does not raise error when require_master_key is false and master key does not exist" do
+ remove_file "config/master.key"
+ add_to_config "config.require_master_key = false"
+
+ assert_match(/Missing 'config\/master\.key' to decrypt data/, run_show_command("config/tokens.yml.enc"))
+ end
+
+ test "won't corrupt encrypted file when passed wrong key" do
+ run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")
+
+ assert_match "passed the wrong key",
+ run_edit_command("config/tokens.yml.enc", allow_failure: true)
+
+ assert_match(/access_key_id: 123/, run_show_command("config/tokens.yml.enc", key: "config/tokens.key"))
+ end
+
+ private
+ def run_edit_command(file, key: nil, editor: "cat", **options)
+ switch_env("EDITOR", editor) do
+ rails "encrypted:edit", prepare_args(file, key), **options
+ end
+ end
+
+ def run_show_command(file, key: nil, **options)
+ rails "encrypted:show", prepare_args(file, key), **options
+ end
+
+ def prepare_args(file, key)
+ args = [ file ]
+ args.push("--key", key) if key
+ args
+ end
+end
diff --git a/railties/test/commands/routes_test.rb b/railties/test/commands/routes_test.rb
new file mode 100644
index 0000000000..77ed2bda61
--- /dev/null
+++ b/railties/test/commands/routes_test.rb
@@ -0,0 +1,175 @@
+# frozen_string_literal: true
+
+require "isolation/abstract_unit"
+require "rails/command"
+require "rails/commands/routes/routes_command"
+require "io/console/size"
+
+class Rails::Command::RoutesTest < ActiveSupport::TestCase
+ setup :build_app
+ teardown :teardown_app
+
+ test "singular resource output in rails routes" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ resource :post
+ end
+ RUBY
+
+ expected_output = [" Prefix Verb URI Pattern Controller#Action",
+ " new_post GET /post/new(.:format) posts#new",
+ "edit_post GET /post/edit(.:format) posts#edit",
+ " post GET /post(.:format) posts#show",
+ " PATCH /post(.:format) posts#update",
+ " PUT /post(.:format) posts#update",
+ " DELETE /post(.:format) posts#destroy",
+ " POST /post(.:format) posts#create\n"].join("\n")
+
+ output = run_routes_command(["-c", "PostController"])
+ assert_equal expected_output, output
+ end
+
+ test "rails routes with global search key" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get '/cart', to: 'cart#show'
+ post '/cart', to: 'cart#create'
+ get '/basketballs', to: 'basketball#index'
+ end
+ RUBY
+
+ output = run_routes_command(["-g", "show"])
+ assert_equal <<~MESSAGE, output
+ Prefix Verb URI Pattern Controller#Action
+ cart GET /cart(.:format) cart#show
+ rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
+ rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
+ rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
+ MESSAGE
+
+ output = run_routes_command(["-g", "POST"])
+ assert_equal <<~MESSAGE, output
+ Prefix Verb URI Pattern Controller#Action
+ POST /cart(.:format) cart#create
+ rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
+ MESSAGE
+
+ output = run_routes_command(["-g", "basketballs"])
+ assert_equal " Prefix Verb URI Pattern Controller#Action\n" \
+ "basketballs GET /basketballs(.:format) basketball#index\n", output
+ end
+
+ test "rails routes with controller search key" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get '/cart', to: 'cart#show'
+ get '/basketball', to: 'basketball#index'
+ end
+ RUBY
+
+ output = run_routes_command(["-c", "cart"])
+ assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
+
+ output = run_routes_command(["-c", "Cart"])
+ assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
+
+ output = run_routes_command(["-c", "CartController"])
+ assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output
+ end
+
+ test "rails routes with namespaced controller search key" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ namespace :admin do
+ resource :post
+ end
+ end
+ RUBY
+
+ expected_output = [" Prefix Verb URI Pattern Controller#Action",
+ " new_admin_post GET /admin/post/new(.:format) admin/posts#new",
+ "edit_admin_post GET /admin/post/edit(.:format) admin/posts#edit",
+ " admin_post GET /admin/post(.:format) admin/posts#show",
+ " PATCH /admin/post(.:format) admin/posts#update",
+ " PUT /admin/post(.:format) admin/posts#update",
+ " DELETE /admin/post(.:format) admin/posts#destroy",
+ " POST /admin/post(.:format) admin/posts#create\n"].join("\n")
+
+ output = run_routes_command(["-c", "Admin::PostController"])
+ assert_equal expected_output, output
+
+ output = run_routes_command(["-c", "PostController"])
+ assert_equal expected_output, output
+ end
+
+ test "rails routes displays message when no routes are defined" do
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ end
+ RUBY
+
+ assert_equal <<~MESSAGE, run_routes_command
+ Prefix Verb URI Pattern Controller#Action
+ rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
+ rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
+ rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
+ update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
+ rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
+ MESSAGE
+ end
+
+ test "rails routes with expanded option" do
+ begin
+ previous_console_winsize = IO.console.winsize
+ IO.console.winsize = [0, 27]
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get '/cart', to: 'cart#show'
+ end
+ RUBY
+
+ output = run_routes_command(["--expanded"])
+
+ assert_equal <<~MESSAGE, output
+ --[ Route 1 ]--------------
+ Prefix | cart
+ Verb | GET
+ URI | /cart(.:format)
+ Controller#Action | cart#show
+ --[ Route 2 ]--------------
+ Prefix | rails_service_blob
+ Verb | GET
+ URI | /rails/active_storage/blobs/:signed_id/*filename(.:format)
+ Controller#Action | active_storage/blobs#show
+ --[ Route 3 ]--------------
+ Prefix | rails_blob_representation
+ Verb | GET
+ URI | /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format)
+ Controller#Action | active_storage/representations#show
+ --[ Route 4 ]--------------
+ Prefix | rails_disk_service
+ Verb | GET
+ URI | /rails/active_storage/disk/:encoded_key/*filename(.:format)
+ Controller#Action | active_storage/disk#show
+ --[ Route 5 ]--------------
+ Prefix | update_rails_disk_service
+ Verb | PUT
+ URI | /rails/active_storage/disk/:encoded_token(.:format)
+ Controller#Action | active_storage/disk#update
+ --[ Route 6 ]--------------
+ Prefix | rails_direct_uploads
+ Verb | POST
+ URI | /rails/active_storage/direct_uploads(.:format)
+ Controller#Action | active_storage/direct_uploads#create
+ MESSAGE
+ ensure
+ IO.console.winsize = previous_console_winsize
+ end
+ end
+
+ private
+ def run_routes_command(args = [])
+ rails "routes", args
+ end
+end
diff --git a/railties/test/commands/secrets_test.rb b/railties/test/commands/secrets_test.rb
index 66a81826e3..6b9f284a0c 100644
--- a/railties/test/commands/secrets_test.rb
+++ b/railties/test/commands/secrets_test.rb
@@ -8,21 +8,38 @@ require "rails/commands/secrets/secrets_command"
class Rails::Command::SecretsCommandTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation, EnvHelpers
- def setup
- build_app
+ setup :build_app
+ teardown :teardown_app
+
+ test "edit without editor gives hint" do
+ assert_match "No $EDITOR to open decrypted secrets in", run_edit_command(editor: "")
end
- def teardown
- teardown_app
+ test "encrypted secrets are deprecated when using credentials" do
+ assert_match "Encrypted secrets is deprecated", run_setup_command
+ assert_equal 1, $?.exitstatus
+ assert_not File.exist?("config/secrets.yml.enc")
end
- test "edit without editor gives hint" do
- assert_match "No $EDITOR to open decrypted secrets in", run_edit_command(editor: "")
+ test "encrypted secrets are deprecated when running edit without setup" do
+ assert_match "Encrypted secrets is deprecated", run_setup_command
+ assert_equal 1, $?.exitstatus
+ assert_not File.exist?("config/secrets.yml.enc")
+ end
+
+ test "encrypted secrets are deprecated for 5.1 config/secrets.yml apps" do
+ Dir.chdir(app_path) do
+ FileUtils.rm("config/credentials.yml.enc")
+ FileUtils.touch("config/secrets.yml")
+
+ assert_match "Encrypted secrets is deprecated", run_setup_command
+ assert_equal 1, $?.exitstatus
+ assert_not File.exist?("config/secrets.yml.enc")
+ end
end
test "edit secrets" do
- # Runs setup before first edit.
- assert_match(/Adding config\/secrets\.yml\.key to store the encryption key/, run_edit_command)
+ prevent_deprecation
# Run twice to ensure encrypted secrets can be reread after first edit pass.
2.times do
@@ -31,22 +48,30 @@ class Rails::Command::SecretsCommandTest < ActiveSupport::TestCase
end
test "show secrets" do
- run_setup_command
+ prevent_deprecation
+
assert_match(/external_api_key: 1466aac22e6a869134be3d09b9e89232fc2c2289/, run_show_command)
end
private
+ def prevent_deprecation
+ Dir.chdir(app_path) do
+ File.write("config/secrets.yml.key", "f731758c639da2604dfb6bf3d1025de8")
+ File.write("config/secrets.yml.enc", "sEB0mHxDbeP1/KdnMk00wyzPFACl9K6t0cZWn5/Mfx/YbTHvnI07vrneqHg9kaH3wOS7L6pIQteu1P077OtE4BSx/ZRc/sgQPHyWu/tXsrfHqnPNpayOF/XZqizE91JacSFItNMWpuPsp9ynbzz+7cGhoB1S4aPNIU6u0doMrzdngDbijsaAFJmsHIQh6t/QHoJx--8aMoE0PvUWmw1Iqz--ldFqnM/K0g9k17M8PKoN/Q==")
+ end
+ end
+
def run_edit_command(editor: "cat")
switch_env("EDITOR", editor) do
- rails "secrets:edit"
+ rails "secrets:edit", allow_failure: true
end
end
def run_show_command
- rails "secrets:show"
+ rails "secrets:show", allow_failure: true
end
def run_setup_command
- rails "secrets:setup"
+ rails "secrets:setup", allow_failure: true
end
end
diff --git a/railties/test/commands/server_test.rb b/railties/test/commands/server_test.rb
index 556c2289e7..e7a56b3e6d 100644
--- a/railties/test/commands/server_test.rb
+++ b/railties/test/commands/server_test.rb
@@ -1,15 +1,15 @@
# frozen_string_literal: true
-require "abstract_unit"
+require "isolation/abstract_unit"
require "env_helpers"
require "rails/command"
require "rails/commands/server/server_command"
-class Rails::ServerTest < ActiveSupport::TestCase
+class Rails::Command::ServerCommandTest < ActiveSupport::TestCase
include EnvHelpers
def test_environment_with_server_option
- args = ["thin", "-e", "production"]
+ args = ["-u", "thin", "-e", "production"]
options = parse_arguments(args)
assert_equal "production", options[:environment]
assert_equal "thin", options[:server]
@@ -22,8 +22,38 @@ class Rails::ServerTest < ActiveSupport::TestCase
assert_nil options[:server]
end
+ def test_explicit_using_option
+ args = ["-u", "thin"]
+ options = parse_arguments(args)
+ assert_equal "thin", options[:server]
+ end
+
+ def test_using_server_mistype
+ assert_match(/Could not find server "tin". Maybe you meant "thin"?/, run_command("--using", "tin"))
+ end
+
+ def test_using_positional_argument_deprecation
+ assert_match(/DEPRECATION WARNING/, run_command("tin"))
+ end
+
+ def test_using_known_server_that_isnt_in_the_gemfile
+ assert_match(/Could not load server "unicorn". Maybe you need to the add it to the Gemfile/, run_command("-u", "unicorn"))
+ end
+
+ def test_daemon_with_option
+ args = ["-d"]
+ options = parse_arguments(args)
+ assert_equal true, options[:daemonize]
+ end
+
+ def test_daemon_without_option
+ args = []
+ options = parse_arguments(args)
+ assert_equal false, options[:daemonize]
+ end
+
def test_server_option_without_environment
- args = ["thin"]
+ args = ["-u", "thin"]
with_rack_env nil do
with_rails_env nil do
options = parse_arguments(args)
@@ -60,6 +90,15 @@ class Rails::ServerTest < ActiveSupport::TestCase
def test_environment_with_host
switch_env "HOST", "1.2.3.4" do
+ assert_deprecated do
+ options = parse_arguments
+ assert_equal "1.2.3.4", options[:Host]
+ end
+ end
+ end
+
+ def test_environment_with_binding
+ switch_env "BINDING", "1.2.3.4" do
options = parse_arguments
assert_equal "1.2.3.4", options[:Host]
end
@@ -81,6 +120,18 @@ class Rails::ServerTest < ActiveSupport::TestCase
assert_equal false, options[:caching]
end
+ def test_early_hints_with_option
+ args = ["--early-hints"]
+ options = parse_arguments(args)
+ assert_equal true, options[:early_hints]
+ end
+
+ def test_early_hints_is_nil_by_default
+ args = []
+ options = parse_arguments(args)
+ assert_nil options[:early_hints]
+ end
+
def test_log_stdout
with_rack_env nil do
with_rails_env nil do
@@ -154,7 +205,7 @@ class Rails::ServerTest < ActiveSupport::TestCase
assert_equal 3000, options[:Port]
end
- switch_env "HOST", "1.2.3.4" do
+ switch_env "BINDING", "1.2.3.4" do
args = ["-b", "127.0.0.1"]
options = parse_arguments(args)
assert_equal "127.0.0.1", options[:Host]
@@ -173,6 +224,11 @@ class Rails::ServerTest < ActiveSupport::TestCase
server_options = parse_arguments(["--port=3001"])
assert_equal [:Port], server_options[:user_supplied_options]
+
+ switch_env "BINDING", "1.2.3.4" do
+ server_options = parse_arguments
+ assert_equal [:Host], server_options[:user_supplied_options]
+ end
end
def test_default_options
@@ -197,7 +253,20 @@ class Rails::ServerTest < ActiveSupport::TestCase
ARGV.replace original_args
end
+ def test_served_url
+ args = %w(-u webrick -b 127.0.0.1 -p 4567)
+ server = Rails::Server.new(parse_arguments(args))
+ assert_equal "http://127.0.0.1:4567", server.served_url
+ end
+
private
+ def run_command(*args)
+ build_app
+ rails "server", *args
+ ensure
+ teardown_app
+ end
+
def parse_arguments(args = [])
Rails::Command::ServerCommand.new([], args).server_options
end
diff --git a/railties/test/engine/test_test.rb b/railties/test/engine/test_test.rb
new file mode 100644
index 0000000000..18af85a0aa
--- /dev/null
+++ b/railties/test/engine/test_test.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class Rails::Engine::TestTest < ActiveSupport::TestCase
+ setup do
+ @destination_root = Dir.mktmpdir("bukkits")
+ Dir.chdir(@destination_root) { `bundle exec rails plugin new bukkits --mountable` }
+ end
+
+ teardown do
+ FileUtils.rm_rf(@destination_root)
+ end
+
+ test "automatically synchronize test schema" do
+ Dir.chdir(plugin_path) do
+ # In order to confirm that migration files are loaded, generate multiple migration files.
+ `bin/rails generate model user name:string;
+ bin/rails generate model todo name:string;
+ RAILS_ENV=development bin/rails db:migrate`
+
+ output = `bin/rails test test/models/bukkits/user_test.rb`
+ assert_includes(output, "0 runs, 0 assertions, 0 failures, 0 errors, 0 skips")
+ end
+ end
+
+ private
+ def plugin_path
+ "#{@destination_root}/bukkits"
+ end
+end
diff --git a/railties/test/engine_test.rb b/railties/test/engine_test.rb
index 4bd8a07085..19379e200c 100644
--- a/railties/test/engine_test.rb
+++ b/railties/test/engine_test.rb
@@ -11,7 +11,7 @@ class EngineTest < ActiveSupport::TestCase
end
end
- assert !engine.routes?
+ assert_not_predicate engine, :routes?
end
def test_application_can_be_subclassed
diff --git a/railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml b/railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml
deleted file mode 100644
index fe80872a16..0000000000
--- a/railties/test/fixtures/about_yml_plugins/bad_about_yml/about.yml
+++ /dev/null
@@ -1 +0,0 @@
-# an empty YAML file - any content in here seems to get parsed as a string \ No newline at end of file
diff --git a/railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb b/railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb
deleted file mode 100644
index 1a82a2bdd4..0000000000
--- a/railties/test/fixtures/about_yml_plugins/bad_about_yml/init.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-
-# intentionally empty
diff --git a/railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb b/railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb
deleted file mode 100644
index 1a82a2bdd4..0000000000
--- a/railties/test/fixtures/about_yml_plugins/plugin_without_about_yml/init.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-
-# intentionally empty
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index 3ecfb4edd9..f421207025 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -308,6 +308,14 @@ class ActionsTest < Rails::Generators::TestCase
end
end
+ test "rake command with capture option should run rake command with capture" do
+ assert_called_with(generator, :run, ["rake log:clear RAILS_ENV=development", verbose: false, capture: true]) do
+ with_rails_env nil do
+ action :rake, "log:clear", capture: true
+ end
+ end
+ end
+
test "rails command should run rails_command with default env" do
assert_called_with(generator, :run, ["rails log:clear RAILS_ENV=development", verbose: false]) do
with_rails_env nil do
@@ -346,6 +354,14 @@ class ActionsTest < Rails::Generators::TestCase
end
end
+ test "rails command with capture option should run rails_command with capture" do
+ assert_called_with(generator, :run, ["rails log:clear RAILS_ENV=development", verbose: false, capture: true]) do
+ with_rails_env nil do
+ action :rails_command, "log:clear", capture: true
+ end
+ end
+ end
+
def test_capify_should_run_the_capify_command
content = capture(:stderr) do
assert_called_with(generator, :run, ["capify .", verbose: false]) do
diff --git a/railties/test/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb
index 7791d472d8..9c523ad372 100644
--- a/railties/test/generators/api_app_generator_test.rb
+++ b/railties/test/generators/api_app_generator_test.rb
@@ -13,7 +13,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
Rails.application = TestApp::Application
super
- Kernel::silence_warnings do
+ Kernel.silence_warnings do
Thor::Base.shell.send(:attr_accessor, :always_force)
@shell = Thor::Base.shell.new
@shell.send(:always_force=, true)
@@ -63,6 +63,23 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generator_if_skip_action_mailer_is_given
+ run_generator [destination_root, "--api", "--skip-action-mailer"]
+ assert_file "config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/
+ assert_file "config/environments/development.rb" do |content|
+ assert_no_match(/config\.action_mailer/, content)
+ end
+ assert_file "config/environments/test.rb" do |content|
+ assert_no_match(/config\.action_mailer/, content)
+ end
+ assert_file "config/environments/production.rb" do |content|
+ assert_no_match(/config\.action_mailer/, content)
+ end
+ assert_no_directory "app/mailers"
+ assert_no_directory "test/mailers"
+ assert_no_directory "app/views"
+ end
+
def test_app_update_does_not_generate_unnecessary_config_files
run_generator
@@ -72,6 +89,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
assert_no_file "config/initializers/cookies_serializer.rb"
assert_no_file "config/initializers/assets.rb"
+ assert_no_file "config/initializers/content_security_policy.rb"
end
def test_app_update_does_not_generate_unnecessary_bin_files
@@ -149,6 +167,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase
bin/yarn
config/initializers/assets.rb
config/initializers/cookies_serializer.rb
+ config/initializers/content_security_policy.rb
lib/assets
test/helpers
tmp/cache/assets
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 904e2a5c84..a820d958f1 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -56,6 +56,7 @@ DEFAULT_APP_FILES = %w(
config/initializers/assets.rb
config/initializers/backtrace_silencers.rb
config/initializers/cookies_serializer.rb
+ config/initializers/content_security_policy.rb
config/initializers/filter_parameter_logging.rb
config/initializers/inflections.rb
config/initializers/mime_types.rb
@@ -75,6 +76,7 @@ DEFAULT_APP_FILES = %w(
log
package.json
public
+ storage
test/application_system_test_case.rb
test/test_helper.rb
test/fixtures
@@ -89,6 +91,7 @@ DEFAULT_APP_FILES = %w(
tmp
tmp/cache
tmp/cache/assets
+ tmp/storage
)
class AppGeneratorTest < Rails::Generators::TestCase
@@ -102,6 +105,15 @@ class AppGeneratorTest < Rails::Generators::TestCase
::DEFAULT_APP_FILES
end
+ def test_skip_bundle
+ assert_not_called(generator([destination_root], skip_bundle: true), :bundle_command) do
+ quietly { generator.invoke_all }
+ # skip_bundle is only about running bundle install, ensure the Gemfile is still
+ # generated.
+ assert_file "Gemfile"
+ end
+ end
+
def test_assets
run_generator
@@ -199,7 +211,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def test_new_application_doesnt_need_defaults
- assert_no_file "config/initializers/new_framework_defaults_5_2.rb"
+ assert_no_file "config/initializers/new_framework_defaults_6_0.rb"
end
def test_new_application_load_defaults
@@ -207,6 +219,8 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [app_root]
output = nil
+ assert_file "#{app_root}/config/application.rb", /\s+config\.load_defaults #{Rails::VERSION::STRING.to_f}/
+
Dir.chdir(app_root) do
output = `./bin/rails r "puts Rails.application.config.assets.unknown_asset_fallback"`
end
@@ -245,14 +259,14 @@ class AppGeneratorTest < Rails::Generators::TestCase
app_root = File.join(destination_root, "myapp")
run_generator [app_root]
- assert_no_file "#{app_root}/config/initializers/new_framework_defaults_5_2.rb"
+ assert_no_file "#{app_root}/config/initializers/new_framework_defaults_6_0.rb"
stub_rails_application(app_root) do
generator = Rails::Generators::AppGenerator.new ["rails"], { update: true }, { destination_root: app_root, shell: @shell }
generator.send(:app_const)
quietly { generator.send(:update_config_files) }
- assert_file "#{app_root}/config/initializers/new_framework_defaults_5_2.rb"
+ assert_file "#{app_root}/config/initializers/new_framework_defaults_6_0.rb"
end
end
@@ -296,6 +310,76 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_gem_for_active_storage
+ run_generator
+ assert_file "Gemfile", /^# gem 'image_processing'/
+ end
+
+ def test_gem_for_active_storage_when_skip_active_storage_is_given
+ run_generator [destination_root, "--skip-active-storage"]
+
+ assert_no_gem "image_processing"
+ end
+
+ def test_app_update_does_not_generate_active_storage_contents_when_skip_active_storage_is_given
+ app_root = File.join(destination_root, "myapp")
+ run_generator [app_root, "--skip-active-storage"]
+
+ FileUtils.cd(app_root) do
+ quietly { system("bin/rails app:update") }
+ end
+
+ assert_file "#{app_root}/config/environments/development.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{app_root}/config/environments/production.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{app_root}/config/environments/test.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_no_file "#{app_root}/config/storage.yml"
+ end
+
+ def test_app_update_does_not_generate_active_storage_contents_when_skip_active_record_is_given
+ app_root = File.join(destination_root, "myapp")
+ run_generator [app_root, "--skip-active-record"]
+
+ FileUtils.cd(app_root) do
+ quietly { system("bin/rails app:update") }
+ end
+
+ assert_file "#{app_root}/config/environments/development.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{app_root}/config/environments/production.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{app_root}/config/environments/test.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_no_file "#{app_root}/config/storage.yml"
+ end
+
+ def test_app_update_does_not_change_config_target_version
+ run_generator
+
+ FileUtils.cd(destination_root) do
+ config = "config/application.rb"
+ content = File.read(config)
+ File.write(config, content.gsub(/config\.load_defaults #{Rails::VERSION::STRING.to_f}/, "config.load_defaults 5.1"))
+ quietly { system("bin/rails app:update") }
+ end
+
+ assert_file "config/application.rb", /\s+config\.load_defaults 5\.1/
+ end
+
def test_application_names_are_not_singularized
run_generator [File.join(destination_root, "hats")]
assert_file "hats/config/environment.rb", /Rails\.application\.initialize!/
@@ -321,13 +405,13 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
- def test_config_another_database
+ def test_config_mysql_database
run_generator([destination_root, "-d", "mysql"])
assert_file "config/database.yml", /mysql/
if defined?(JRUBY_VERSION)
assert_gem "activerecord-jdbcmysql-adapter"
else
- assert_gem "mysql2", "'>= 0.3.18', '< 0.5'"
+ assert_gem "mysql2", "'>= 0.4.4', '< 0.6.0'"
end
end
@@ -342,7 +426,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
if defined?(JRUBY_VERSION)
assert_gem "activerecord-jdbcpostgresql-adapter"
else
- assert_gem "pg", "'~> 0.18'"
+ assert_gem "pg", "'>= 0.18', '< 2.0'"
end
end
@@ -381,15 +465,13 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_generator_defaults_to_puma_version
run_generator [destination_root]
- assert_gem "puma", "'~> 3.7'"
+ assert_gem "puma", "'~> 3.11'"
end
def test_generator_if_skip_puma_is_given
run_generator [destination_root, "--skip-puma"]
assert_no_file "config/puma.rb"
- assert_file "Gemfile" do |content|
- assert_no_match(/puma/, content)
- end
+ assert_no_gem "puma"
end
def test_generator_has_assets_gems
@@ -409,20 +491,18 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "config/application.rb", /#\s+require\s+["']rails\/test_unit\/railtie["']/
- assert_file "Gemfile" do |content|
- assert_no_match(/capybara/, content)
- assert_no_match(/selenium-webdriver/, content)
- end
+ assert_no_gem "capybara"
+ assert_no_gem "selenium-webdriver"
+ assert_no_gem "chromedriver-helper"
assert_no_directory("test")
end
def test_generator_if_skip_system_test_is_given
run_generator [destination_root, "--skip-system-test"]
- assert_file "Gemfile" do |content|
- assert_no_match(/capybara/, content)
- assert_no_match(/selenium-webdriver/, content)
- end
+ assert_no_gem "capybara"
+ assert_no_gem "selenium-webdriver"
+ assert_no_gem "chromedriver-helper"
assert_directory("test")
@@ -468,10 +548,8 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_match(/javascript_include_tag\s+'application' \%>/, contents)
end
- assert_file "Gemfile" do |content|
- assert_no_match(/coffee-rails/, content)
- assert_no_match(/uglifier/, content)
- end
+ assert_no_gem "coffee-rails"
+ assert_no_gem "uglifier"
assert_file "config/environments/production.rb" do |content|
assert_no_match(/config\.assets\.js_compressor = :uglifier/, content)
@@ -495,9 +573,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_inclusion_of_a_debugger
run_generator
if defined?(JRUBY_VERSION) || RUBY_ENGINE == "rbx"
- assert_file "Gemfile" do |content|
- assert_no_match(/byebug/, content)
- end
+ assert_no_gem "byebug"
else
assert_gem "byebug"
end
@@ -560,6 +636,18 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_match(/run git init/, output)
end
+ def test_quiet_option
+ output = run_generator [File.join(destination_root, "myapp"), "--quiet"]
+ assert_empty output
+ end
+
+ def test_force_option_overwrites_every_file_except_master_key
+ run_generator [File.join(destination_root, "myapp")]
+ output = run_generator [File.join(destination_root, "myapp"), "--force"]
+ assert_match(/force/, output)
+ assert_no_match("force config/master.key", output)
+ end
+
def test_application_name_with_spaces
path = File.join(destination_root, "foo bar")
@@ -636,9 +724,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_called_with(Process, :respond_to?, [[:fork], [:fork]], returns: false) do
run_generator
- assert_file "Gemfile" do |content|
- assert_no_match(/spring/, content)
- end
+ assert_no_gem "spring"
end
end
@@ -646,25 +732,58 @@ class AppGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--skip-spring"]
assert_no_file "config/spring.rb"
- assert_file "Gemfile" do |content|
- assert_no_match(/spring/, content)
- end
+ assert_no_gem "spring"
end
def test_spring_with_dev_option
run_generator [destination_root, "--dev"]
- assert_file "Gemfile" do |content|
- assert_no_match(/spring/, content)
+ assert_no_gem "spring"
+ end
+
+ def test_webpack_option
+ command_check = -> command, *_ do
+ @called ||= 0
+ if command == "webpacker:install"
+ @called += 1
+ assert_equal 1, @called, "webpacker:install expected to be called once, but was called #{@called} times."
+ end
+ end
+
+ generator([destination_root], webpack: "webpack").stub(:rails_command, command_check) do
+ generator.stub :bundle_command, nil do
+ quietly { generator.invoke_all }
+ end
+ end
+
+ assert_gem "webpacker"
+ end
+
+ def test_webpack_option_with_js_framework
+ command_check = -> command, *_ do
+ case command
+ when "webpacker:install"
+ @webpacker ||= 0
+ @webpacker += 1
+ assert_equal 1, @webpacker, "webpacker:install expected to be called once, but was called #{@webpacker} times."
+ when "webpacker:install:react"
+ @react ||= 0
+ @react += 1
+ assert_equal 1, @react, "webpacker:install:react expected to be called once, but was called #{@react} times."
+ end
+ end
+
+ generator([destination_root], webpack: "react").stub(:rails_command, command_check) do
+ generator.stub :bundle_command, nil do
+ quietly { generator.invoke_all }
+ end
end
end
def test_generator_if_skip_turbolinks_is_given
run_generator [destination_root, "--skip-turbolinks"]
- assert_file "Gemfile" do |content|
- assert_no_match(/turbolinks/, content)
- end
+ assert_no_gem "turbolinks"
assert_file "app/views/layouts/application.html.erb" do |content|
assert_no_match(/data-turbolinks-track/, content)
end
@@ -673,6 +792,40 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_bootsnap
+ run_generator
+
+ unless defined?(JRUBY_VERSION)
+ assert_gem "bootsnap"
+ assert_file "config/boot.rb" do |content|
+ assert_match(/require 'bootsnap\/setup'/, content)
+ end
+ else
+ assert_no_gem "bootsnap"
+ assert_file "config/boot.rb" do |content|
+ assert_no_match(/require 'bootsnap\/setup'/, content)
+ end
+ end
+ end
+
+ def test_skip_bootsnap
+ run_generator [destination_root, "--skip-bootsnap"]
+
+ assert_no_gem "bootsnap"
+ assert_file "config/boot.rb" do |content|
+ assert_no_match(/require 'bootsnap\/setup'/, content)
+ end
+ end
+
+ def test_bootsnap_with_dev_option
+ run_generator [destination_root, "--dev"]
+
+ assert_no_gem "bootsnap"
+ assert_file "config/boot.rb" do |content|
+ assert_no_match(/require 'bootsnap\/setup'/, content)
+ end
+ end
+
def test_inclusion_of_ruby_version
run_generator
@@ -680,7 +833,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_match(/ruby '#{RUBY_VERSION}'/, content)
end
assert_file ".ruby-version" do |content|
- assert_match(/#{RUBY_VERSION}/, content)
+ assert_match(/#{RUBY_ENGINE}-#{RUBY_ENGINE_VERSION}/, content)
end
end
@@ -737,7 +890,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
sequence = ["git init", "install", "exec spring binstub --all", "echo ran after_bundle"]
@sequence_step ||= 0
- ensure_bundler_first = -> command do
+ ensure_bundler_first = -> command, options = nil do
assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}"
@sequence_step += 1
end
@@ -745,7 +898,9 @@ class AppGeneratorTest < Rails::Generators::TestCase
generator([destination_root], template: path).stub(:open, check_open, template) do
generator.stub(:bundle_command, ensure_bundler_first) do
generator.stub(:run, ensure_bundler_first) do
- quietly { generator.invoke_all }
+ generator.stub(:rails_command, ensure_bundler_first) do
+ quietly { generator.invoke_all }
+ end
end
end
end
@@ -753,6 +908,14 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_equal 4, @sequence_step
end
+ def test_gitignore
+ run_generator
+
+ assert_file ".gitignore" do |content|
+ assert_match(/config\/master\.key/, content)
+ end
+ end
+
def test_system_tests_directory_generated
run_generator
@@ -760,6 +923,15 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_directory("test/system")
end
+ unless Gem.win_platform?
+ def test_master_key_is_only_readable_by_the_owner
+ run_generator
+
+ stat = File.stat("config/master.key")
+ assert_equal "100600", sprintf("%o", stat.mode)
+ end
+ end
+
private
def stub_rails_application(root)
Rails.application.config.root = root
@@ -780,6 +952,12 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def assert_no_gem(gem)
+ assert_file "Gemfile" do |content|
+ assert_no_match(gem, content)
+ end
+ end
+
def assert_listen_related_configuration
assert_gem "listen"
assert_gem "spring-watcher-listen"
@@ -790,9 +968,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
def assert_no_listen_related_configuration
- assert_file "Gemfile" do |content|
- assert_no_match(/listen/, content)
- end
+ assert_no_gem "listen"
assert_file "config/environments/development.rb" do |content|
assert_match(/^\s*# config\.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
diff --git a/railties/test/generators/argv_scrubber_test.rb b/railties/test/generators/argv_scrubber_test.rb
index 3f4c985a33..9ef61dc978 100644
--- a/railties/test/generators/argv_scrubber_test.rb
+++ b/railties/test/generators/argv_scrubber_test.rb
@@ -82,9 +82,8 @@ module Rails
file.puts "--hello --world"
file.flush
- message = nil
scrubber = Class.new(ARGVScrubber) {
- define_method(:puts) { |msg| message = msg }
+ define_method(:puts) { |msg| }
}.new ["new", "--rc=#{file.path}"]
args = scrubber.prepare!
assert_equal ["--hello", "--world"], args
diff --git a/railties/test/generators/channel_generator_test.rb b/railties/test/generators/channel_generator_test.rb
index e238197eba..e543cc11b8 100644
--- a/railties/test/generators/channel_generator_test.rb
+++ b/railties/test/generators/channel_generator_test.rb
@@ -76,4 +76,14 @@ class ChannelGeneratorTest < Rails::Generators::TestCase
assert_file "app/channels/application_cable/connection.rb"
assert_file "app/assets/javascripts/cable.js"
end
+
+ def test_channel_suffix_is_not_duplicated
+ run_generator ["chat_channel"]
+
+ assert_no_file "app/channels/chat_channel_channel.rb"
+ assert_file "app/channels/chat_channel.rb"
+
+ assert_no_file "app/assets/javascripts/channels/chat_channel.js"
+ assert_file "app/assets/javascripts/channels/chat.js"
+ end
end
diff --git a/railties/test/generators/controller_generator_test.rb b/railties/test/generators/controller_generator_test.rb
index a3218951a6..021004c9b8 100644
--- a/railties/test/generators/controller_generator_test.rb
+++ b/railties/test/generators/controller_generator_test.rb
@@ -109,4 +109,33 @@ class ControllerGeneratorTest < Rails::Generators::TestCase
assert_match(/^ namespace :admin do\n get 'dashboard\/index'\n get 'dashboard\/show'\n end$/, route)
end
end
+
+ def test_does_not_add_routes_when_action_is_not_specified
+ run_generator ["admin/dashboard"]
+ assert_file "config/routes.rb" do |routes|
+ assert_no_match(/namespace :admin/, routes)
+ end
+ end
+
+ def test_controller_suffix_is_not_duplicated
+ run_generator ["account_controller"]
+
+ assert_no_file "app/controllers/account_controller_controller.rb"
+ assert_file "app/controllers/account_controller.rb"
+
+ assert_no_file "app/views/account_controller/"
+ assert_file "app/views/account/"
+
+ assert_no_file "test/controllers/account_controller_controller_test.rb"
+ assert_file "test/controllers/account_controller_test.rb"
+
+ assert_no_file "app/helpers/account_controller_helper.rb"
+ assert_file "app/helpers/account_helper.rb"
+
+ assert_no_file "app/assets/javascripts/account_controller.js"
+ assert_file "app/assets/javascripts/account.js"
+
+ assert_no_file "app/assets/stylesheets/account_controller.css"
+ assert_file "app/assets/stylesheets/account.css"
+ end
end
diff --git a/railties/test/generators/create_migration_test.rb b/railties/test/generators/create_migration_test.rb
index 3cb7fd6baa..2ae38045c5 100644
--- a/railties/test/generators/create_migration_test.rb
+++ b/railties/test/generators/create_migration_test.rb
@@ -70,7 +70,7 @@ class CreateMigrationTest < Rails::Generators::TestCase
create_migration
assert_match(/identical db\/migrate\/1_create_articles\.rb\n/, invoke!)
- assert @migration.identical?
+ assert_predicate @migration, :identical?
end
def test_invoke_when_exists_not_identical
diff --git a/railties/test/generators/encrypted_secrets_generator_test.rb b/railties/test/generators/encrypted_secrets_generator_test.rb
deleted file mode 100644
index eacb5166c0..0000000000
--- a/railties/test/generators/encrypted_secrets_generator_test.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require "generators/generators_test_helper"
-require "rails/generators/rails/encrypted_secrets/encrypted_secrets_generator"
-
-class EncryptedSecretsGeneratorTest < Rails::Generators::TestCase
- include GeneratorsTestHelper
-
- def setup
- super
- cd destination_root
- end
-
- def test_generates_key_file_and_encrypted_secrets_file
- run_generator
-
- assert_file "config/secrets.yml.key", /\w+/
-
- assert File.exist?("config/secrets.yml.enc")
- assert_no_match(/# production:\n# external_api_key: \w+/, IO.binread("config/secrets.yml.enc"))
- assert_match(/# production:\n# external_api_key: \w+/, Rails::Secrets.read)
- end
-
- def test_appends_to_gitignore
- FileUtils.touch(".gitignore")
-
- run_generator
-
- assert_file ".gitignore", /config\/secrets.yml.key/, /(?!config\/secrets.yml.enc)/
- end
-
- def test_warns_when_ignore_is_missing
- assert_match(/Add this to your ignore file/i, run_generator)
- end
-
- def test_doesnt_generate_a_new_key_file_if_already_opted_in_to_encrypted_secrets
- FileUtils.mkdir("config")
- File.open("config/secrets.yml.enc", "w") { |f| f.puts "already secrety" }
-
- run_generator
-
- assert_no_file "config/secrets.yml.key"
- end
-end
diff --git a/railties/test/generators/generated_attribute_test.rb b/railties/test/generators/generated_attribute_test.rb
index c6f7bdeda1..772b4f6f0d 100644
--- a/railties/test/generators/generated_attribute_test.rb
+++ b/railties/test/generators/generated_attribute_test.rb
@@ -104,25 +104,25 @@ class GeneratedAttributeTest < Rails::Generators::TestCase
def test_reference_is_true
%w(references belongs_to).each do |attribute_type|
- assert create_generated_attribute(attribute_type).reference?
+ assert_predicate create_generated_attribute(attribute_type), :reference?
end
end
def test_reference_is_false
%w(foo bar baz).each do |attribute_type|
- assert !create_generated_attribute(attribute_type).reference?
+ assert_not_predicate create_generated_attribute(attribute_type), :reference?
end
end
def test_polymorphic_reference_is_true
%w(references belongs_to).each do |attribute_type|
- assert create_generated_attribute("#{attribute_type}{polymorphic}").polymorphic?
+ assert_predicate create_generated_attribute("#{attribute_type}{polymorphic}"), :polymorphic?
end
end
def test_polymorphic_reference_is_false
%w(foo bar baz).each do |attribute_type|
- assert !create_generated_attribute("#{attribute_type}{polymorphic}").polymorphic?
+ assert_not_predicate create_generated_attribute("#{attribute_type}{polymorphic}"), :polymorphic?
end
end
@@ -148,7 +148,7 @@ class GeneratedAttributeTest < Rails::Generators::TestCase
att = Rails::Generators::GeneratedAttribute.parse("supplier:references{required}:index")
assert_equal "supplier", att.name
assert_equal :references, att.type
- assert att.has_index?
- assert att.required?
+ assert_predicate att, :has_index?
+ assert_predicate att, :required?
end
end
diff --git a/railties/test/generators/generators_test_helper.rb b/railties/test/generators/generators_test_helper.rb
index cb5d8da7b1..ad2a55f496 100644
--- a/railties/test/generators/generators_test_helper.rb
+++ b/railties/test/generators/generators_test_helper.rb
@@ -43,9 +43,9 @@ module GeneratorsTestHelper
end
def copy_routes
- routes = File.expand_path("../../lib/rails/generators/rails/app/templates/config/routes.rb", __dir__)
+ routes = File.expand_path("../../lib/rails/generators/rails/app/templates/config/routes.rb.tt", __dir__)
destination = File.join(destination_root, "config")
FileUtils.mkdir_p(destination)
- FileUtils.cp routes, destination
+ FileUtils.cp routes, File.join(destination, "routes.rb")
end
end
diff --git a/railties/test/generators/job_generator_test.rb b/railties/test/generators/job_generator_test.rb
index 13276fac65..234ba6dad7 100644
--- a/railties/test/generators/job_generator_test.rb
+++ b/railties/test/generators/job_generator_test.rb
@@ -35,4 +35,14 @@ class JobGeneratorTest < Rails::Generators::TestCase
assert_match(/class ApplicationJob < ActiveJob::Base/, job)
end
end
+
+ def test_job_suffix_is_not_duplicated
+ run_generator ["notifier_job"]
+
+ assert_no_file "app/jobs/notifier_job_job.rb"
+ assert_file "app/jobs/notifier_job.rb"
+
+ assert_no_file "test/jobs/notifier_job_job_test.rb"
+ assert_file "test/jobs/notifier_job_test.rb"
+ end
end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 516aa0704f..8d933e82c3 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -2,7 +2,6 @@
require "generators/generators_test_helper"
require "rails/generators/rails/model/model_generator"
-require "active_support/core_ext/string/strip"
class ModelGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
@@ -379,10 +378,10 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_required_belongs_to_adds_required_association
run_generator ["account", "supplier:references{required}"]
- expected_file = <<-FILE.strip_heredoc
- class Account < ApplicationRecord
- belongs_to :supplier, required: true
- end
+ expected_file = <<~FILE
+ class Account < ApplicationRecord
+ belongs_to :supplier, required: true
+ end
FILE
assert_file "app/models/account.rb", expected_file
end
@@ -390,10 +389,10 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_required_polymorphic_belongs_to_generages_correct_model
run_generator ["account", "supplier:references{required,polymorphic}"]
- expected_file = <<-FILE.strip_heredoc
- class Account < ApplicationRecord
- belongs_to :supplier, polymorphic: true, required: true
- end
+ expected_file = <<~FILE
+ class Account < ApplicationRecord
+ belongs_to :supplier, polymorphic: true, required: true
+ end
FILE
assert_file "app/models/account.rb", expected_file
end
@@ -401,10 +400,10 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_required_and_polymorphic_are_order_independent
run_generator ["account", "supplier:references{polymorphic.required}"]
- expected_file = <<-FILE.strip_heredoc
- class Account < ApplicationRecord
- belongs_to :supplier, polymorphic: true, required: true
- end
+ expected_file = <<~FILE
+ class Account < ApplicationRecord
+ belongs_to :supplier, polymorphic: true, required: true
+ end
FILE
assert_file "app/models/account.rb", expected_file
end
@@ -452,11 +451,11 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_token_option_adds_has_secure_token
run_generator ["user", "token:token", "auth_token:token"]
- expected_file = <<-FILE.strip_heredoc
- class User < ApplicationRecord
- has_secure_token
- has_secure_token :auth_token
- end
+ expected_file = <<~FILE
+ class User < ApplicationRecord
+ has_secure_token
+ has_secure_token :auth_token
+ end
FILE
assert_file "app/models/user.rb", expected_file
end
diff --git a/railties/test/generators/named_base_test.rb b/railties/test/generators/named_base_test.rb
index 67f05926e3..4e61b660d7 100644
--- a/railties/test/generators/named_base_test.rb
+++ b/railties/test/generators/named_base_test.rb
@@ -33,6 +33,17 @@ class NamedBaseTest < Rails::Generators::TestCase
assert_name g, "foos", :plural_name
assert_name g, "admin.foo", :i18n_scope
assert_name g, "admin_foos", :table_name
+ assert_name g, "admin/foos", :controller_name
+ assert_name g, %w(admin), :controller_class_path
+ assert_name g, "Admin::Foos", :controller_class_name
+ assert_name g, "admin/foos", :controller_file_path
+ assert_name g, "foos", :controller_file_name
+ assert_name g, "admin.foos", :controller_i18n_scope
+ assert_name g, "admin_foo", :singular_route_name
+ assert_name g, "admin_foos", :plural_route_name
+ assert_name g, "@admin_foo", :redirect_resource_name
+ assert_name g, "admin_foo", :model_resource_name
+ assert_name g, "admin_foos", :index_helper
end
def test_named_generator_attributes_as_ruby
@@ -47,6 +58,17 @@ class NamedBaseTest < Rails::Generators::TestCase
assert_name g, "foos", :plural_name
assert_name g, "admin.foo", :i18n_scope
assert_name g, "admin_foos", :table_name
+ assert_name g, "Admin::Foos", :controller_name
+ assert_name g, %w(admin), :controller_class_path
+ assert_name g, "Admin::Foos", :controller_class_name
+ assert_name g, "admin/foos", :controller_file_path
+ assert_name g, "foos", :controller_file_name
+ assert_name g, "admin.foos", :controller_i18n_scope
+ assert_name g, "admin_foo", :singular_route_name
+ assert_name g, "admin_foos", :plural_route_name
+ assert_name g, "@admin_foo", :redirect_resource_name
+ assert_name g, "admin_foo", :model_resource_name
+ assert_name g, "admin_foos", :index_helper
end
def test_named_generator_attributes_without_pluralized
@@ -59,7 +81,7 @@ class NamedBaseTest < Rails::Generators::TestCase
ActiveRecord::Base.pluralize_table_names = original_pluralize_table_names
end
- def test_scaffold_plural_names
+ def test_namespaced_scaffold_plural_names
g = generator ["admin/foo"]
assert_name g, "admin/foos", :controller_name
assert_name g, %w(admin), :controller_class_path
@@ -69,7 +91,7 @@ class NamedBaseTest < Rails::Generators::TestCase
assert_name g, "admin.foos", :controller_i18n_scope
end
- def test_scaffold_plural_names_as_ruby
+ def test_namespaced_scaffold_plural_names_as_ruby
g = generator ["Admin::Foo"]
assert_name g, "Admin::Foos", :controller_name
assert_name g, %w(admin), :controller_class_path
@@ -131,6 +153,19 @@ class NamedBaseTest < Rails::Generators::TestCase
assert_name g, "admin/foos", :controller_file_path
assert_name g, "foos", :controller_file_name
assert_name g, "admin.foos", :controller_i18n_scope
+ assert_name g, "admin_user", :singular_route_name
+ assert_name g, "admin_users", :plural_route_name
+ assert_name g, "[:admin, @user]", :redirect_resource_name
+ assert_name g, "[:admin, user]", :model_resource_name
+ assert_name g, "admin_users", :index_helper
+ end
+
+ def test_scaffold_plural_names
+ g = generator ["User"]
+ assert_name g, "@user", :redirect_resource_name
+ assert_name g, "user", :model_resource_name
+ assert_name g, "user", :singular_route_name
+ assert_name g, "users", :plural_route_name
end
private
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index 38130ceb68..28ac3611b7 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -82,11 +82,12 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
def test_generating_in_full_mode_with_almost_of_all_skip_options
- run_generator [destination_root, "--full", "-M", "-O", "-C", "-S", "-T"]
+ run_generator [destination_root, "--full", "-M", "-O", "-C", "-S", "-T", "--skip-active-storage"]
assert_file "bin/rails" do |content|
assert_no_match(/\s+require\s+["']rails\/all["']/, content)
end
assert_file "bin/rails", /#\s+require\s+["']active_record\/railtie["']/
+ assert_file "bin/rails", /#\s+require\s+["']active_storage\/engine["']/
assert_file "bin/rails", /#\s+require\s+["']action_mailer\/railtie["']/
assert_file "bin/rails", /#\s+require\s+["']action_cable\/engine["']/
assert_file "bin/rails", /#\s+require\s+["']sprockets\/railtie["']/
@@ -216,12 +217,22 @@ class PluginGeneratorTest < Rails::Generators::TestCase
def test_javascripts_generation
run_generator [destination_root, "--mountable"]
- assert_file "app/assets/javascripts/bukkits/application.js"
+ assert_file "app/assets/javascripts/bukkits/application.js" do |content|
+ assert_match "//= require rails-ujs", content
+ assert_match "//= require activestorage", content
+ assert_match "//= require_tree .", content
+ end
+ assert_file "app/views/layouts/bukkits/application.html.erb" do |content|
+ assert_match "javascript_include_tag", content
+ end
end
def test_skip_javascripts
run_generator [destination_root, "--skip-javascript", "--mountable"]
assert_no_file "app/assets/javascripts/bukkits/application.js"
+ assert_file "app/views/layouts/bukkits/application.html.erb" do |content|
+ assert_no_match "javascript_include_tag", content
+ end
end
def test_template_from_dir_pwd
@@ -240,8 +251,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
run_generator [destination_root, "--full", "--skip_active_record"]
FileUtils.cd destination_root
quietly { system "bundle install" }
- # FIXME: Active Storage will provoke a test error without ActiveRecord (fix by allowing to skip active storage)
- assert_match(/1 runs, 0 assertions, 0 failures, 1 errors/, `bundle exec rake test 2>&1`)
+ assert_match(/1 runs, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test 2>&1`)
end
def test_ensure_that_migration_tasks_work_with_mountable_option
@@ -321,8 +331,11 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/
assert_file "app/views/layouts/bukkits/application.html.erb" do |contents|
assert_match "<title>Bukkits</title>", contents
+ assert_match "<%= csrf_meta_tags %>", contents
+ assert_match "<%= csp_meta_tag %>", contents
assert_match(/stylesheet_link_tag\s+['"]bukkits\/application['"]/, contents)
assert_match(/javascript_include_tag\s+['"]bukkits\/application['"]/, contents)
+ assert_match "<%= yield %>", contents
end
assert_file "test/test_helper.rb" do |content|
assert_match(/ActiveRecord::Migrator\.migrations_paths.+\.\.\/test\/dummy\/db\/migrate/, content)
@@ -475,6 +488,8 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_no_file "test/dummy/Gemfile"
assert_no_file "test/dummy/public/robots.txt"
assert_no_file "test/dummy/README.md"
+ assert_no_file "test/dummy/config/master.key"
+ assert_no_file "test/dummy/config/credentials.yml.enc"
assert_no_directory "test/dummy/lib/tasks"
assert_no_directory "test/dummy/test"
assert_no_directory "test/dummy/vendor"
@@ -514,10 +529,11 @@ class PluginGeneratorTest < Rails::Generators::TestCase
gemfile_path = "#{Rails.root}/Gemfile"
Object.const_set("APP_PATH", Rails.root)
FileUtils.touch gemfile_path
+ File.write(gemfile_path, "#foo")
run_generator
- assert_file gemfile_path, /gem 'bukkits', path: 'tmp\/bukkits'/
+ assert_file gemfile_path, /^gem 'bukkits', path: 'tmp\/bukkits'/
ensure
Object.send(:remove_const, "APP_PATH")
FileUtils.rm gemfile_path
@@ -719,6 +735,38 @@ class PluginGeneratorTest < Rails::Generators::TestCase
Object.send(:remove_const, "ENGINE_ROOT")
end
+ def test_after_bundle_callback
+ path = "http://example.org/rails_template"
+ template = %{ after_bundle { run "echo ran after_bundle" } }.dup
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ check_open = -> *args do
+ assert_equal [ path, "Accept" => "application/x-thor-template" ], args
+ template
+ end
+
+ sequence = ["echo ran after_bundle"]
+ @sequence_step ||= 0
+ ensure_bundler_first = -> command do
+ assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}"
+ @sequence_step += 1
+ end
+
+ content = nil
+ generator([destination_root], template: path).stub(:open, check_open, template) do
+ generator.stub(:bundle_command, ensure_bundler_first) do
+ generator.stub(:run, ensure_bundler_first) do
+ silence_stream($stdout) do
+ content = capture(:stderr) { generator.invoke_all }
+ end
+ end
+ end
+ end
+
+ assert_equal 1, @sequence_step
+ assert_match(/DEPRECATION WARNING: `after_bundle` is deprecated/, content)
+ end
+
private
def action(*args, &block)
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index 384524aba9..fd5aa817b4 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -174,6 +174,29 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
assert_instance_method :index, content do |m|
assert_match("@users = User.all", m)
end
+
+ assert_instance_method :create, content do |m|
+ assert_match("redirect_to [:admin, @user]", m)
+ end
+
+ assert_instance_method :update, content do |m|
+ assert_match("redirect_to [:admin, @user]", m)
+ end
+ end
+
+ assert_file "app/views/admin/users/index.html.erb" do |content|
+ assert_match("'Show', [:admin, user]", content)
+ assert_match("'Edit', edit_admin_user_path(user)", content)
+ assert_match("'Destroy', [:admin, user]", content)
+ assert_match("'New User', new_admin_user_path", content)
+ end
+
+ assert_file "app/views/admin/users/new.html.erb" do |content|
+ assert_match("'Back', admin_users_path", content)
+ end
+
+ assert_file "app/views/admin/users/_form.html.erb" do |content|
+ assert_match("model: [:admin, user]", content)
end
end
@@ -184,6 +207,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
Dir.chdir(engine_path) do
quietly { `bin/rails g controller dashboard foo` }
+ quietly { `bin/rails db:migrate RAILS_ENV=test` }
assert_match(/2 runs, 2 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
end
end
@@ -195,6 +219,7 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
Dir.chdir(engine_path) do
quietly { `bin/rails g controller dashboard foo` }
+ quietly { `bin/rails db:migrate RAILS_ENV=test` }
assert_match(/2 runs, 2 assertions, 0 failures, 0 errors/, `bin/rails test 2>&1`)
end
end
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 03322c1c59..29426cd99f 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -282,7 +282,14 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
/class Admin::RolesTest < ApplicationSystemTestCase/
# Views
- %w(index edit new show _form).each do |view|
+ assert_file "app/views/admin/roles/index.html.erb" do |content|
+ assert_match("'Show', admin_role", content)
+ assert_match("'Edit', edit_admin_role_path(admin_role)", content)
+ assert_match("'Destroy', admin_role", content)
+ assert_match("'New Admin Role', new_admin_role_path", content)
+ end
+
+ %w(edit new show _form).each do |view|
assert_file "app/views/admin/roles/#{view}.html.erb"
end
assert_no_file "app/views/layouts/admin/roles.html.erb"
@@ -464,8 +471,8 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
end
assert_file "app/views/accounts/_form.html.erb" do |content|
- assert_match(/^\W{4}<%= form\.text_field :name, id: :account_name %>/, content)
- assert_match(/^\W{4}<%= form\.text_field :currency_id, id: :account_currency_id %>/, content)
+ assert_match(/^\W{4}<%= form\.text_field :name %>/, content)
+ assert_match(/^\W{4}<%= form\.text_field :currency_id %>/, content)
end
end
@@ -488,8 +495,8 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
end
assert_file "app/views/users/_form.html.erb" do |content|
- assert_match(/<%= form\.password_field :password, id: :user_password %>/, content)
- assert_match(/<%= form\.password_field :password_confirmation, id: :user_password_confirmation %>/, content)
+ assert_match(/<%= form\.password_field :password %>/, content)
+ assert_match(/<%= form\.password_field :password_confirmation %>/, content)
end
assert_file "app/views/users/index.html.erb" do |content|
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index 654d16de65..aa577e4234 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -9,7 +9,7 @@ module SharedGeneratorTests
super
Rails::Generators::AppGenerator.instance_variable_set("@desc", nil)
- Kernel::silence_warnings do
+ Kernel.silence_warnings do
Thor::Base.shell.send(:attr_accessor, :always_force)
@shell = Thor::Base.shell.new
@shell.send(:always_force=, true)
@@ -92,7 +92,9 @@ module SharedGeneratorTests
end
generator([destination_root], template: path).stub(:open, check_open, template) do
- quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
+ generator.stub :bundle_command, nil do
+ quietly { assert_match(/It works!/, capture(:stdout) { generator.invoke_all }) }
+ end
end
end
@@ -103,15 +105,6 @@ module SharedGeneratorTests
end
end
- def test_skip_bundle
- assert_not_called(generator([destination_root], skip_bundle: true), :bundle_command) do
- quietly { generator.invoke_all }
- # skip_bundle is only about running bundle install, ensure the Gemfile is still
- # generated.
- assert_file "Gemfile"
- end
- end
-
def test_skip_git
run_generator [destination_root, "--skip-git", "--full"]
assert_no_file(".gitignore")
@@ -129,13 +122,26 @@ module SharedGeneratorTests
end
def test_default_frameworks_are_required_when_others_are_removed
- run_generator [destination_root, "--skip-active-record", "--skip-action-mailer", "--skip-action-cable", "--skip-sprockets"]
- assert_file "#{application_path}/config/application.rb", /require\s+["']rails["']/
- assert_file "#{application_path}/config/application.rb", /require\s+["']active_model\/railtie["']/
- assert_file "#{application_path}/config/application.rb", /require\s+["']active_job\/railtie["']/
- assert_file "#{application_path}/config/application.rb", /require\s+["']action_controller\/railtie["']/
- assert_file "#{application_path}/config/application.rb", /require\s+["']action_view\/railtie["']/
- assert_file "#{application_path}/config/application.rb", /require\s+["']active_storage\/engine["']/
+ run_generator [
+ destination_root,
+ "--skip-active-record",
+ "--skip-active-storage",
+ "--skip-action-mailer",
+ "--skip-action-cable",
+ "--skip-sprockets"
+ ]
+
+ assert_file "#{application_path}/config/application.rb", /^require\s+["']rails["']/
+ assert_file "#{application_path}/config/application.rb", /^require\s+["']active_model\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /^require\s+["']active_job\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /^# require\s+["']active_record\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /^# require\s+["']active_storage\/engine["']/
+ assert_file "#{application_path}/config/application.rb", /^require\s+["']action_controller\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /^# require\s+["']action_mailer\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /^require\s+["']action_view\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /^# require\s+["']action_cable\/engine["']/
+ assert_file "#{application_path}/config/application.rb", /^# require\s+["']sprockets\/railtie["']/
+ assert_file "#{application_path}/config/application.rb", /^require\s+["']rails\/test_unit\/railtie["']/
end
def test_generator_without_skips
@@ -189,6 +195,94 @@ module SharedGeneratorTests
end
end
+ def test_generator_for_active_storage
+ run_generator
+
+ assert_file "#{application_path}/app/assets/javascripts/application.js" do |content|
+ assert_match(/^\/\/= require activestorage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/development.rb" do |content|
+ assert_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/production.rb" do |content|
+ assert_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/test.rb" do |content|
+ assert_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{application_path}/config/storage.yml"
+ assert_directory "#{application_path}/storage"
+ assert_directory "#{application_path}/tmp/storage"
+
+ assert_file ".gitignore" do |content|
+ assert_match(/\/storage\//, content)
+ end
+ end
+
+ def test_generator_if_skip_active_storage_is_given
+ run_generator [destination_root, "--skip-active-storage"]
+
+ assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/
+
+ assert_file "#{application_path}/app/assets/javascripts/application.js" do |content|
+ assert_no_match(/^\/\/= require activestorage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/development.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/production.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/test.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_no_file "#{application_path}/config/storage.yml"
+ assert_no_directory "#{application_path}/storage"
+ assert_no_directory "#{application_path}/tmp/storage"
+
+ assert_file ".gitignore" do |content|
+ assert_no_match(/\/storage\//, content)
+ end
+ end
+
+ def test_generator_does_not_generate_active_storage_contents_if_skip_active_record_is_given
+ run_generator [destination_root, "--skip-active-record"]
+
+ assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']active_storage\/engine["']/
+
+ assert_file "#{application_path}/app/assets/javascripts/application.js" do |content|
+ assert_no_match(/^\/\/= require activestorage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/development.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/production.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_file "#{application_path}/config/environments/test.rb" do |content|
+ assert_no_match(/config\.active_storage/, content)
+ end
+
+ assert_no_file "#{application_path}/config/storage.yml"
+ assert_no_directory "#{application_path}/storage"
+ assert_no_directory "#{application_path}/tmp/storage"
+
+ assert_file ".gitignore" do |content|
+ assert_no_match(/\/storage\//, content)
+ end
+ end
+
def test_generator_if_skip_action_mailer_is_given
run_generator [destination_root, "--skip-action-mailer"]
assert_file "#{application_path}/config/application.rb", /#\s+require\s+["']action_mailer\/railtie["']/
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 28e7617d7f..a16a2d3f0a 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -33,13 +33,26 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_generator_suggestions
name = :migrationz
output = capture(:stdout) { Rails::Generators.invoke name }
- assert_match "Maybe you meant 'migration'", output
+ assert_match 'Maybe you meant "migration"?', output
+ end
+
+ def test_generator_suggestions_except_en_locale
+ orig_available_locales = I18n.available_locales
+ orig_default_locale = I18n.default_locale
+ I18n.available_locales = :ja
+ I18n.default_locale = :ja
+ name = :tas
+ output = capture(:stdout) { Rails::Generators.invoke name }
+ assert_match 'Maybe you meant "task"?', output
+ ensure
+ I18n.available_locales = orig_available_locales
+ I18n.default_locale = orig_default_locale
end
def test_generator_multiple_suggestions
name = :tas
output = capture(:stdout) { Rails::Generators.invoke name }
- assert_match "Maybe you meant 'task', 'job' or", output
+ assert_match 'Maybe you meant "task"?', output
end
def test_help_when_a_generator_with_required_arguments_is_invoked_without_arguments
@@ -51,7 +64,7 @@ class GeneratorsTest < Rails::Generators::TestCase
assert File.exist?(File.join(@path, "generators", "model_generator.rb"))
assert_called_with(Rails::Generators::ModelGenerator, :start, [["Account"], {}]) do
warnings = capture(:stderr) { Rails::Generators.invoke :model, ["Account"] }
- assert warnings.empty?
+ assert_empty warnings
end
end
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index b7f214cb73..3cde7c03b0 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
@@ -82,22 +87,6 @@ module TestHelpers
assert_match "charset=utf-8", resp[1]["Content-Type"]
assert extract_body(resp).match(/Yay! You.*re on Rails!/)
end
-
- def assert_success(resp)
- assert_equal 202, resp[0]
- end
-
- def assert_missing(resp)
- assert_equal 404, resp[0]
- end
-
- def assert_header(key, value, resp)
- assert_equal value, resp[1][key.to_s]
- end
-
- def assert_body(expected, resp)
- assert_equal expected, extract_body(resp)
- end
end
module Generation
@@ -123,22 +112,57 @@ module TestHelpers
end
end
- File.open("#{app_path}/config/database.yml", "w") do |f|
- f.puts <<-YAML
- default: &default
- adapter: sqlite3
- pool: 5
- timeout: 5000
- development:
- <<: *default
- database: db/development.sqlite3
- test:
- <<: *default
- database: db/test.sqlite3
- production:
- <<: *default
- database: db/production.sqlite3
- YAML
+ if options[:multi_db]
+ File.open("#{app_path}/config/database.yml", "w") do |f|
+ f.puts <<-YAML
+ default: &default
+ adapter: sqlite3
+ pool: 5
+ timeout: 5000
+ development:
+ primary:
+ <<: *default
+ database: db/development.sqlite3
+ animals:
+ <<: *default
+ database: db/development_animals.sqlite3
+ migrations_paths: db/animals_migrate
+ test:
+ primary:
+ <<: *default
+ database: db/test.sqlite3
+ animals:
+ <<: *default
+ database: db/test_animals.sqlite3
+ migrations_paths: db/animals_migrate
+ production:
+ primary:
+ <<: *default
+ database: db/production.sqlite3
+ animals:
+ <<: *default
+ database: db/production_animals.sqlite3
+ migrations_paths: db/animals_migrate
+ YAML
+ end
+ else
+ File.open("#{app_path}/config/database.yml", "w") do |f|
+ f.puts <<-YAML
+ default: &default
+ adapter: sqlite3
+ pool: 5
+ timeout: 5000
+ development:
+ <<: *default
+ database: db/development.sqlite3
+ test:
+ <<: *default
+ database: db/test.sqlite3
+ production:
+ <<: *default
+ database: db/production.sqlite3
+ YAML
+ end
end
add_to_config <<-RUBY
@@ -153,6 +177,7 @@ module TestHelpers
def teardown_app
ENV["RAILS_ENV"] = @prev_rails_env if @prev_rails_env
+ FileUtils.rm_rf(tmp_path)
end
# Make a very basic app, without creating the whole directory structure.
@@ -235,7 +260,7 @@ module TestHelpers
# Invoke a bin/rails command inside the app
#
- # allow_failures:: true to return normally if the command exits with
+ # allow_failure:: true to return normally if the command exits with
# a non-zero status. By default, this method will raise.
# stderr:: true to pass STDERR output straight to the "real" STDERR.
# By default, the STDERR and STDOUT of the process will be
@@ -357,10 +382,12 @@ module TestHelpers
end
def app_file(path, contents, mode = "w")
- FileUtils.mkdir_p File.dirname("#{app_path}/#{path}")
- File.open("#{app_path}/#{path}", mode) do |f|
+ file_name = "#{app_path}/#{path}"
+ FileUtils.mkdir_p File.dirname(file_name)
+ File.open(file_name, mode) do |f|
f.puts contents
end
+ file_name
end
def remove_file(path)
@@ -380,6 +407,21 @@ module TestHelpers
$:.reject! { |path| path =~ %r'/(#{to_remove.join('|')})/' }
end
+
+ def use_postgresql
+ File.open("#{app_path}/config/database.yml", "w") do |f|
+ f.puts <<-YAML
+ default: &default
+ adapter: postgresql
+ pool: 5
+ database: railties_test
+ development:
+ <<: *default
+ test:
+ <<: *default
+ YAML
+ end
+ end
end
end
@@ -388,6 +430,10 @@ class ActiveSupport::TestCase
include TestHelpers::Rack
include TestHelpers::Generation
include ActiveSupport::Testing::Stream
+
+ def frozen_error_class
+ Object.const_defined?(:FrozenError) ? FrozenError : RuntimeError
+ end
end
# Create a scope and build a fixture rails app
diff --git a/railties/test/minitest/rails_plugin_test.rb b/railties/test/minitest/rails_plugin_test.rb
new file mode 100644
index 0000000000..7c3a2022a9
--- /dev/null
+++ b/railties/test/minitest/rails_plugin_test.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+
+class Minitest::RailsPluginTest < ActiveSupport::TestCase
+ setup do
+ @options = Minitest.process_args []
+ @output = StringIO.new("".encode("UTF-8"))
+ end
+
+ test "default reporters are replaced" do
+ with_reporter Minitest::CompositeReporter.new do |reporter|
+ reporter << Minitest::SummaryReporter.new(@output, @options)
+ reporter << Minitest::ProgressReporter.new(@output, @options)
+ reporter << Minitest::Reporter.new(@output, @options)
+
+ Minitest.plugin_rails_init({})
+
+ assert_equal 3, reporter.reporters.count
+ assert reporter.reporters.any? { |candidate| candidate.kind_of?(Minitest::SuppressedSummaryReporter) }
+ assert reporter.reporters.any? { |candidate| candidate.kind_of?(::Rails::TestUnitReporter) }
+ assert reporter.reporters.any? { |candidate| candidate.kind_of?(Minitest::Reporter) }
+ end
+ end
+
+ test "no custom reporters are added if nothing to replace" do
+ with_reporter Minitest::CompositeReporter.new do |reporter|
+ Minitest.plugin_rails_init({})
+
+ assert_empty reporter.reporters
+ end
+ end
+
+ private
+ def with_reporter(reporter)
+ old_reporter, Minitest.reporter = Minitest.reporter, reporter
+
+ yield reporter
+ ensure
+ Minitest.reporter = old_reporter
+ end
+end
diff --git a/railties/test/paths_test.rb b/railties/test/paths_test.rb
index 854b4448a4..9f5bb37c20 100644
--- a/railties/test/paths_test.rb
+++ b/railties/test/paths_test.rb
@@ -104,7 +104,7 @@ class PathsTest < ActiveSupport::TestCase
File.stub(:exist?, true) do
@root.add "app", with: "/app"
@root["app"].autoload_once!
- assert @root["app"].autoload_once?
+ assert_predicate @root["app"], :autoload_once?
assert_includes @root.autoload_once, @root["app"].expanded.first
end
end
@@ -112,17 +112,17 @@ class PathsTest < ActiveSupport::TestCase
test "it is possible to remove a path that should be autoloaded only once" do
@root["app"] = "/app"
@root["app"].autoload_once!
- assert @root["app"].autoload_once?
+ assert_predicate @root["app"], :autoload_once?
@root["app"].skip_autoload_once!
- assert !@root["app"].autoload_once?
+ assert_not_predicate @root["app"], :autoload_once?
assert_not_includes @root.autoload_once, @root["app"].expanded.first
end
test "it is possible to add a path without assignment and specify it should be loaded only once" do
File.stub(:exist?, true) do
@root.add "app", with: "/app", autoload_once: true
- assert @root["app"].autoload_once?
+ assert_predicate @root["app"], :autoload_once?
assert_includes @root.autoload_once, "/app"
end
end
@@ -130,7 +130,7 @@ class PathsTest < ActiveSupport::TestCase
test "it is possible to add multiple paths without assignment and specify it should be loaded only once" do
File.stub(:exist?, true) do
@root.add "app", with: ["/app", "/app2"], autoload_once: true
- assert @root["app"].autoload_once?
+ assert_predicate @root["app"], :autoload_once?
assert_includes @root.autoload_once, "/app"
assert_includes @root.autoload_once, "/app2"
end
@@ -158,7 +158,7 @@ class PathsTest < ActiveSupport::TestCase
File.stub(:exist?, true) do
@root["app"] = "/app"
@root["app"].eager_load!
- assert @root["app"].eager_load?
+ assert_predicate @root["app"], :eager_load?
assert_includes @root.eager_load, @root["app"].to_a.first
end
end
@@ -166,17 +166,17 @@ class PathsTest < ActiveSupport::TestCase
test "it is possible to skip a path from eager loading" do
@root["app"] = "/app"
@root["app"].eager_load!
- assert @root["app"].eager_load?
+ assert_predicate @root["app"], :eager_load?
@root["app"].skip_eager_load!
- assert !@root["app"].eager_load?
+ assert_not_predicate @root["app"], :eager_load?
assert_not_includes @root.eager_load, @root["app"].to_a.first
end
test "it is possible to add a path without assignment and mark it as eager" do
File.stub(:exist?, true) do
@root.add "app", with: "/app", eager_load: true
- assert @root["app"].eager_load?
+ assert_predicate @root["app"], :eager_load?
assert_includes @root.eager_load, "/app"
end
end
@@ -184,7 +184,7 @@ class PathsTest < ActiveSupport::TestCase
test "it is possible to add multiple paths without assignment and mark them as eager" do
File.stub(:exist?, true) do
@root.add "app", with: ["/app", "/app2"], eager_load: true
- assert @root["app"].eager_load?
+ assert_predicate @root["app"], :eager_load?
assert_includes @root.eager_load, "/app"
assert_includes @root.eager_load, "/app2"
end
@@ -193,8 +193,8 @@ class PathsTest < ActiveSupport::TestCase
test "it is possible to create a path without assignment and mark it both as eager and load once" do
File.stub(:exist?, true) do
@root.add "app", with: "/app", eager_load: true, autoload_once: true
- assert @root["app"].eager_load?
- assert @root["app"].autoload_once?
+ assert_predicate @root["app"], :eager_load?
+ assert_predicate @root["app"], :autoload_once?
assert_includes @root.eager_load, "/app"
assert_includes @root.autoload_once, "/app"
end
@@ -254,7 +254,7 @@ class PathsTest < ActiveSupport::TestCase
test "a path can be added to the load path on creation" do
File.stub(:exist?, true) do
@root.add "app", with: "/app", load_path: true
- assert @root["app"].load_path?
+ assert_predicate @root["app"], :load_path?
assert_equal ["/app"], @root.load_paths
end
end
@@ -271,7 +271,7 @@ class PathsTest < ActiveSupport::TestCase
test "a path can be marked as autoload on creation" do
File.stub(:exist?, true) do
@root.add "app", with: "/app", autoload: true
- assert @root["app"].autoload?
+ assert_predicate @root["app"], :autoload?
assert_equal ["/app"], @root.autoload_paths
end
end
diff --git a/railties/test/rack_logger_test.rb b/railties/test/rack_logger_test.rb
index e47f30d5b6..6e8f333e1d 100644
--- a/railties/test/rack_logger_test.rb
+++ b/railties/test/rack_logger_test.rb
@@ -14,14 +14,21 @@ module Rails
attr_reader :logger
- def initialize(logger = NULL, taggers = nil, &block)
- super(->(_) { block.call; [200, {}, []] }, taggers)
+ def initialize(logger = NULL, app: nil, taggers: nil, &block)
+ app ||= ->(_) { block.call; [200, {}, []] }
+ super(app, taggers)
@logger = logger
end
def development?; false; end
end
+ class TestApp < Struct.new(:response)
+ def call(_env)
+ response
+ end
+ end
+
Subscriber = Struct.new(:starts, :finishes) do
def initialize(starts = [], finishes = [])
super
@@ -72,6 +79,17 @@ module Rails
end
end
end
+
+ def test_logger_does_not_mutate_app_return
+ response = [].freeze
+ app = TestApp.new(response)
+ logger = TestLogger.new(app: app)
+ assert_no_changes("response") do
+ assert_nothing_raised do
+ logger.call("REQUEST_METHOD" => "GET")
+ end
+ end
+ end
end
end
end
diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb
index 227a739b71..50522c1be6 100644
--- a/railties/test/rails_info_test.rb
+++ b/railties/test/rails_info_test.rb
@@ -2,27 +2,14 @@
require "abstract_unit"
-unless defined?(Rails) && defined?(Rails::Info)
- module Rails
- class Info; end
- end
-end
-
-require "active_support/core_ext/kernel/reporting"
-
class InfoTest < ActiveSupport::TestCase
- def setup
- Rails.send :remove_const, :Info
- silence_warnings { load "rails/info.rb" }
- end
-
def test_property_with_block_swallows_exceptions_and_ignores_property
assert_nothing_raised do
Rails::Info.module_eval do
property("Bogus") { raise }
end
end
- assert !property_defined?("Bogus")
+ assert_not property_defined?("Bogus")
end
def test_property_with_string
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index e6964b4b18..9a3ddc8d5e 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -32,6 +32,11 @@ module RailtiesTest
require "#{app_path}/config/environment"
end
+ def migrations
+ migration_root = File.expand_path(ActiveRecord::Migrator.migrations_paths.first, app_path)
+ ActiveRecord::MigrationContext.new(migration_root).migrations
+ end
+
test "serving sprocket's assets" do
@plugin.write "app/assets/javascripts/engine.js.erb", "<%= :alert %>();"
add_to_env_config "development", "config.assets.digest = false"
@@ -82,31 +87,32 @@ module RailtiesTest
end
RUBY
- add_to_config "ActiveRecord::Base.timestamped_migrations = false"
-
boot_rails
Dir.chdir(app_path) do
+ # Install Active Storage migration file first so as not to affect test.
+ `bundle exec rake active_storage:install`
output = `bundle exec rake bukkits:install:migrations`
- assert File.exist?("#{app_path}/db/migrate/2_create_users.bukkits.rb")
- assert File.exist?("#{app_path}/db/migrate/3_add_last_name_to_users.bukkits.rb")
- assert_match(/Copied migration 2_create_users\.bukkits\.rb from bukkits/, output)
- assert_match(/Copied migration 3_add_last_name_to_users\.bukkits\.rb from bukkits/, output)
- assert_match(/NOTE: Migration 3_create_sessions\.rb from bukkits has been skipped/, output)
- assert_equal 3, Dir["#{app_path}/db/migrate/*.rb"].length
-
- output = `bundle exec rake railties:install:migrations`.split("\n")
+ ["CreateUsers", "AddLastNameToUsers", "CreateSessions"].each do |migration_name|
+ assert migrations.detect { |migration| migration.name == migration_name }
+ end
+ assert_match(/Copied migration \d+_create_users\.bukkits\.rb from bukkits/, output)
+ assert_match(/Copied migration \d+_add_last_name_to_users\.bukkits\.rb from bukkits/, output)
+ assert_match(/NOTE: Migration \d+_create_sessions\.rb from bukkits has been skipped/, output)
- assert_no_match(/2_create_users/, output.join("\n"))
+ migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length
- bukkits_migration_order = output.index(output.detect { |o| /NOTE: Migration 3_create_sessions\.rb from bukkits has been skipped/ =~ o })
- assert_not_nil bukkits_migration_order, "Expected migration to be skipped"
+ assert_equal migrations.length, migrations_count
- migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length
- `bundle exec rake railties:install:migrations`
+ output = `bundle exec rake railties:install:migrations`.split("\n")
assert_equal migrations_count, Dir["#{app_path}/db/migrate/*.rb"].length
+
+ assert_no_match(/\d+_create_users/, output.join("\n"))
+
+ bukkits_migration_order = output.index(output.detect { |o| /NOTE: Migration \d+_create_sessions\.rb from bukkits has been skipped/ =~ o })
+ assert_not_nil bukkits_migration_order, "Expected migration to be skipped"
end
end
@@ -171,10 +177,12 @@ module RailtiesTest
boot_rails
Dir.chdir(app_path) do
+ # Install Active Storage migration file first so as not to affect test.
+ `bundle exec rake active_storage:install`
output = `bundle exec rake railties:install:migrations`.split("\n")
- assert_match(/Copied migration \d+_create_users\.core_engine\.rb from core_engine/, output.second)
- assert_match(/Copied migration \d+_create_keys\.api_engine\.rb from api_engine/, output.last)
+ assert_match(/Copied migration \d+_create_users\.core_engine\.rb from core_engine/, output.first)
+ assert_match(/Copied migration \d+_create_keys\.api_engine\.rb from api_engine/, output.second)
end
end
@@ -203,9 +211,12 @@ module RailtiesTest
Dir.chdir(@plugin.path) do
output = `bundle exec rake app:bukkits:install:migrations`
- assert File.exist?("#{app_path}/db/migrate/0_add_first_name_to_users.bukkits.rb")
- assert_match(/Copied migration 0_add_first_name_to_users\.bukkits\.rb from bukkits/, output)
- assert_equal 1, Dir["#{app_path}/db/migrate/*.rb"].length
+
+ migration_with_engine_path = migrations.detect { |migration| migration.name == "AddFirstNameToUsers" }
+ assert migration_with_engine_path
+ assert_match(/\/db\/migrate\/\d+_add_first_name_to_users\.bukkits\.rb/, migration_with_engine_path.filename)
+ assert_match(/Copied migration \d+_add_first_name_to_users\.bukkits\.rb from bukkits/, output)
+ assert_equal migrations.length, Dir["#{app_path}/db/migrate/*.rb"].length
end
end
@@ -215,7 +226,7 @@ module RailtiesTest
require "rdoc/task"
require "rake/testtask"
Rails.application.load_tasks
- assert !Rake::Task.task_defined?("bukkits:install:migrations")
+ assert_not Rake::Task.task_defined?("bukkits:install:migrations")
end
test "puts its lib directory on load path" do
@@ -734,7 +745,7 @@ YAML
assert_equal "bukkits", Bukkits::Engine.engine_name
assert_equal Bukkits.railtie_namespace, Bukkits::Engine
assert ::Bukkits::MyMailer.method_defined?(:foo_url)
- assert !::Bukkits::MyMailer.method_defined?(:bar_url)
+ assert_not ::Bukkits::MyMailer.method_defined?(:bar_url)
get("/bukkits/from_app")
assert_equal "false", last_response.body
@@ -969,14 +980,14 @@ YAML
boot_rails
app_generators = Rails.application.config.generators.options[:rails]
- assert_equal :mongoid , app_generators[:orm]
- assert_equal :liquid , app_generators[:template_engine]
+ assert_equal :mongoid, app_generators[:orm]
+ assert_equal :liquid, app_generators[:template_engine]
assert_equal :test_unit, app_generators[:test_framework]
generators = Bukkits::Engine.config.generators.options[:rails]
assert_equal :data_mapper, generators[:orm]
- assert_equal :haml , generators[:template_engine]
- assert_equal :rspec , generators[:test_framework]
+ assert_equal :haml, generators[:template_engine]
+ assert_equal :rspec, generators[:test_framework]
end
test "engine should get default generators with ability to overwrite them" do
@@ -992,10 +1003,10 @@ YAML
generators = Bukkits::Engine.config.generators.options[:rails]
assert_equal :active_record, generators[:orm]
- assert_equal :rspec , generators[:test_framework]
+ assert_equal :rspec, generators[:test_framework]
app_generators = Rails.application.config.generators.options[:rails]
- assert_equal :test_unit , app_generators[:test_framework]
+ assert_equal :test_unit, app_generators[:test_framework]
end
test "do not create table_name_prefix method if it already exists" do
@@ -1468,6 +1479,21 @@ YAML
assert_equal "/fruits/2/bukkits/posts", last_response.body
end
+ test "active_storage:install task works within engine" do
+ @plugin.write "Rakefile", <<-RUBY
+ APP_RAKEFILE = '#{app_path}/Rakefile'
+ load 'rails/tasks/engine.rake'
+ RUBY
+
+ Dir.chdir(@plugin.path) do
+ output = `bundle exec rake app:active_storage:install`
+ assert $?.success?, output
+
+ active_storage_migration = migrations.detect { |migration| migration.name == "CreateActiveStorageTables" }
+ assert active_storage_migration
+ end
+ end
+
private
def app
Rails.application
diff --git a/railties/test/railties/railtie_test.rb b/railties/test/railties/railtie_test.rb
index 359ab0fdae..7c3d1e3759 100644
--- a/railties/test/railties/railtie_test.rb
+++ b/railties/test/railties/railtie_test.rb
@@ -65,7 +65,7 @@ module RailtiesTest
test "railtie can add to_prepare callbacks" do
$to_prepare = false
class Foo < Rails::Railtie ; config.to_prepare { $to_prepare = true } ; end
- assert !$to_prepare
+ assert_not $to_prepare
require "#{app_path}/config/environment"
require "rack/test"
extend Rack::Test::Methods
@@ -91,7 +91,7 @@ module RailtiesTest
test "railtie can add after_initialize callbacks" do
$after_initialize = false
class Foo < Rails::Railtie ; config.after_initialize { $after_initialize = true } ; end
- assert !$after_initialize
+ assert_not $after_initialize
require "#{app_path}/config/environment"
assert $after_initialize
end
@@ -107,7 +107,7 @@ module RailtiesTest
require "#{app_path}/config/environment"
- assert !$ran_block
+ assert_not $ran_block
require "rake"
require "rake/testtask"
require "rdoc/task"
@@ -151,7 +151,7 @@ module RailtiesTest
require "#{app_path}/config/environment"
- assert !$ran_block
+ assert_not $ran_block
Rails.application.load_generators
assert $ran_block
end
@@ -167,7 +167,7 @@ module RailtiesTest
require "#{app_path}/config/environment"
- assert !$ran_block
+ assert_not $ran_block
Rails.application.load_console
assert $ran_block
end
@@ -183,7 +183,7 @@ module RailtiesTest
require "#{app_path}/config/environment"
- assert !$ran_block
+ assert_not $ran_block
Rails.application.load_runner
assert $ran_block
end
@@ -197,7 +197,7 @@ module RailtiesTest
end
end
- assert !$ran_block
+ assert_not $ran_block
require "#{app_path}/config/environment"
assert $ran_block
end
diff --git a/railties/test/secrets_test.rb b/railties/test/secrets_test.rb
index 888fee173a..06877bc76a 100644
--- a/railties/test/secrets_test.rb
+++ b/railties/test/secrets_test.rb
@@ -1,20 +1,13 @@
# frozen_string_literal: true
require "isolation/abstract_unit"
-require "rails/generators"
-require "rails/generators/rails/encrypted_secrets/encrypted_secrets_generator"
require "rails/secrets"
class Rails::SecretsTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation
- def setup
- build_app
- end
-
- def teardown
- teardown_app
- end
+ setup :build_app
+ teardown :teardown_app
test "setting read to false skips parsing" do
run_secrets_generator do
@@ -172,9 +165,8 @@ class Rails::SecretsTest < ActiveSupport::TestCase
private
def run_secrets_generator
Dir.chdir(app_path) do
- capture(:stdout) do
- Rails::Generators::EncryptedSecretsGenerator.start
- end
+ File.write("config/secrets.yml.key", "f731758c639da2604dfb6bf3d1025de8")
+ File.write("config/secrets.yml.enc", "sEB0mHxDbeP1/KdnMk00wyzPFACl9K6t0cZWn5/Mfx/YbTHvnI07vrneqHg9kaH3wOS7L6pIQteu1P077OtE4BSx/ZRc/sgQPHyWu/tXsrfHqnPNpayOF/XZqizE91JacSFItNMWpuPsp9ynbzz+7cGhoB1S4aPNIU6u0doMrzdngDbijsaAFJmsHIQh6t/QHoJx--8aMoE0PvUWmw1Iqz--ldFqnM/K0g9k17M8PKoN/Q==")
add_to_config <<-RUBY
config.read_encrypted_secrets = true
diff --git a/railties/test/test_unit/reporter_test.rb b/railties/test/test_unit/reporter_test.rb
index ad852d0f35..91cb47779b 100644
--- a/railties/test/test_unit/reporter_test.rb
+++ b/railties/test/test_unit/reporter_test.rb
@@ -163,7 +163,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase
end
def failed_test
- ft = ExampleTest.new(:woot)
+ ft = Minitest::Result.from(ExampleTest.new(:woot))
ft.failures << begin
raise Minitest::Assertion, "boo"
rescue Minitest::Assertion => e
@@ -176,17 +176,17 @@ class TestUnitReporterTest < ActiveSupport::TestCase
error = ArgumentError.new("wups")
error.set_backtrace([ "some_test.rb:4" ])
- et = ExampleTest.new(:woot)
+ et = Minitest::Result.from(ExampleTest.new(:woot))
et.failures << Minitest::UnexpectedError.new(error)
et
end
def passing_test
- ExampleTest.new(:woot)
+ Minitest::Result.from(ExampleTest.new(:woot))
end
def skipped_test
- st = ExampleTest.new(:woot)
+ st = Minitest::Result.from(ExampleTest.new(:woot))
st.failures << begin
raise Minitest::Skip, "skipchurches, misstemples"
rescue Minitest::Assertion => e