railties 7.0.8.7 → 7.1.5.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +723 -215
- data/MIT-LICENSE +1 -1
- data/RDOC_MAIN.md +99 -0
- data/README.rdoc +4 -4
- data/lib/minitest/rails_plugin.rb +63 -0
- data/lib/rails/api/task.rb +35 -4
- data/lib/rails/app_updater.rb +14 -2
- data/lib/rails/application/bootstrap.rb +23 -4
- data/lib/rails/application/configuration.rb +190 -69
- data/lib/rails/application/default_middleware_stack.rb +8 -2
- data/lib/rails/application/dummy_config.rb +19 -0
- data/lib/rails/application/finisher.rb +43 -33
- data/lib/rails/application.rb +141 -33
- data/lib/rails/backtrace_cleaner.rb +5 -3
- data/lib/rails/cli.rb +5 -2
- data/lib/rails/command/actions.rb +10 -12
- data/lib/rails/command/base.rb +55 -53
- data/lib/rails/command/environment_argument.rb +32 -16
- data/lib/rails/command/helpers/editor.rb +17 -12
- data/lib/rails/command.rb +84 -33
- data/lib/rails/commands/about/about_command.rb +14 -0
- data/lib/rails/commands/application/application_command.rb +2 -0
- data/lib/rails/commands/console/console_command.rb +14 -14
- data/lib/rails/commands/credentials/USAGE +53 -55
- data/lib/rails/commands/credentials/credentials_command/diffing.rb +5 -3
- data/lib/rails/commands/credentials/credentials_command.rb +64 -70
- data/lib/rails/commands/db/system/change/change_command.rb +2 -1
- data/lib/rails/commands/dbconsole/dbconsole_command.rb +25 -115
- data/lib/rails/commands/destroy/destroy_command.rb +3 -2
- data/lib/rails/commands/dev/dev_command.rb +1 -6
- data/lib/rails/commands/encrypted/USAGE +15 -20
- data/lib/rails/commands/encrypted/encrypted_command.rb +46 -35
- data/lib/rails/commands/gem_help/USAGE +16 -0
- data/lib/rails/commands/gem_help/gem_help_command.rb +13 -0
- data/lib/rails/commands/generate/generate_command.rb +2 -2
- data/lib/rails/commands/help/USAGE +13 -13
- data/lib/rails/commands/help/help_command.rb +21 -2
- data/lib/rails/commands/initializers/initializers_command.rb +1 -4
- data/lib/rails/commands/middleware/middleware_command.rb +17 -0
- data/lib/rails/commands/new/new_command.rb +2 -0
- data/lib/rails/commands/notes/notes_command.rb +2 -1
- data/lib/rails/commands/plugin/plugin_command.rb +2 -0
- data/lib/rails/commands/rake/rake_command.rb +25 -22
- data/lib/rails/commands/restart/restart_command.rb +14 -0
- data/lib/rails/commands/routes/routes_command.rb +13 -1
- data/lib/rails/commands/runner/USAGE +14 -12
- data/lib/rails/commands/runner/runner_command.rb +32 -20
- data/lib/rails/commands/secret/secret_command.rb +13 -0
- data/lib/rails/commands/secrets/USAGE +44 -49
- data/lib/rails/commands/secrets/secrets_command.rb +20 -38
- data/lib/rails/commands/server/server_command.rb +33 -32
- data/lib/rails/commands/test/USAGE +14 -0
- data/lib/rails/commands/test/test_command.rb +56 -14
- data/lib/rails/commands/unused_routes/unused_routes_command.rb +75 -0
- data/lib/rails/commands/version/version_command.rb +1 -0
- data/lib/rails/configuration.rb +5 -5
- data/lib/rails/console/app.rb +1 -4
- data/lib/rails/deprecator.rb +7 -0
- data/lib/rails/engine/configuration.rb +50 -6
- data/lib/rails/engine.rb +49 -21
- data/lib/rails/gem_version.rb +4 -4
- data/lib/rails/generators/actions.rb +6 -15
- data/lib/rails/generators/active_model.rb +28 -14
- data/lib/rails/generators/app_base.rb +355 -82
- data/lib/rails/generators/app_name.rb +3 -14
- data/lib/rails/generators/base.rb +17 -9
- data/lib/rails/generators/database.rb +40 -2
- data/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt +1 -1
- data/lib/rails/generators/generated_attribute.rb +12 -0
- data/lib/rails/generators/migration.rb +4 -5
- data/lib/rails/generators/model_helpers.rb +2 -1
- data/lib/rails/generators/rails/app/USAGE +22 -6
- data/lib/rails/generators/rails/app/app_generator.rb +85 -64
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +103 -0
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +9 -11
- data/lib/rails/generators/rails/app/templates/app/views/layouts/mailer.html.erb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/bin/setup.tt +10 -1
- data/lib/rails/generators/rails/app/templates/config/application.rb.tt +6 -17
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml.tt +4 -4
- data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml.tt +4 -6
- data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/databases/trilogy.yml.tt +59 -0
- data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +12 -2
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +32 -28
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +13 -9
- data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +2 -0
- data/lib/rails/generators/rails/app/templates/config/initializers/content_security_policy.rb.tt +2 -2
- data/lib/rails/generators/rails/app/templates/config/initializers/cors.rb.tt +1 -1
- data/lib/rails/generators/rails/app/templates/config/initializers/filter_parameter_logging.rb.tt +3 -3
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt +280 -0
- data/lib/rails/generators/rails/app/templates/config/initializers/permissions_policy.rb.tt +11 -9
- data/lib/rails/generators/rails/app/templates/config/locales/en.yml +11 -13
- data/lib/rails/generators/rails/app/templates/config/puma.rb.tt +21 -20
- data/lib/rails/generators/rails/app/templates/config/routes.rb.tt +5 -1
- data/lib/rails/generators/rails/app/templates/db/seeds.rb.tt +6 -4
- data/lib/rails/generators/rails/app/templates/docker-entrypoint.tt +10 -0
- data/lib/rails/generators/rails/app/templates/dockerignore.tt +43 -0
- data/lib/rails/generators/rails/app/templates/gitignore.tt +4 -8
- data/lib/rails/generators/rails/app/templates/node-version.tt +1 -0
- data/lib/rails/generators/rails/app/templates/test/channels/application_cable/connection_test.rb.tt +10 -8
- data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +9 -7
- data/lib/rails/generators/rails/application_record/application_record_generator.rb +4 -0
- data/lib/rails/generators/rails/benchmark/benchmark_generator.rb +2 -1
- data/lib/rails/generators/rails/controller/USAGE +12 -4
- data/lib/rails/generators/rails/controller/controller_generator.rb +5 -0
- data/lib/rails/generators/rails/controller/templates/controller.rb.tt +1 -1
- data/lib/rails/generators/rails/credentials/credentials_generator.rb +29 -24
- data/lib/rails/generators/rails/credentials/templates/credentials.yml.tt +8 -0
- data/lib/rails/generators/rails/db/system/change/change_generator.rb +30 -0
- data/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator.rb +1 -2
- data/lib/rails/generators/rails/migration/USAGE +21 -11
- data/lib/rails/generators/rails/model/model_generator.rb +4 -0
- data/lib/rails/generators/rails/plugin/USAGE +17 -6
- data/lib/rails/generators/rails/plugin/plugin_generator.rb +5 -15
- data/lib/rails/generators/rails/plugin/templates/Gemfile.tt +2 -2
- data/lib/rails/generators/rails/plugin/templates/MIT-LICENSE.tt +1 -1
- data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +1 -17
- data/lib/rails/generators/rails/plugin/templates/gitignore.tt +0 -2
- data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb.tt +4 -4
- data/lib/rails/generators/rails/resource/resource_generator.rb +6 -0
- data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +2 -1
- data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +1 -1
- data/lib/rails/generators/test_case.rb +2 -2
- data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +1 -1
- data/lib/rails/generators/testing/{behaviour.rb → behavior.rb} +4 -1
- data/lib/rails/generators.rb +6 -14
- data/lib/rails/health_controller.rb +55 -0
- data/lib/rails/info.rb +1 -1
- data/lib/rails/info_controller.rb +33 -11
- data/lib/rails/mailers_controller.rb +15 -5
- data/lib/rails/paths.rb +13 -10
- data/lib/rails/rack/logger.rb +15 -12
- data/lib/rails/rackup/server.rb +15 -0
- data/lib/rails/railtie/configuration.rb +14 -1
- data/lib/rails/railtie.rb +31 -31
- data/lib/rails/ruby_version_check.rb +2 -0
- data/lib/rails/source_annotation_extractor.rb +67 -18
- data/lib/rails/tasks/engine.rake +8 -8
- data/lib/rails/tasks/framework.rake +4 -10
- data/lib/rails/tasks/log.rake +1 -1
- data/lib/rails/tasks/misc.rake +3 -14
- data/lib/rails/tasks/statistics.rake +5 -4
- data/lib/rails/tasks/tmp.rake +5 -5
- data/lib/rails/tasks/zeitwerk.rake +15 -35
- data/lib/rails/tasks.rb +0 -2
- data/lib/rails/templates/rails/mailers/email.html.erb +32 -0
- data/lib/rails/templates/rails/mailers/index.html.erb +14 -7
- data/lib/rails/templates/rails/mailers/mailer.html.erb +11 -5
- data/lib/rails/templates/rails/welcome/index.html.erb +1 -0
- data/lib/rails/test_help.rb +9 -14
- data/lib/rails/test_unit/line_filtering.rb +1 -1
- data/lib/rails/test_unit/reporter.rb +6 -2
- data/lib/rails/test_unit/runner.rb +36 -18
- data/lib/rails/test_unit/test_parser.rb +88 -0
- data/lib/rails/test_unit/testing.rake +13 -33
- data/lib/rails/testing/maintain_test_schema.rb +16 -0
- data/lib/rails/version.rb +1 -1
- data/lib/rails/zeitwerk_checker.rb +15 -0
- data/lib/rails.rb +15 -15
- metadata +64 -27
- data/RDOC_MAIN.rdoc +0 -97
- data/lib/rails/application/dummy_erb_compiler.rb +0 -18
- data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_0.rb.tt +0 -143
- data/lib/rails/generators/rails/model/USAGE +0 -113
- data/lib/rails/tasks/middleware.rake +0 -9
- data/lib/rails/tasks/restart.rake +0 -9
data/lib/rails/tasks/tmp.rake
CHANGED
@@ -11,32 +11,32 @@ namespace :tmp do
|
|
11
11
|
|
12
12
|
tmp_dirs.each { |d| directory d }
|
13
13
|
|
14
|
-
desc "
|
14
|
+
desc "Create tmp directories for cache, sockets, and pids"
|
15
15
|
task create: tmp_dirs
|
16
16
|
|
17
17
|
namespace :cache do
|
18
|
-
# desc "
|
18
|
+
# desc "Clear all files and directories in tmp/cache"
|
19
19
|
task :clear do
|
20
20
|
rm_rf Dir["tmp/cache/[^.]*"], verbose: false
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
namespace :sockets do
|
25
|
-
# desc "
|
25
|
+
# desc "Clear all files in tmp/sockets"
|
26
26
|
task :clear do
|
27
27
|
rm Dir["tmp/sockets/[^.]*"], verbose: false
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
namespace :pids do
|
32
|
-
# desc "
|
32
|
+
# desc "Clear all files in tmp/pids"
|
33
33
|
task :clear do
|
34
34
|
rm Dir["tmp/pids/[^.]*"], verbose: false
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
namespace :screenshots do
|
39
|
-
# desc "
|
39
|
+
# desc "Clear all files in tmp/screenshots"
|
40
40
|
task :clear do
|
41
41
|
rm Dir["tmp/screenshots/[^.]*"], verbose: false
|
42
42
|
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
puts "Hold on, I am eager loading the application."
|
5
|
-
Zeitwerk::Loader.eager_load_all
|
6
|
-
end
|
3
|
+
require "rails/zeitwerk_checker"
|
7
4
|
|
8
|
-
|
5
|
+
report_unchecked = ->(unchecked) do
|
9
6
|
puts
|
10
7
|
puts <<~EOS
|
11
8
|
WARNING: The following directories will only be checked if you configure
|
@@ -13,7 +10,7 @@ report_not_checked = ->(not_checked) do
|
|
13
10
|
EOS
|
14
11
|
puts
|
15
12
|
|
16
|
-
|
13
|
+
unchecked.each { |dir| puts " #{dir}" }
|
17
14
|
puts
|
18
15
|
|
19
16
|
puts <<~EOS
|
@@ -23,39 +20,22 @@ report_not_checked = ->(not_checked) do
|
|
23
20
|
puts
|
24
21
|
end
|
25
22
|
|
26
|
-
report = ->(not_checked) do
|
27
|
-
if not_checked.any?
|
28
|
-
report_not_checked[not_checked]
|
29
|
-
puts "Otherwise, all is good!"
|
30
|
-
else
|
31
|
-
puts "All is good!"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
23
|
namespace :zeitwerk do
|
36
|
-
desc "
|
24
|
+
desc "Check project structure for Zeitwerk compatibility"
|
37
25
|
task check: :environment do
|
26
|
+
puts "Hold on, I am eager loading the application."
|
27
|
+
|
38
28
|
begin
|
39
|
-
|
40
|
-
rescue NameError => e
|
41
|
-
|
42
|
-
abort $&.sub(/expected file #{Regexp.escape(Rails.root.to_s)}./, "expected file ")
|
43
|
-
else
|
44
|
-
raise
|
45
|
-
end
|
29
|
+
unchecked = Rails::ZeitwerkChecker.check
|
30
|
+
rescue Zeitwerk::NameError => e
|
31
|
+
abort e.message.sub(/#{Regexp.escape(Rails.root.to_s)}./, "")
|
46
32
|
end
|
47
33
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
not_checked = ActiveSupport::Dependencies.autoload_paths - eager_load_paths
|
56
|
-
not_checked.select! { |dir| Dir.exist?(dir) }
|
57
|
-
not_checked.reject! { |dir| Dir.empty?(dir) }
|
58
|
-
|
59
|
-
report[not_checked]
|
34
|
+
if unchecked.empty?
|
35
|
+
puts "All is good!"
|
36
|
+
else
|
37
|
+
report_unchecked[unchecked]
|
38
|
+
puts "Otherwise, all is good!"
|
39
|
+
end
|
60
40
|
end
|
61
41
|
end
|
data/lib/rails/tasks.rb
CHANGED
@@ -44,6 +44,13 @@
|
|
44
44
|
content: "\00a0"; //
|
45
45
|
}
|
46
46
|
|
47
|
+
th {
|
48
|
+
font-weight: inherit;
|
49
|
+
color: #7f7f7f;
|
50
|
+
text-align: right;
|
51
|
+
white-space: nowrap;
|
52
|
+
}
|
53
|
+
|
47
54
|
iframe {
|
48
55
|
border: 0;
|
49
56
|
width: 100%;
|
@@ -80,6 +87,11 @@
|
|
80
87
|
<dd id="cc"><%= @email.header['cc'] %></dd>
|
81
88
|
<% end %>
|
82
89
|
|
90
|
+
<% if @email.bcc %>
|
91
|
+
<dt>BCC:</dt>
|
92
|
+
<dd id="bcc"><%= @email.header['bcc'] %></dd>
|
93
|
+
<% end %>
|
94
|
+
|
83
95
|
<dt>Date:</dt>
|
84
96
|
<dd id="date"><%= Time.current.rfc2822 %></dd>
|
85
97
|
|
@@ -120,6 +132,26 @@
|
|
120
132
|
</select>
|
121
133
|
</dd>
|
122
134
|
<% end %>
|
135
|
+
|
136
|
+
<% unless @email.header_fields.nil? || @email.header_fields.empty? %>
|
137
|
+
<dt>Headers:</dt>
|
138
|
+
<dd>
|
139
|
+
<details>
|
140
|
+
<summary>Show all headers</summary>
|
141
|
+
<table>
|
142
|
+
<% @email.header_fields.each do |field| %>
|
143
|
+
<tr>
|
144
|
+
<th><%= field.name %>:</th>
|
145
|
+
<td><%= field.value %></td>
|
146
|
+
</tr>
|
147
|
+
<% end %>
|
148
|
+
</table>
|
149
|
+
</details>
|
150
|
+
</dd>
|
151
|
+
<% end %>
|
152
|
+
|
153
|
+
<dt>EML File:</dt>
|
154
|
+
<dd><%= link_to "Download", action: :download %></dd>
|
123
155
|
</dl>
|
124
156
|
</header>
|
125
157
|
|
@@ -1,8 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
<%
|
5
|
-
<
|
6
|
-
|
7
|
-
|
1
|
+
<h1><%= @page_title %></h1>
|
2
|
+
|
3
|
+
<% if @previews.any? %>
|
4
|
+
<% @previews.each do |preview| %>
|
5
|
+
<h3><%= link_to preview.preview_name.titleize, url_for(controller: "rails/mailers", action: "preview", path: preview.preview_name) %></h3>
|
6
|
+
<ul>
|
7
|
+
<% preview.emails.each do |email| %>
|
8
|
+
<li><%= link_to email, url_for(controller: "rails/mailers", action: "preview", path: "#{preview.preview_name}/#{email}") %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
<% end %>
|
12
|
+
<% else %>
|
13
|
+
<p>You have not defined any Action Mailer Previews.</p>
|
14
|
+
<p>Read <%= link_to "Action Mailer Basics", "https://guides.rubyonrails.org/action_mailer_basics.html#previewing-emails" %> to learn how to define your first.</p>
|
8
15
|
<% end %>
|
@@ -1,6 +1,12 @@
|
|
1
|
-
<
|
2
|
-
|
3
|
-
<% @preview.emails.
|
4
|
-
<
|
1
|
+
<h1><%= @page_title %></h1>
|
2
|
+
|
3
|
+
<% if @preview.emails.any? %>
|
4
|
+
<ul>
|
5
|
+
<% @preview.emails.each do |email| %>
|
6
|
+
<li><%= link_to email, url_for(controller: "rails/mailers", action: "preview", path: "#{@preview.preview_name}/#{email}") %></li>
|
7
|
+
<% end %>
|
8
|
+
</ul>
|
9
|
+
<% else %>
|
10
|
+
<p>You have not defined any actions for <%= @preview %>.</p>
|
11
|
+
<p>Read <%= link_to "Action Mailer Basics", "https://guides.rubyonrails.org/action_mailer_basics.html#previewing-emails" %> to learn how to define your first.</p>
|
5
12
|
<% end %>
|
6
|
-
</ul>
|
data/lib/rails/test_help.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :enddoc:
|
4
|
+
|
3
5
|
# Make double-sure the RAILS_ENV is not set to production,
|
4
6
|
# so fixtures aren't loaded into that environment
|
5
7
|
abort("Abort testing: Your Rails environment is running in production mode!") if Rails.env.production?
|
@@ -12,24 +14,19 @@ require "rails/generators/test_case"
|
|
12
14
|
|
13
15
|
require "active_support/testing/autorun"
|
14
16
|
|
15
|
-
|
16
|
-
begin
|
17
|
-
ActiveRecord::Migration.maintain_test_schema!
|
18
|
-
rescue ActiveRecord::PendingMigrationError => e
|
19
|
-
puts e.to_s.strip
|
20
|
-
exit 1
|
21
|
-
end
|
17
|
+
require "rails/testing/maintain_test_schema"
|
22
18
|
|
19
|
+
if defined?(ActiveRecord::Base)
|
23
20
|
ActiveSupport.on_load(:active_support_test_case) do
|
24
21
|
include ActiveRecord::TestDatabases
|
25
22
|
include ActiveRecord::TestFixtures
|
26
23
|
|
27
|
-
self.
|
28
|
-
self.file_fixture_path =
|
24
|
+
self.fixture_paths << "#{Rails.root}/test/fixtures/"
|
25
|
+
self.file_fixture_path = "#{Rails.root}/test/fixtures/files"
|
29
26
|
end
|
30
27
|
|
31
28
|
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
32
|
-
self.
|
29
|
+
self.fixture_paths += ActiveSupport::TestCase.fixture_paths
|
33
30
|
end
|
34
31
|
else
|
35
32
|
ActiveSupport.on_load(:active_support_test_case) do
|
@@ -37,17 +34,15 @@ else
|
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
40
|
-
# :enddoc:
|
41
|
-
|
42
37
|
ActiveSupport.on_load(:action_controller_test_case) do
|
43
|
-
def before_setup
|
38
|
+
def before_setup
|
44
39
|
@routes = Rails.application.routes
|
45
40
|
super
|
46
41
|
end
|
47
42
|
end
|
48
43
|
|
49
44
|
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
50
|
-
def before_setup
|
45
|
+
def before_setup
|
51
46
|
@routes = Rails.application.routes
|
52
47
|
super
|
53
48
|
end
|
@@ -5,7 +5,7 @@ require "rails/test_unit/runner"
|
|
5
5
|
module Rails
|
6
6
|
module LineFiltering # :nodoc:
|
7
7
|
def run(reporter, options = {})
|
8
|
-
options
|
8
|
+
options = options.merge(filter: Rails::TestUnit::Runner.compose_filter(self, options[:filter]))
|
9
9
|
|
10
10
|
super
|
11
11
|
end
|
@@ -6,7 +6,7 @@ require "minitest"
|
|
6
6
|
module Rails
|
7
7
|
class TestUnitReporter < Minitest::StatisticsReporter
|
8
8
|
class_attribute :app_root
|
9
|
-
class_attribute :executable, default: "rails test"
|
9
|
+
class_attribute :executable, default: "bin/rails test"
|
10
10
|
|
11
11
|
def record(result)
|
12
12
|
super
|
@@ -52,7 +52,11 @@ module Rails
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def relative_path_for(file)
|
55
|
-
|
55
|
+
if app_root
|
56
|
+
file.sub(/^#{app_root}\/?/, "")
|
57
|
+
else
|
58
|
+
file
|
59
|
+
end
|
56
60
|
end
|
57
61
|
|
58
62
|
private
|
@@ -1,14 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "shellwords"
|
4
|
-
require "method_source"
|
5
4
|
require "rake/file_list"
|
6
5
|
require "active_support"
|
7
6
|
require "active_support/core_ext/module/attribute_accessors"
|
7
|
+
require "active_support/core_ext/range"
|
8
|
+
require "rails/test_unit/test_parser"
|
8
9
|
|
9
10
|
module Rails
|
10
11
|
module TestUnit
|
11
12
|
class Runner
|
13
|
+
TEST_FOLDERS = [:models, :helpers, :channels, :controllers, :mailers, :integration, :jobs, :mailboxes]
|
14
|
+
PATH_ARGUMENT_PATTERN = %r"^(?!/.+/$)[.\w]*[/\\]"
|
12
15
|
mattr_reader :filters, default: []
|
13
16
|
|
14
17
|
class << self
|
@@ -30,9 +33,9 @@ module Rails
|
|
30
33
|
$VERBOSE = argv.delete_at(w_index) if w_index
|
31
34
|
end
|
32
35
|
|
33
|
-
def
|
36
|
+
def run_from_rake(test_command, argv = [])
|
34
37
|
# Ensure the tests run during the Rake Task action, not when the process exits
|
35
|
-
success = system("rails",
|
38
|
+
success = system("rails", test_command, *argv, *Shellwords.split(ENV["TESTOPTS"] || ""))
|
36
39
|
success || exit(false)
|
37
40
|
end
|
38
41
|
|
@@ -43,11 +46,14 @@ module Rails
|
|
43
46
|
end
|
44
47
|
|
45
48
|
def load_tests(argv)
|
46
|
-
|
49
|
+
patterns = extract_filters(argv)
|
50
|
+
tests = list_tests(patterns)
|
47
51
|
tests.to_a.each { |path| require File.expand_path(path) }
|
48
52
|
end
|
49
53
|
|
50
54
|
def compose_filter(runnable, filter)
|
55
|
+
filter = normalize_declarative_test_filter(filter)
|
56
|
+
|
51
57
|
if filters.any? { |_, lines| lines.any? }
|
52
58
|
CompositeFilter.new(runnable, filter, filters)
|
53
59
|
else
|
@@ -59,11 +65,11 @@ module Rails
|
|
59
65
|
def extract_filters(argv)
|
60
66
|
# Extract absolute and relative paths but skip -n /.*/ regexp filters.
|
61
67
|
argv.filter_map do |path|
|
62
|
-
next unless path_argument?(path)
|
68
|
+
next unless path_argument?(path)
|
63
69
|
|
64
70
|
path = path.tr("\\", "/")
|
65
71
|
case
|
66
|
-
when /(:\d+)+$/.match?(path)
|
72
|
+
when /(:\d+(-\d+)?)+$/.match?(path)
|
67
73
|
file, *lines = path.split(":")
|
68
74
|
filters << [ file, lines ]
|
69
75
|
file
|
@@ -89,16 +95,27 @@ module Rails
|
|
89
95
|
end
|
90
96
|
|
91
97
|
def path_argument?(arg)
|
92
|
-
|
98
|
+
PATH_ARGUMENT_PATTERN.match?(arg)
|
93
99
|
end
|
94
100
|
|
95
|
-
def list_tests(
|
96
|
-
patterns = extract_filters(argv)
|
97
|
-
|
101
|
+
def list_tests(patterns)
|
98
102
|
tests = Rake::FileList[patterns.any? ? patterns : default_test_glob]
|
99
103
|
tests.exclude(default_test_exclude_glob) if patterns.empty?
|
100
104
|
tests
|
101
105
|
end
|
106
|
+
|
107
|
+
def normalize_declarative_test_filter(filter)
|
108
|
+
if filter.is_a?(String)
|
109
|
+
if regexp_filter?(filter)
|
110
|
+
# Minitest::Spec::DSL#it does not replace whitespace in method
|
111
|
+
# names, so match unmodified method names as well.
|
112
|
+
filter = filter.gsub(/\s+/, "_").delete_suffix("/") + "|" + filter.delete_prefix("/")
|
113
|
+
elsif !filter.start_with?("test_")
|
114
|
+
filter = "test_#{filter.gsub(/\s+/, "_")}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
filter
|
118
|
+
end
|
102
119
|
end
|
103
120
|
end
|
104
121
|
|
@@ -139,17 +156,21 @@ module Rails
|
|
139
156
|
end
|
140
157
|
|
141
158
|
class Filter # :nodoc:
|
142
|
-
def initialize(runnable, file,
|
159
|
+
def initialize(runnable, file, line_or_range)
|
143
160
|
@runnable, @file = runnable, File.expand_path(file)
|
144
|
-
|
161
|
+
if line_or_range
|
162
|
+
first, last = line_or_range.split("-").map(&:to_i)
|
163
|
+
last ||= first
|
164
|
+
@line_range = Range.new(first, last)
|
165
|
+
end
|
145
166
|
end
|
146
167
|
|
147
168
|
def ===(method)
|
148
169
|
return unless @runnable.method_defined?(method)
|
149
170
|
|
150
|
-
if @
|
171
|
+
if @line_range
|
151
172
|
test_file, test_range = definition_for(@runnable.instance_method(method))
|
152
|
-
test_file == @file &&
|
173
|
+
test_file == @file && @line_range.overlaps?(test_range)
|
153
174
|
else
|
154
175
|
@runnable.instance_method(method).source_location.first == @file
|
155
176
|
end
|
@@ -157,10 +178,7 @@ module Rails
|
|
157
178
|
|
158
179
|
private
|
159
180
|
def definition_for(method)
|
160
|
-
|
161
|
-
end_line = method.source.count("\n") + start_line - 1
|
162
|
-
|
163
|
-
return file, start_line..end_line
|
181
|
+
TestParser.definition_for(method)
|
164
182
|
end
|
165
183
|
end
|
166
184
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ripper"
|
4
|
+
|
5
|
+
module Rails
|
6
|
+
module TestUnit
|
7
|
+
# Parse a test file to extract the line ranges of all tests in both
|
8
|
+
# method-style (def test_foo) and declarative-style (test "foo" do)
|
9
|
+
class TestParser < Ripper # :nodoc:
|
10
|
+
# Helper to translate a method object into the path and line range where
|
11
|
+
# the method was defined.
|
12
|
+
def self.definition_for(method_obj)
|
13
|
+
path, begin_line = method_obj.source_location
|
14
|
+
begins_to_ends = new(File.read(path), path).parse
|
15
|
+
return unless end_line = begins_to_ends[begin_line]
|
16
|
+
[path, (begin_line..end_line)]
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(*)
|
20
|
+
# A hash mapping the 1-indexed line numbers that tests start on to where they end.
|
21
|
+
@begins_to_ends = {}
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse
|
26
|
+
super
|
27
|
+
@begins_to_ends
|
28
|
+
end
|
29
|
+
|
30
|
+
# method test e.g. `def test_some_description`
|
31
|
+
# This event's first argument gets the `ident` node containing the method
|
32
|
+
# name, which we have overridden to return the line number of the ident
|
33
|
+
# instead.
|
34
|
+
def on_def(begin_line, *)
|
35
|
+
@begins_to_ends[begin_line] = lineno
|
36
|
+
end
|
37
|
+
|
38
|
+
# Everything past this point is to support declarative tests, which
|
39
|
+
# require more work to get right because of the many different ways
|
40
|
+
# methods can be invoked in ruby, all of which are parsed differently.
|
41
|
+
#
|
42
|
+
# The approach is just to store the current line number when the
|
43
|
+
# "test" method is called and pass it up the tree so it's available at
|
44
|
+
# the point when we also know the line where the associated block ends.
|
45
|
+
|
46
|
+
def on_method_add_block(begin_line, end_line)
|
47
|
+
if begin_line && end_line
|
48
|
+
@begins_to_ends[begin_line] = end_line
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def on_command_call(*, begin_lineno, _args)
|
53
|
+
begin_lineno
|
54
|
+
end
|
55
|
+
|
56
|
+
def first_arg(arg, *)
|
57
|
+
arg
|
58
|
+
end
|
59
|
+
|
60
|
+
def just_lineno(*)
|
61
|
+
lineno
|
62
|
+
end
|
63
|
+
|
64
|
+
alias on_method_add_arg first_arg
|
65
|
+
alias on_command first_arg
|
66
|
+
alias on_stmts_add first_arg
|
67
|
+
alias on_arg_paren first_arg
|
68
|
+
alias on_bodystmt first_arg
|
69
|
+
|
70
|
+
alias on_ident just_lineno
|
71
|
+
alias on_do_block just_lineno
|
72
|
+
alias on_stmts_new just_lineno
|
73
|
+
alias on_brace_block just_lineno
|
74
|
+
|
75
|
+
def on_args_new
|
76
|
+
[]
|
77
|
+
end
|
78
|
+
|
79
|
+
def on_args_add(parts, part)
|
80
|
+
parts << part
|
81
|
+
end
|
82
|
+
|
83
|
+
def on_args_add_block(args, *rest)
|
84
|
+
args.first
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,18 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
gem "minitest"
|
4
3
|
require "minitest"
|
5
4
|
require "rails/test_unit/runner"
|
6
5
|
|
7
6
|
task default: :test
|
8
7
|
|
9
|
-
desc "
|
8
|
+
desc "Run all tests in test folder except system ones"
|
10
9
|
task :test do
|
11
|
-
|
12
|
-
Rails::TestUnit::Runner.rake_run([ENV["TEST"]])
|
13
|
-
else
|
14
|
-
Rails::TestUnit::Runner.rake_run
|
15
|
-
end
|
10
|
+
Rails::TestUnit::Runner.run_from_rake("test", Array(ENV["TEST"]))
|
16
11
|
end
|
17
12
|
|
18
13
|
namespace :test do
|
@@ -23,37 +18,22 @@ namespace :test do
|
|
23
18
|
|
24
19
|
task run: %w[test]
|
25
20
|
|
26
|
-
desc "
|
21
|
+
desc "Reset the database and run `bin/rails test`"
|
27
22
|
task :db do
|
28
23
|
success = system({ "RAILS_ENV" => ENV.fetch("RAILS_ENV", "test") }, "rake", "db:test:prepare", "test")
|
29
24
|
success || exit(false)
|
30
25
|
end
|
31
26
|
|
32
|
-
[
|
33
|
-
|
34
|
-
|
27
|
+
[
|
28
|
+
*Rails::TestUnit::Runner::TEST_FOLDERS,
|
29
|
+
:all,
|
30
|
+
:generators,
|
31
|
+
:units,
|
32
|
+
:functionals,
|
33
|
+
:system,
|
34
|
+
].each do |name|
|
35
|
+
task name do
|
36
|
+
Rails::TestUnit::Runner.run_from_rake("test:#{name}")
|
35
37
|
end
|
36
38
|
end
|
37
|
-
|
38
|
-
desc "Runs all tests, including system tests"
|
39
|
-
task all: "test:prepare" do
|
40
|
-
Rails::TestUnit::Runner.rake_run(["test/**/*_test.rb"])
|
41
|
-
end
|
42
|
-
|
43
|
-
task generators: "test:prepare" do
|
44
|
-
Rails::TestUnit::Runner.rake_run(["test/lib/generators"])
|
45
|
-
end
|
46
|
-
|
47
|
-
task units: "test:prepare" do
|
48
|
-
Rails::TestUnit::Runner.rake_run(["test/models", "test/helpers", "test/unit"])
|
49
|
-
end
|
50
|
-
|
51
|
-
task functionals: "test:prepare" do
|
52
|
-
Rails::TestUnit::Runner.rake_run(["test/controllers", "test/mailers", "test/functional"])
|
53
|
-
end
|
54
|
-
|
55
|
-
desc "Run system tests only"
|
56
|
-
task system: "test:prepare" do
|
57
|
-
Rails::TestUnit::Runner.rake_run(["test/system"])
|
58
|
-
end
|
59
39
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
if defined?(ActiveRecord::Base)
|
4
|
+
begin
|
5
|
+
ActiveRecord::Migration.maintain_test_schema!
|
6
|
+
rescue ActiveRecord::PendingMigrationError => e
|
7
|
+
puts e.to_s.strip
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
|
11
|
+
if Rails.configuration.eager_load
|
12
|
+
ActiveRecord::Base.descendants.each do |model|
|
13
|
+
model.load_schema if !model.abstract_class? && model.table_exists?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/rails/version.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# The actual (private) implementation of the Rake task zeitwerk:check.
|
4
|
+
class Rails::ZeitwerkChecker # :nodoc:
|
5
|
+
def self.check
|
6
|
+
Zeitwerk::Loader.eager_load_all
|
7
|
+
|
8
|
+
autoloaded = ActiveSupport::Dependencies.autoload_paths + ActiveSupport::Dependencies.autoload_once_paths
|
9
|
+
eager_loaded = ActiveSupport::Dependencies._eager_load_paths.to_a
|
10
|
+
|
11
|
+
unchecked = autoloaded - eager_loaded
|
12
|
+
unchecked.select! { |dir| Dir.exist?(dir) && !Dir.empty?(dir) }
|
13
|
+
unchecked
|
14
|
+
end
|
15
|
+
end
|