aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md10
-rw-r--r--railties/lib/rails/app_updater.rb3
-rw-r--r--railties/lib/rails/command/spellchecker.rb51
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb12
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile.tt2
-rw-r--r--railties/lib/rails/tasks/framework.rake2
-rw-r--r--railties/lib/rails/templates/rails/mailers/email.html.erb17
-rw-r--r--railties/railties.gemspec2
-rw-r--r--railties/test/application/assets_test.rb2
-rw-r--r--railties/test/application/configuration_test.rb17
-rw-r--r--railties/test/application/paths_test.rb2
-rw-r--r--railties/test/application/rake/migrations_test.rb2
-rw-r--r--railties/test/application/server_test.rb2
-rw-r--r--railties/test/generators/actions_test.rb2
-rw-r--r--railties/test/generators/app_generator_test.rb141
-rw-r--r--railties/test/generators/scaffold_generator_test.rb4
16 files changed, 192 insertions, 79 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index a4d4a87a8b..83a57a8c6a 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,13 @@
+* Don't generate unused files in `app:update` task
+
+ Skip the assets' initializer when sprockets isn't loaded.
+
+ Skip `config/spring.rb` when spring isn't loaded.
+
+ Skip yarn's contents when yarn integration isn't used.
+
+ *Tsukuru Tanimichi*
+
* Make the master.key file read-only for the owner upon generation on
POSIX-compliant systems.
diff --git a/railties/lib/rails/app_updater.rb b/railties/lib/rails/app_updater.rb
index a076d082d5..a243968a39 100644
--- a/railties/lib/rails/app_updater.rb
+++ b/railties/lib/rails/app_updater.rb
@@ -21,12 +21,15 @@ module Rails
private
def generator_options
options = { api: !!Rails.application.config.api_only, update: true }
+ options[:skip_yarn] = !File.exist?(Rails.root.join("bin", "yarn"))
options[:skip_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[:skip_bootsnap] = !defined?(Bootsnap)
+ options[:skip_spring] = !defined?(Spring)
options
end
end
diff --git a/railties/lib/rails/command/spellchecker.rb b/railties/lib/rails/command/spellchecker.rb
index 154358cd45..04485097fa 100644
--- a/railties/lib/rails/command/spellchecker.rb
+++ b/railties/lib/rails/command/spellchecker.rb
@@ -3,8 +3,55 @@
module Rails
module Command
module Spellchecker # :nodoc:
- def self.suggest(word, from:)
- DidYouMean::SpellChecker.new(dictionary: from.map(&:to_s)).correct(word).first
+ class << self
+ def suggest(word, from:)
+ if defined?(DidYouMean::SpellChecker)
+ DidYouMean::SpellChecker.new(dictionary: from.map(&:to_s)).correct(word).first
+ else
+ from.sort_by { |w| levenshtein_distance(word, w) }.first
+ end
+ 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
end
end
end
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 395ac7ef2f..34067240d7 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -95,11 +95,9 @@ module Rails
end
def bin_when_updating
- bin_yarn_exist = File.exist?("bin/yarn")
-
bin
- if options[:api] && !bin_yarn_exist
+ if options[:skip_yarn]
remove_file "bin/yarn"
end
end
@@ -146,6 +144,10 @@ module Rails
template "config/storage.yml"
end
+ if options[:skip_sprockets] && !assets_config_exist
+ remove_file "config/initializers/assets.rb"
+ end
+
unless rack_cors_config_exist
remove_file "config/initializers/cors.rb"
end
@@ -155,10 +157,6 @@ module Rails
remove_file "config/initializers/cookies_serializer.rb"
end
- unless assets_config_exist
- remove_file "config/initializers/assets.rb"
- end
-
unless csp_config_exist
remove_file "config/initializers/content_security_policy.rb"
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
index 5e7455cdc7..1567333023 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile.tt
@@ -23,7 +23,7 @@ ruby <%= "'#{RUBY_VERSION}'" -%>
<% unless skip_active_storage? -%>
# Use ActiveStorage variant
-# gem 'mini_magick', '~> 4.8'
+# gem 'image_processing', '~> 1.2'
<% end -%>
# Use Capistrano for deployment
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 7dfcd14bd0..1a3711c446 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -40,7 +40,7 @@ namespace :app do
namespace :update do
require "rails/app_updater"
- # desc "Update config/boot.rb from your current rails install"
+ # desc "Update config files from your current rails install"
task :configs do
Rails::AppUpdater.invoke_from_app_generator :create_boot_file
Rails::AppUpdater.invoke_from_app_generator :update_config_files
diff --git a/railties/lib/rails/templates/rails/mailers/email.html.erb b/railties/lib/rails/templates/rails/mailers/email.html.erb
index 2a41c29602..e46364ba8a 100644
--- a/railties/lib/rails/templates/rails/mailers/email.html.erb
+++ b/railties/lib/rails/templates/rails/mailers/email.html.erb
@@ -98,7 +98,7 @@
<dt>Format:</dt>
<% if @email.multipart? %>
<dd>
- <select id="part" onchange="refreshBody();">
+ <select id="part" onchange="refreshBody(false);">
<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>
@@ -110,7 +110,7 @@
<% if I18n.available_locales.count > 1 %>
<dt>Locale:</dt>
<dd>
- <select id="locale" onchange="refreshBody();">
+ <select id="locale" onchange="refreshBody(true);">
<% I18n.available_locales.each do |locale| %>
<option <%= I18n.locale == locale ? 'selected' : '' %> value="<%= locale_query(locale) %>"><%= locale %></option>
<% end %>
@@ -130,7 +130,7 @@
<% end %>
<script>
- function refreshBody() {
+ function refreshBody(reload) {
var part_select = document.querySelector('select#part');
var locale_select = document.querySelector('select#locale');
var iframe = document.getElementsByName('messageBody')[0];
@@ -146,10 +146,13 @@
}
iframe.contentWindow.location = fresh_location;
- if (history.replaceState) {
- 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);
+ 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);
+
+ if (reload) {
+ location.href = state_to_replace;
+ } else if (history.replaceState) {
window.history.replaceState({}, '', state_to_replace);
}
}
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index 1df8b1fe39..6fdb4648c2 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
s.add_dependency "actionpack", version
s.add_dependency "rake", ">= 0.8.7"
- s.add_dependency "thor", ">= 0.18.1", "< 2.0"
+ s.add_dependency "thor", ">= 0.19.0", "< 2.0"
s.add_dependency "method_source"
s.add_development_dependency "actionview", version
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 9ef123c5b6..4ca6d02b85 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -47,7 +47,7 @@ module ApplicationTests
end
def assert_no_file_exists(filename)
- assert !File.exist?(filename), "#{filename} does exist"
+ assert_not File.exist?(filename), "#{filename} does exist"
end
test "assets routes have higher priority" do
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 84606d3b90..c2699006f6 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -1979,6 +1979,23 @@ module ApplicationTests
assert_equal true, ActionView::Helpers::FormTagHelper.default_enforce_utf8
end
+ test "ActionView::Template.finalize_compiled_template_methods is true by default" do
+ app "test"
+ assert_equal true, ActionView::Template.finalize_compiled_template_methods
+ end
+
+ test "ActionView::Template.finalize_compiled_template_methods can be configured via config.action_view.finalize_compiled_template_methods" do
+ app_file "config/environments/test.rb", <<-RUBY
+ Rails.application.configure do
+ config.action_view.finalize_compiled_template_methods = false
+ end
+ RUBY
+
+ app "test"
+
+ assert_equal false, ActionView::Template.finalize_compiled_template_methods
+ 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/paths_test.rb b/railties/test/application/paths_test.rb
index 0abc5cc9aa..28a9206daa 100644
--- a/railties/test/application/paths_test.rb
+++ b/railties/test/application/paths_test.rb
@@ -37,7 +37,7 @@ module ApplicationTests
end
def assert_not_in_load_path(*path)
- assert !$:.any? { |p| File.expand_path(p) == root(*path) }, "Load path includes '#{root(*path)}'. They are:\n-----\n #{$:.join("\n")}\n-----"
+ assert_not $:.any? { |p| File.expand_path(p) == root(*path) }, "Load path includes '#{root(*path)}'. They are:\n-----\n #{$:.join("\n")}\n-----"
end
test "booting up Rails yields a valid paths object" do
diff --git a/railties/test/application/rake/migrations_test.rb b/railties/test/application/rake/migrations_test.rb
index bf5b07afbd..47c5ac105a 100644
--- a/railties/test/application/rake/migrations_test.rb
+++ b/railties/test/application/rake/migrations_test.rb
@@ -417,7 +417,7 @@ module ApplicationTests
version = output =~ %r{[^/]+db/migrate/(\d+)_create_authors\.rb} && $1
rails "db:migrate", "db:rollback", "db:forward", "db:migrate:up", "db:migrate:down", "VERSION=#{version}"
- assert !File.exist?("db/schema.rb"), "should not dump schema when configured not to"
+ assert_not File.exist?("db/schema.rb"), "should not dump schema when configured not to"
end
add_to_config("config.active_record.dump_schema_after_migration = true")
diff --git a/railties/test/application/server_test.rb b/railties/test/application/server_test.rb
index f3a7e00a4d..92b991dd05 100644
--- a/railties/test/application/server_test.rb
+++ b/railties/test/application/server_test.rb
@@ -36,7 +36,7 @@ module ApplicationTests
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 "ENV['BUNDLE_GEMFILE'] = '#{Bundler.default_gemfile}'"
f.puts "require 'bundler/setup'"
end
diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb
index f421207025..a54a6dbc28 100644
--- a/railties/test/generators/actions_test.rb
+++ b/railties/test/generators/actions_test.rb
@@ -403,7 +403,7 @@ class ActionsTest < Rails::Generators::TestCase
content.gsub!(/^ \#.*\n/, "")
content.gsub!(/^\n/, "")
- File.open(route_path, "wb") { |file| file.write(content) }
+ File.write(route_path, content)
routes = <<-F
Rails.application.routes.draw do
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index d6b98eb4d5..3cb7d66bbb 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -296,6 +296,51 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_app_update_does_not_generate_yarn_contents_when_bin_yarn_is_not_used
+ app_root = File.join(destination_root, "myapp")
+ run_generator [app_root, "--skip-yarn"]
+
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_yarn: true }, { destination_root: app_root, shell: @shell }
+ generator.send(:app_const)
+ quietly { generator.send(:update_bin_files) }
+
+ assert_no_file "#{app_root}/bin/yarn"
+
+ assert_file "#{app_root}/bin/setup" do |content|
+ assert_no_match(/system\('bin\/yarn'\)/, content)
+ end
+
+ assert_file "#{app_root}/bin/update" do |content|
+ assert_no_match(/system\('bin\/yarn'\)/, content)
+ end
+ end
+ end
+
+ def test_app_update_does_not_generate_assets_initializer_when_skip_sprockets_is_given
+ app_root = File.join(destination_root, "myapp")
+ run_generator [app_root, "--skip-sprockets"]
+
+ stub_rails_application(app_root) do
+ generator = Rails::Generators::AppGenerator.new ["rails"], { update: true, skip_sprockets: true }, { destination_root: app_root, shell: @shell }
+ generator.send(:app_const)
+ quietly { generator.send(:update_config_files) }
+
+ assert_no_file "#{app_root}/config/initializers/assets.rb"
+ end
+ end
+
+ def test_app_update_does_not_generate_spring_contents_when_skip_spring_is_given
+ app_root = File.join(destination_root, "myapp")
+ run_generator [app_root, "--skip-spring"]
+
+ FileUtils.cd(app_root) do
+ quietly { system("bin/rails app:update") }
+ end
+
+ assert_no_file "#{app_root}/config/spring.rb"
+ end
+
def test_app_update_does_not_generate_action_cable_contents_when_skip_action_cable_is_given
app_root = File.join(destination_root, "myapp")
run_generator [app_root, "--skip-action-cable"]
@@ -310,18 +355,28 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
- def test_active_storage_mini_magick_gem
+ def test_app_update_does_not_generate_bootsnap_contents_when_skip_bootsnap_is_given
+ app_root = File.join(destination_root, "myapp")
+ run_generator [app_root, "--skip-bootsnap"]
+
+ FileUtils.cd(app_root) do
+ quietly { system("bin/rails app:update") }
+ end
+
+ assert_file "#{app_root}/config/boot.rb" do |content|
+ assert_no_match(/require 'bootsnap\/setup'/, content)
+ end
+ end
+
+ def test_gem_for_active_storage
run_generator
- assert_file "Gemfile", /^# gem 'mini_magick'/
+ assert_file "Gemfile", /^# gem 'image_processing'/
end
- def test_mini_magick_gem_when_skip_active_storage_is_given
- app_root = File.join(destination_root, "myapp")
- run_generator [app_root, "--skip-active-storage"]
+ def test_gem_for_active_storage_when_skip_active_storage_is_given
+ run_generator [destination_root, "--skip-active-storage"]
- assert_file "#{app_root}/Gemfile" do |content|
- assert_no_match(/gem 'mini_magick'/, content)
- end
+ assert_no_gem "image_processing"
end
def test_app_update_does_not_generate_active_storage_contents_when_skip_active_storage_is_given
@@ -474,9 +529,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
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
@@ -496,22 +549,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)
- assert_no_match(/chromedriver-helper/, 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)
- assert_no_match(/chromedriver-helper/, content)
- end
+ assert_no_gem "capybara"
+ assert_no_gem "selenium-webdriver"
+ assert_no_gem "chromedriver-helper"
assert_directory("test")
@@ -557,10 +606,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)
@@ -584,9 +631,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
@@ -737,9 +782,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
@@ -747,17 +790,13 @@ 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)
- end
+ assert_no_gem "spring"
end
def test_webpack_option
@@ -802,9 +841,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
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
@@ -822,9 +859,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_match(/require 'bootsnap\/setup'/, content)
end
else
- assert_file "Gemfile" do |content|
- assert_no_match(/bootsnap/, content)
- end
+ assert_no_gem "bootsnap"
assert_file "config/boot.rb" do |content|
assert_no_match(/require 'bootsnap\/setup'/, content)
end
@@ -834,9 +869,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_skip_bootsnap
run_generator [destination_root, "--skip-bootsnap"]
- assert_file "Gemfile" do |content|
- assert_no_match(/bootsnap/, content)
- end
+ assert_no_gem "bootsnap"
assert_file "config/boot.rb" do |content|
assert_no_match(/require 'bootsnap\/setup'/, content)
end
@@ -845,9 +878,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_bootsnap_with_dev_option
run_generator [destination_root, "--dev"]
- assert_file "Gemfile" do |content|
- assert_no_match(/bootsnap/, content)
- end
+ assert_no_gem "bootsnap"
assert_file "config/boot.rb" do |content|
assert_no_match(/require 'bootsnap\/setup'/, content)
end
@@ -946,8 +977,8 @@ class AppGeneratorTest < Rails::Generators::TestCase
def test_system_tests_directory_generated
run_generator
- assert_file("test/system/.keep")
assert_directory("test/system")
+ assert_file("test/system/.keep")
end
unless Gem.win_platform?
@@ -979,6 +1010,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"
@@ -989,9 +1026,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/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 29426cd99f..3e631f6021 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -347,7 +347,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
content = File.read(route_path).gsub(/\.routes\.draw do/) do |match|
"#{match} |map|"
end
- File.open(route_path, "wb") { |file| file.write(content) }
+ File.write(route_path, content)
run_generator ["product_line"], behavior: :revoke
@@ -364,7 +364,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
content.gsub!(/^ \#.*\n/, "")
content.gsub!(/^\n/, "")
- File.open(route_path, "wb") { |file| file.write(content) }
+ File.write(route_path, content)
assert_file "config/routes.rb", /\.routes\.draw do\n resources :product_lines\nend\n\z/
run_generator ["product_line"], behavior: :revoke