railties 7.1.5.2 → 7.2.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +174 -806
  3. data/lib/minitest/rails_plugin.rb +5 -2
  4. data/lib/rails/all.rb +1 -3
  5. data/lib/rails/api/task.rb +3 -2
  6. data/lib/rails/application/bootstrap.rb +5 -6
  7. data/lib/rails/application/configuration.rb +31 -36
  8. data/lib/rails/application/dummy_config.rb +2 -2
  9. data/lib/rails/application/finisher.rb +7 -0
  10. data/lib/rails/application.rb +13 -57
  11. data/lib/rails/backtrace_cleaner.rb +14 -1
  12. data/lib/rails/cli.rb +0 -1
  13. data/lib/rails/command.rb +1 -1
  14. data/lib/rails/commands/app/update_command.rb +86 -0
  15. data/lib/rails/commands/console/console_command.rb +2 -21
  16. data/lib/rails/commands/console/irb_console.rb +137 -0
  17. data/lib/rails/commands/credentials/credentials_command.rb +2 -2
  18. data/lib/rails/commands/dbconsole/dbconsole_command.rb +21 -30
  19. data/lib/rails/commands/devcontainer/devcontainer_command.rb +34 -0
  20. data/lib/rails/commands/rake/rake_command.rb +1 -1
  21. data/lib/rails/commands/runner/runner_command.rb +14 -3
  22. data/lib/rails/commands/server/server_command.rb +5 -3
  23. data/lib/rails/commands/test/test_command.rb +2 -0
  24. data/lib/rails/configuration.rb +10 -1
  25. data/lib/rails/console/app.rb +5 -32
  26. data/lib/rails/console/helpers.rb +5 -16
  27. data/lib/rails/console/methods.rb +23 -0
  28. data/lib/rails/engine.rb +5 -5
  29. data/lib/rails/gem_version.rb +3 -3
  30. data/lib/rails/generators/app_base.rb +70 -49
  31. data/lib/rails/generators/base.rb +5 -1
  32. data/lib/rails/generators/database.rb +227 -69
  33. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb.tt +2 -0
  34. data/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt +2 -0
  35. data/lib/rails/generators/erb/scaffold/templates/new.html.erb.tt +2 -0
  36. data/lib/rails/generators/generated_attribute.rb +26 -1
  37. data/lib/rails/generators/rails/app/app_generator.rb +52 -23
  38. data/lib/rails/generators/rails/app/templates/Dockerfile.tt +23 -14
  39. data/lib/rails/generators/rails/app/templates/Gemfile.tt +16 -16
  40. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb.tt +4 -0
  41. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +8 -1
  42. data/lib/rails/generators/rails/app/templates/app/views/pwa/manifest.json.erb.tt +22 -0
  43. data/lib/rails/generators/rails/app/templates/app/views/pwa/service-worker.js +26 -0
  44. data/lib/rails/generators/rails/app/templates/bin/brakeman.tt +6 -0
  45. data/lib/rails/generators/rails/app/templates/bin/rubocop.tt +7 -0
  46. data/lib/rails/generators/rails/app/templates/bin/setup.tt +6 -2
  47. data/lib/rails/generators/rails/app/templates/config/application.rb.tt +1 -1
  48. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml.tt +3 -3
  49. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +7 -0
  50. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +8 -1
  51. data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +3 -3
  52. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +11 -6
  53. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +2 -0
  54. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +6 -5
  55. data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +1 -1
  56. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_2.rb.tt +70 -0
  57. data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +39 -29
  58. data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +4 -0
  59. data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +5 -0
  60. data/lib/rails/generators/rails/app/templates/dockerignore.tt +13 -0
  61. data/lib/rails/generators/rails/app/templates/github/ci.yml.tt +138 -0
  62. data/lib/rails/generators/rails/app/templates/github/dependabot.yml +12 -0
  63. data/lib/rails/generators/rails/app/templates/gitignore.tt +3 -3
  64. data/lib/rails/generators/rails/app/templates/public/406-unsupported-browser.html +66 -0
  65. data/lib/rails/generators/rails/app/templates/public/icon.png +0 -0
  66. data/lib/rails/generators/rails/app/templates/public/icon.svg +3 -0
  67. data/lib/rails/generators/rails/app/templates/rubocop.yml.tt +8 -0
  68. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb.tt +1 -1
  69. data/lib/rails/generators/rails/controller/controller_generator.rb +1 -1
  70. data/lib/rails/generators/rails/db/system/change/change_generator.rb +131 -20
  71. data/lib/rails/generators/rails/devcontainer/devcontainer_generator.rb +166 -0
  72. data/lib/rails/generators/rails/migration/migration_generator.rb +4 -0
  73. data/lib/rails/generators/rails/plugin/plugin_generator.rb +38 -7
  74. data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
  75. data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +5 -1
  76. data/lib/rails/generators/rails/plugin/templates/bin/rubocop.tt +7 -0
  77. data/lib/rails/generators/rails/plugin/templates/github/ci.yml.tt +103 -0
  78. data/lib/rails/generators/rails/plugin/templates/github/dependabot.yml +12 -0
  79. data/lib/rails/generators/rails/plugin/templates/rubocop.yml.tt +8 -0
  80. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb.tt +1 -1
  81. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +10 -0
  82. data/lib/rails/generators/test_unit/scaffold/templates/system_test.rb.tt +2 -0
  83. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb.tt +1 -1
  84. data/lib/rails/generators/testing/assertions.rb +20 -0
  85. data/lib/rails/generators/testing/behavior.rb +7 -6
  86. data/lib/rails/generators.rb +1 -1
  87. data/lib/rails/health_controller.rb +1 -1
  88. data/lib/rails/info.rb +2 -2
  89. data/lib/rails/info_controller.rb +2 -4
  90. data/lib/rails/mailers_controller.rb +14 -1
  91. data/lib/rails/paths.rb +2 -2
  92. data/lib/rails/pwa_controller.rb +15 -0
  93. data/lib/rails/rack/logger.rb +15 -7
  94. data/lib/rails/railtie/configurable.rb +2 -2
  95. data/lib/rails/railtie.rb +15 -16
  96. data/lib/rails/tasks/framework.rake +0 -26
  97. data/lib/rails/tasks/tmp.rake +1 -1
  98. data/lib/rails/templates/layouts/application.html.erb +1 -1
  99. data/lib/rails/templates/rails/mailers/email.html.erb +12 -8
  100. data/lib/rails/templates/rails/welcome/index.html.erb +3 -2
  101. data/lib/rails/test_help.rb +2 -4
  102. data/lib/rails/test_unit/reporter.rb +8 -2
  103. data/lib/rails/test_unit/runner.rb +21 -2
  104. data/lib/rails/test_unit/test_parser.rb +45 -0
  105. data/lib/rails.rb +6 -3
  106. metadata +41 -32
  107. data/lib/rails/app_updater.rb +0 -52
  108. data/lib/rails/commands/secrets/USAGE +0 -61
  109. data/lib/rails/commands/secrets/secrets_command.rb +0 -47
  110. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml.tt +0 -68
  111. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml.tt +0 -54
  112. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +0 -70
  113. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +0 -24
  114. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml.tt +0 -62
  115. data/lib/rails/generators/rails/app/templates/config/databases/sqlserver.yml.tt +0 -53
  116. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +0 -280
  117. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png +0 -0
  118. data/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png +0 -0
  119. data/lib/rails/generators/rails/app/templates/public/favicon.ico +0 -0
  120. data/lib/rails/ruby_version_check.rb +0 -17
  121. data/lib/rails/secrets.rb +0 -110
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/application_controller"
4
+
5
+ class Rails::PwaController < Rails::ApplicationController # :nodoc:
6
+ skip_forgery_protection
7
+
8
+ def service_worker
9
+ render template: "pwa/service-worker", layout: false
10
+ end
11
+
12
+ def manifest
13
+ render template: "pwa/manifest", layout: false
14
+ end
15
+ end
@@ -20,22 +20,26 @@ module Rails
20
20
  def call(env)
21
21
  request = ActionDispatch::Request.new(env)
22
22
 
23
- if logger.respond_to?(:tagged)
24
- logger.tagged(*compute_tags(request)) { call_app(request, env) }
23
+ env["rails.rack_logger_tag_count"] = if logger.respond_to?(:push_tags)
24
+ logger.push_tags(*compute_tags(request)).size
25
25
  else
26
- call_app(request, env)
26
+ 0
27
27
  end
28
+
29
+ call_app(request, env)
28
30
  end
29
31
 
30
32
  private
31
33
  def call_app(request, env) # :doc:
34
+ logger_tag_pop_count = env["rails.rack_logger_tag_count"]
35
+
32
36
  instrumenter = ActiveSupport::Notifications.instrumenter
33
37
  handle = instrumenter.build_handle("request.action_dispatch", { request: request })
34
38
  handle.start
35
39
 
36
40
  logger.info { started_request_message(request) }
37
41
  status, headers, body = response = @app.call(env)
38
- body = ::Rack::BodyProxy.new(body, &handle.method(:finish))
42
+ body = ::Rack::BodyProxy.new(body) { finish_request_instrumentation(handle, logger_tag_pop_count) }
39
43
 
40
44
  if response.frozen?
41
45
  [status, headers, body]
@@ -44,10 +48,8 @@ module Rails
44
48
  response
45
49
  end
46
50
  rescue Exception
47
- handle.finish
51
+ finish_request_instrumentation(handle, logger_tag_pop_count)
48
52
  raise
49
- ensure
50
- ActiveSupport::LogSubscriber.flush_all!
51
53
  end
52
54
 
53
55
  # Started GET "/session/new" for 127.0.0.1 at 2012-09-26 14:51:42 -0700
@@ -75,6 +77,12 @@ module Rails
75
77
  def logger
76
78
  Rails.logger
77
79
  end
80
+
81
+ def finish_request_instrumentation(handle, logger_tag_pop_count)
82
+ handle.finish
83
+ logger.pop_tags(logger_tag_pop_count) if logger.respond_to?(:pop_tags) && logger_tag_pop_count > 0
84
+ ActiveSupport::LogSubscriber.flush_all!
85
+ end
78
86
  end
79
87
  end
80
88
  end
@@ -27,8 +27,8 @@ module Rails
27
27
  end
28
28
 
29
29
  private
30
- def method_missing(*args, &block)
31
- instance.send(*args, &block)
30
+ def method_missing(...)
31
+ instance.send(...)
32
32
  end
33
33
  end
34
34
  end
data/lib/rails/railtie.rb CHANGED
@@ -50,8 +50,8 @@ module Rails
50
50
  # To add an initialization step to the \Rails boot process from your railtie, just
51
51
  # define the initialization code with the +initializer+ macro:
52
52
  #
53
- # class MyGem::Railtie < Rails::Railtie
54
- # initializer "my_gem.configure_rails_initialization" do
53
+ # class MyRailtie < Rails::Railtie
54
+ # initializer "my_railtie.configure_rails_initialization" do
55
55
  # # some initialization behavior
56
56
  # end
57
57
  # end
@@ -59,9 +59,9 @@ module Rails
59
59
  # If specified, the block can also receive the application object, in case you
60
60
  # need to access some application-specific configuration, like middleware:
61
61
  #
62
- # class MyGem::Railtie < Rails::Railtie
63
- # initializer "my_gem.configure_rails_initialization" do |app|
64
- # app.middleware.use MyGem::Middleware
62
+ # class MyRailtie < Rails::Railtie
63
+ # initializer "my_railtie.configure_rails_initialization" do |app|
64
+ # app.middleware.use MyRailtie::Middleware
65
65
  # end
66
66
  # end
67
67
  #
@@ -74,14 +74,14 @@ module Rails
74
74
  # Railties can access a config object which contains configuration shared by all
75
75
  # railties and the application:
76
76
  #
77
- # class MyGem::Railtie < Rails::Railtie
77
+ # class MyRailtie < Rails::Railtie
78
78
  # # Customize the ORM
79
- # config.app_generators.orm :my_gem_orm
79
+ # config.app_generators.orm :my_railtie_orm
80
80
  #
81
81
  # # Add a to_prepare block which is executed once in production
82
82
  # # and before each request in development.
83
83
  # config.to_prepare do
84
- # MyGem.setup!
84
+ # MyRailtie.setup!
85
85
  # end
86
86
  # end
87
87
  #
@@ -90,9 +90,9 @@ module Rails
90
90
  # If your railtie has Rake tasks, you can tell \Rails to load them through the method
91
91
  # +rake_tasks+:
92
92
  #
93
- # class MyGem::Railtie < Rails::Railtie
93
+ # class MyRailtie < Rails::Railtie
94
94
  # rake_tasks do
95
- # load "path/to/my_gem.tasks"
95
+ # load "path/to/my_railtie.tasks"
96
96
  # end
97
97
  # end
98
98
  #
@@ -100,9 +100,9 @@ module Rails
100
100
  # your generators at a different location, you can specify in your railtie a block which
101
101
  # will load them during normal generators lookup:
102
102
  #
103
- # class MyGem::Railtie < Rails::Railtie
103
+ # class MyRailtie < Rails::Railtie
104
104
  # generators do
105
- # require "path/to/my_gem_generator"
105
+ # require "path/to/my_railtie_generator"
106
106
  # end
107
107
  # end
108
108
  #
@@ -120,7 +120,7 @@ module Rails
120
120
  # this less confusing for everyone.
121
121
  # It can be used like this:
122
122
  #
123
- # class MyGem::Railtie < Rails::Railtie
123
+ # class MyRailtie < Rails::Railtie
124
124
  # server do
125
125
  # WebpackServer.start
126
126
  # end
@@ -221,14 +221,13 @@ module Rails
221
221
 
222
222
  # If the class method does not have a method, then send the method call
223
223
  # to the Railtie instance.
224
- def method_missing(name, *args, &block)
224
+ def method_missing(name, ...)
225
225
  if !abstract_railtie? && instance.respond_to?(name)
226
- instance.public_send(name, *args, &block)
226
+ instance.public_send(name, ...)
227
227
  else
228
228
  super
229
229
  end
230
230
  end
231
- ruby2_keywords(:method_missing)
232
231
 
233
232
  # receives an instance variable identifier, set the variable value if is
234
233
  # blank and append given block to value, which will be used later in
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :app do
4
- desc "Update configs and some other initially generated files (or use just update:configs or update:bin)"
5
- task update: [ "update:configs", "update:bin", "update:active_storage", "update:upgrade_guide_info" ]
6
-
7
4
  desc "Apply the template supplied by LOCATION=(/path/to/template) or URL"
8
5
  task template: :environment do
9
6
  template = ENV["LOCATION"]
@@ -34,27 +31,4 @@ namespace :app do
34
31
  end
35
32
  end
36
33
  end
37
-
38
- namespace :update do
39
- require "rails/app_updater"
40
-
41
- # desc "Update config files from your current rails install"
42
- task :configs do
43
- Rails::AppUpdater.invoke_from_app_generator :create_boot_file
44
- Rails::AppUpdater.invoke_from_app_generator :update_config_files
45
- end
46
-
47
- # desc "Add new executables to the application bin/ directory"
48
- task :bin do
49
- Rails::AppUpdater.invoke_from_app_generator :update_bin_files
50
- end
51
-
52
- task :active_storage do
53
- Rails::AppUpdater.invoke_from_app_generator :update_active_storage
54
- end
55
-
56
- task :upgrade_guide_info do
57
- Rails::AppUpdater.invoke_from_app_generator :display_upgrade_guide_info
58
- end
59
- end
60
34
  end
@@ -7,7 +7,7 @@ namespace :tmp do
7
7
  tmp_dirs = [ "tmp/cache",
8
8
  "tmp/sockets",
9
9
  "tmp/pids",
10
- "tmp/cache/assets" ]
10
+ ]
11
11
 
12
12
  tmp_dirs.each { |d| directory d }
13
13
 
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en">
2
+ <html>
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <title><%= @page_title %></title>
@@ -61,14 +61,14 @@
61
61
  <body>
62
62
  <header>
63
63
  <dl>
64
- <% if @email.respond_to?(:smtp_envelope_from) && Array(@email.from) != Array(@email.smtp_envelope_from) %>
64
+ <% if Array(@email.from) != Array(@email.smtp_envelope_from) %>
65
65
  <dt>SMTP-From:</dt>
66
66
  <dd id="smtp_from"><%= @email.smtp_envelope_from %></dd>
67
67
  <% end %>
68
68
 
69
- <% if @email.respond_to?(:smtp_envelope_to) && @email.to != @email.smtp_envelope_to %>
69
+ <% if Set[*@email.to, *@email.cc, *@email.bcc] != Set[*@email.smtp_envelope_to] %>
70
70
  <dt>SMTP-To:</dt>
71
- <dd id="smtp_to"><%= @email.smtp_envelope_to %></dd>
71
+ <dd id="smtp_to"><%= @email.smtp_envelope_to.join(", ") %></dd>
72
72
  <% end %>
73
73
 
74
74
  <dt>From:</dt>
@@ -93,17 +93,21 @@
93
93
  <% end %>
94
94
 
95
95
  <dt>Date:</dt>
96
- <dd id="date"><%= Time.current.rfc2822 %></dd>
96
+ <dd id="date"><%= @email.header['date'] || Time.current.rfc2822 %></dd>
97
97
 
98
98
  <dt>Subject:</dt>
99
99
  <dd><strong id="subject"><%= @email.subject %></strong></dd>
100
100
 
101
- <% unless @email.attachments.nil? || @email.attachments.empty? %>
101
+ <% if @attachments.any? || @inline_attachments.any? %>
102
102
  <dt>Attachments:</dt>
103
103
  <dd>
104
- <% @email.attachments.each do |a| %>
105
- <% filename = a.respond_to?(:original_filename) ? a.original_filename : a.filename %>
106
- <%= link_to filename, "data:application/octet-stream;charset=utf-8;base64,#{Base64.encode64(a.body.to_s)}", download: filename %>
104
+ <% @attachments.each do |filename, attachment| %>
105
+ <%= link_to filename, attachment_url(attachment), download: filename %>
106
+ <% end %>
107
+
108
+ <% if @inline_attachments.any? %>
109
+ (Inline: <% @inline_attachments.each do |filename, attachment| %>
110
+ <%= link_to filename, attachment_url(attachment), download: filename %><% end %>)
107
111
  <% end %>
108
112
  </dd>
109
113
  <% end %>
@@ -1,11 +1,12 @@
1
- <% ruby_on_rails_logo_favicon_data_uri = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIwcHgiIGhlaWdodD0iMzIwcHgiIHZpZXdCb3g9IjAgMCAzMjAgMzIwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPHRpdGxlPkljb248L3RpdGxlPgogICAgPGcgaWQ9Ikljb24iIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJSdWJ5LU9uLVJhaWxzLUxvZ28iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDUuMDAwMDAwLCAyMC4wMDAwMDApIiBmaWxsPSIjRDgxRTAwIj4KICAgICAgICAgICAgPHBhdGggZD0iTTIxLjkzMzA3MDYsMjg1IEwxNjguMTc1NDI2LDI4NSBDMTQ3Ljk0MDg1OCwxNTAuNjkxNzA2IDE5Ni44ODIzODMsNjYuMzE0MjkwMiAzMTUsMzEuODY3NzUzNiBDMzE1LDIxLjc4NTEyODQgMzE1LDMxLjg2Nzc1MzYgMzE1LDIxLjc4NTEyODQgQzE2MS4yNTI4MywyNC45MTE2Mjc4IDYzLjU2Mzg1MzMsMTEyLjY0OTkxOCAyMS45MzMwNzA2LDI4NSBaIiBpZD0iUGF0aCIvPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iUGF0aCIgcG9pbnRzPSI0MC40MDgyNjQzIDE4NS45MTU3MSAxMi43MzI2NDk0IDE3NC40MDE2NjMgLTEuNDIxMDg1NDdlLTE0IDIwNS40NDI3MSAyOS41NzExOTY2IDIxNi42NDcxMTUiLz4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlBhdGgiIHBvaW50cz0iMTgwLjQ3MzEwMiAyNjguMDczNjQzIDIwNC45MzYwMTYgMjc2LjQxMDk2NiAyMDQuOTM2MDE2IDI1NC41MDg2NzMgMTgwLjQ4OTY0NCAyNDQuMzM4MTA3Ii8+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJQYXRoIiBwb2ludHM9IjEwMC41ODk1MTkgOTcuMjI4NzYwNiA3Ni42ODQwMTU2IDc5LjE2ODcwMjEgNTUuMjQ0MDc5MSAxMDAuMTgzMTA1IDgxLjUxNDMyMzkgMTE3LjQzMzcyNSIvPgogICAgICAgICAgICA8cG9seWdvbiBpZD0iUGF0aCIgcG9pbnRzPSIxODQuNTc1Njc5IDE4NC44OTYyOTUgMjA3Ljk1MjAzIDIwMC4yNDY2MSAyMTEuNzI3NzI5IDE4MS4yMDUyNjYgMTg5Ljg2MzY1MyAxNjQuNjg3NDYiLz4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlBhdGgiIHBvaW50cz0iMjYxLjczNDAxIDY1Ljg5NTk0NDYgMjY5LjM1NDIzNCA4Mi4zMjk1NCAyODUuMzE4MjU2IDcyLjcwNDg1OTYgMjc4LjMxMDEyOSA1Ni45ODI5ODk1Ii8+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJQYXRoIiBwb2ludHM9IjI2MS45MTM3IDE2LjE4NDU0NzMgMjU1LjU5ODQ3OSA3LjEwNTQyNzM2ZS0xNSAyMzIuNzk2MDIgMy40ODg5NjMyMyAyNDAuNDYzODczIDIwLjAyNTI3MjUiLz4KICAgICAgICAgICAgPHBvbHlnb24gaWQ9IlBhdGgiIHBvaW50cz0iMjExLjkzNDExOSAxMTEuNTgwNjc1IDIyNi43MjI1NDcgMTI3Ljc5MjYwMSAyMzguMDIzOTI1IDExMy45MDM3MTUgMjIzLjQ2ODM3NSA5Ni41NDY4Njg1Ii8+CiAgICAgICAgICAgIDxwb2x5Z29uIGlkPSJQYXRoIiBwb2ludHM9IjE3OS42ODY4NTggMzguNDk1MjIxOCAxNjQuNjQxOTMxIDIwLjAyNTI3MjUgMTM5Ljg0NzYyIDMyLjU1NTI5OTIgMTU2LjYwMTMyNCA1MC45MjE2NzUzIi8+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4=" %>
2
1
  <!DOCTYPE html>
3
2
  <html>
4
3
  <head>
5
4
  <title>Ruby on Rails <%= Rails.version %></title>
6
5
  <meta charset="utf-8">
7
6
  <meta name="viewport" content="width=device-width">
8
- <link rel="icon" href="<%= ruby_on_rails_logo_favicon_data_uri %>" />
7
+
8
+ <link rel="icon" href="/icon.png" type="image/png">
9
+ <link rel="apple-touch-icon" href="/icon.png" sizes="512x512">
9
10
 
10
11
  <style type="text/css">
11
12
  * {
@@ -7,19 +7,17 @@
7
7
  abort("Abort testing: Your Rails environment is running in production mode!") if Rails.env.production?
8
8
 
9
9
  require "active_support/test_case"
10
- require "action_controller"
11
- require "action_controller/test_case"
12
- require "action_dispatch/testing/integration"
13
10
  require "rails/generators/test_case"
14
-
15
11
  require "active_support/testing/autorun"
16
12
 
17
13
  require "rails/testing/maintain_test_schema"
18
14
 
19
15
  if defined?(ActiveRecord::Base)
16
+ require "active_record/testing/query_assertions"
20
17
  ActiveSupport.on_load(:active_support_test_case) do
21
18
  include ActiveRecord::TestDatabases
22
19
  include ActiveRecord::TestFixtures
20
+ include ActiveRecord::Assertions::QueryAssertions
23
21
 
24
22
  self.fixture_paths << "#{Rails.root}/test/fixtures/"
25
23
  self.file_fixture_path = "#{Rails.root}/test/fixtures/files"
@@ -8,6 +8,13 @@ module Rails
8
8
  class_attribute :app_root
9
9
  class_attribute :executable, default: "bin/rails test"
10
10
 
11
+ def prerecord(test_class, test_name)
12
+ super
13
+ if options[:verbose]
14
+ io.print "%s#%s = " % [test_class.name, test_name]
15
+ end
16
+ end
17
+
11
18
  def record(result)
12
19
  super
13
20
 
@@ -69,8 +76,7 @@ module Rails
69
76
  end
70
77
 
71
78
  def format_line(result)
72
- klass = result.respond_to?(:klass) ? result.klass : result.class
73
- "%s#%s = %.2f s = %s" % [klass, result.name, result.time, result.result_code]
79
+ "%.2f s = %s" % [result.time, result.result_code]
74
80
  end
75
81
 
76
82
  def format_rerun_snippet(result)
@@ -9,6 +9,15 @@ require "rails/test_unit/test_parser"
9
9
 
10
10
  module Rails
11
11
  module TestUnit
12
+ class InvalidTestError < StandardError
13
+ def initialize(path, suggestion)
14
+ super(<<~MESSAGE.squish)
15
+ Could not load test file: #{path}.
16
+ #{suggestion}
17
+ MESSAGE
18
+ end
19
+ end
20
+
12
21
  class Runner
13
22
  TEST_FOLDERS = [:models, :helpers, :channels, :controllers, :mailers, :integration, :jobs, :mailboxes]
14
23
  PATH_ARGUMENT_PATTERN = %r"^(?!/.+/$)[.\w]*[/\\]"
@@ -48,7 +57,17 @@ module Rails
48
57
  def load_tests(argv)
49
58
  patterns = extract_filters(argv)
50
59
  tests = list_tests(patterns)
51
- tests.to_a.each { |path| require File.expand_path(path) }
60
+ tests.to_a.each do |path|
61
+ require File.expand_path(path)
62
+ rescue LoadError => exception
63
+ all_tests = list_tests([default_test_glob])
64
+ corrections = DidYouMean::SpellChecker.new(dictionary: all_tests).correct(path)
65
+
66
+ if corrections.empty?
67
+ raise exception
68
+ end
69
+ raise InvalidTestError.new(path, DidYouMean::Formatter.message_for(corrections))
70
+ end
52
71
  end
53
72
 
54
73
  def compose_filter(runnable, filter)
@@ -87,7 +106,7 @@ module Rails
87
106
  end
88
107
 
89
108
  def default_test_exclude_glob
90
- ENV["DEFAULT_TEST_EXCLUDE"] || "test/{system,dummy}/**/*_test.rb"
109
+ ENV["DEFAULT_TEST_EXCLUDE"] || "test/{system,dummy,fixtures}/**/*_test.rb"
91
110
  end
92
111
 
93
112
  def regexp_filter?(arg)
@@ -1,5 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ begin
4
+ require "prism"
5
+ rescue LoadError
6
+ # If Prism isn't available (because of using an older Ruby version) then we'll
7
+ # define a fallback parser using ripper.
8
+ end
9
+
10
+ if defined?(Prism)
11
+ module Rails
12
+ module TestUnit
13
+ # Parse a test file to extract the line ranges of all tests in both
14
+ # method-style (def test_foo) and declarative-style (test "foo" do)
15
+ module TestParser
16
+ # Helper to translate a method object into the path and line range where
17
+ # the method was defined.
18
+ def self.definition_for(method)
19
+ filepath, start_line = method.source_location
20
+ queue = [Prism.parse_file(filepath).value]
21
+
22
+ while (node = queue.shift)
23
+ case node.type
24
+ when :def_node
25
+ if node.name.start_with?("test") && node.location.start_line == start_line
26
+ return [filepath, start_line..node.location.end_line]
27
+ end
28
+ when :call_node
29
+ if node.name == :test && node.location.start_line == start_line
30
+ return [filepath, start_line..node.location.end_line]
31
+ end
32
+ end
33
+
34
+ queue.concat(node.compact_child_nodes)
35
+ end
36
+
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ # If we have Prism, then we don't need to define the fallback parser using
44
+ # ripper.
45
+ return
46
+ end
47
+
3
48
  require "ripper"
4
49
 
5
50
  module Rails
data/lib/rails.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rails/ruby_version_check"
4
-
5
3
  require "pathname"
6
4
 
7
5
  require "active_support"
@@ -29,12 +27,16 @@ module Rails
29
27
  extend ActiveSupport::Autoload
30
28
  extend ActiveSupport::Benchmarkable
31
29
 
32
- autoload :HealthController
33
30
  autoload :Info
34
31
  autoload :InfoController
35
32
  autoload :MailersController
36
33
  autoload :WelcomeController
37
34
 
35
+ eager_autoload do
36
+ autoload :HealthController
37
+ autoload :PwaController
38
+ end
39
+
38
40
  class << self
39
41
  @application = @app_class = nil
40
42
 
@@ -69,6 +71,7 @@ module Rails
69
71
  # Rails.env # => "development"
70
72
  # Rails.env.development? # => true
71
73
  # Rails.env.production? # => false
74
+ # Rails.env.local? # => true true for "development" and "test", false for anything else
72
75
  def env
73
76
  @_env ||= ActiveSupport::EnvironmentInquirer.new(ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence || "development")
74
77
  end