railties 7.0.4 → 7.1.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +729 -174
- data/MIT-LICENSE +1 -1
- data/RDOC_MAIN.md +99 -0
- data/README.rdoc +5 -5
- data/lib/minitest/rails_plugin.rb +63 -0
- data/lib/rails/api/task.rb +35 -4
- data/lib/rails/app_updater.rb +1 -1
- data/lib/rails/application/bootstrap.rb +23 -4
- data/lib/rails/application/configuration.rb +190 -70
- 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 +159 -59
- data/lib/rails/application_controller.rb +1 -1
- data/lib/rails/backtrace_cleaner.rb +1 -1
- 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 +17 -13
- 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 +178 -59
- 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 +39 -1
- 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 +1 -2
- 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 +83 -62
- data/lib/rails/generators/rails/app/templates/Dockerfile.tt +103 -0
- data/lib/rails/generators/rails/app/templates/Gemfile.tt +10 -10
- 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 +11 -1
- data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +31 -27
- data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +12 -8
- 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 +284 -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 +11 -19
- 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 +4 -13
- data/lib/rails/generators/rails/plugin/templates/%name%.gemspec.tt +2 -2
- 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 -15
- 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/rails/scaffold_controller/templates/controller.rb.tt +2 -2
- 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} +5 -2
- 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 +31 -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 +18 -18
- data/lib/rails/ruby_version_check.rb +2 -0
- data/lib/rails/secrets.rb +10 -8
- 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 +13 -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 +66 -29
- 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 -135
- 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
@@ -26,12 +26,13 @@ STATS_DIRECTORIES ||= [
|
|
26
26
|
%w(Channel\ tests test/channels),
|
27
27
|
%w(Integration\ tests test/integration),
|
28
28
|
%w(System\ tests test/system),
|
29
|
-
]
|
30
|
-
[ name, "#{File.dirname(Rake.application.rakefile_location)}/#{dir}" ]
|
31
|
-
end.select { |name, dir| File.directory?(dir) }
|
29
|
+
]
|
32
30
|
|
33
31
|
desc "Report code statistics (KLOCs, etc) from the application or engine"
|
34
32
|
task :stats do
|
35
33
|
require "rails/code_statistics"
|
36
|
-
|
34
|
+
stat_directories = STATS_DIRECTORIES.collect do |name, dir|
|
35
|
+
[ name, "#{File.dirname(Rake.application.rakefile_location)}/#{dir}" ]
|
36
|
+
end.select { |name, dir| File.directory?(dir) }
|
37
|
+
CodeStatistics.new(*stat_directories).to_s
|
37
38
|
end
|
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,38 +14,35 @@ 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
|
30
|
+
end
|
31
|
+
else
|
32
|
+
ActiveSupport.on_load(:active_support_test_case) do
|
33
|
+
self.file_fixture_path = "#{Rails.root}/test/fixtures/files"
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
# :enddoc:
|
37
|
-
|
38
37
|
ActiveSupport.on_load(:action_controller_test_case) do
|
39
|
-
def before_setup
|
38
|
+
def before_setup
|
40
39
|
@routes = Rails.application.routes
|
41
40
|
super
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
44
|
ActiveSupport.on_load(:action_dispatch_integration_test) do
|
46
|
-
def before_setup
|
45
|
+
def before_setup
|
47
46
|
@routes = Rails.application.routes
|
48
47
|
super
|
49
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
|