Skip to content

Commit

Permalink
Stub rails_command to prevent app:template command from being run
Browse files Browse the repository at this point in the history
When #48269 was merged any gem installed during `rails new` which calls `app:template` would cause the install command to be executed and consequently `bundle install` would also run.

We want to avoid running these commands in our tests because they are very expensive.

It is up to the gem (importmap, etc) to test the behavior of the install command, not railties.

Before

```
$ bin/test test/generators/plugin_generator_test.rb test/generators/app_generator_test.rb
Finished in 320.803659s, 0.8541 runs/s, 7.1913 assertions/s.
274 runs, 2307 assertions, 14 failures, 0 errors, 0 skips
```

After

```
Finished in 70.316250s, 3.9251 runs/s, 34.3164 assertions/s.
276 runs, 2413 assertions, 0 failures, 0 errors, 0 skips
```

Change railties default log_level to :error

The default of :info generates a ton of unnecessary noise in the
railties logs.

This change greatly reduces the amount of noise in the railties tests.

**After**

```
$ bundle exec rake test >> railties_output_patched 2>&1
$ wc -l railties_output_patched
    1491 railties_output_patched
```

**Before**

```
$ bundle exec rake test >> railties_output_unpatched 2>&1
$ wc -l railties_output_unpatched
   19023 railties_output_unpatched
```
  • Loading branch information
zzak committed May 18, 2024
1 parent d135be2 commit bfaef20
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 75 deletions.
1 change: 1 addition & 0 deletions railties/test/application/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def suppress_default_config
def restore_default_config
FileUtils.rm_rf("#{app_path}/config/environments")
FileUtils.mv("#{app_path}/config/__environments__", "#{app_path}/config/environments")
remove_from_env_config "production", "config.log_level = :error"
end

test "Rails.env does not set the RAILS_ENV environment variable which would leak out into rake tasks" do
Expand Down
125 changes: 52 additions & 73 deletions railties/test/generators/app_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,20 @@ def test_ci_files_are_skipped_if_required
assert_no_file ".github/dependabot.yml"
end

def test_inclusion_of_kamal_files
run_generator_instance

assert_file "config/deploy.yml"
assert_file ".env.erb"
end

def test_kamal_files_are_skipped_if_required
run_generator [destination_root, "--skip-kamal"]

assert_no_file "config/deploy.yml"
assert_no_file ".env.erb"
end

def test_usage_read_from_file
assert_called(File, :read, returns: "USAGE FROM FILE") do
assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
Expand Down Expand Up @@ -766,15 +780,10 @@ def test_skip_active_job_option
def test_skip_javascript_option
generator([destination_root], skip_javascript: true)

command_check = -> command, *_ do
if command == "importmap:install"
flunk "`importmap:install` expected to not be called."
end
end
run_generator_instance

generator.stub(:rails_command, command_check) do
run_generator_instance
end
assert_not_includes @rails_commands, "importmap:install", "`importmap:install` expected to not be called."
assert_not_includes @rails_commands, "turbo:install stimulus:install", "`turbo:install stimulus:install` expected to not be called."

assert_no_gem "importmap-rails"
assert_no_gem "jsbundling-rails"
Expand All @@ -792,39 +801,19 @@ def test_skip_javascript_option
def test_webpack_option
generator([destination_root], javascript: "webpack")

webpack_called = 0
command_check = -> command, *_ do
case command
when "javascript:install:webpack"
webpack_called += 1
end
end

generator.stub(:rails_command, command_check) do
run_generator_instance
end
run_generator_instance

assert_equal 1, webpack_called, "`javascript:install:webpack` expected to be called once, but was called #{webpack_called} times."
assert_includes @rails_commands, "javascript:install:webpack", "`javascript:install:webpack` expected to be called, but wasn't."
assert_gem "jsbundling-rails"
assert_node_files
end

def test_esbuild_option
generator([destination_root], javascript: "esbuild")

esbuild_called = 0
command_check = -> command, *_ do
case command
when "javascript:install:esbuild"
esbuild_called += 1
end
end

generator.stub(:rails_command, command_check) do
run_generator_instance
end
run_generator_instance

assert_equal 1, esbuild_called, "`javascript:install:esbuild` expected to be called once, but was called #{esbuild_called} times."
assert_includes @rails_commands, "javascript:install:esbuild", "`javascript:install:esbuild` expected to be called, but wasn't."
assert_gem "jsbundling-rails"
assert_node_files
end
Expand All @@ -847,19 +836,9 @@ def test_esbuild_option_with_js_argument
def test_bun_option
generator([destination_root], javascript: "bun")

bun_called = 0
command_check = -> command, *_ do
case command
when "javascript:install:bun"
bun_called += 1
end
end

generator.stub(:rails_command, command_check) do
run_generator_instance
end
run_generator_instance

assert_equal 1, bun_called, "`javascript:install:bun` expected to be called once, but was called #{bun_called} times."
assert_includes @rails_commands, "javascript:install:bun", "`javascript:install:bun` expected to be called, but wasn't."
assert_gem "jsbundling-rails"
end

Expand Down Expand Up @@ -900,20 +879,20 @@ def test_skip_javascript_option_with_skip_js_argument
end

def test_hotwire
run_generator_and_bundler [destination_root]
generator [destination_root]
run_generator_instance

assert_includes @rails_commands, "turbo:install stimulus:install", "`turbo:install stimulus:install` expected to be called, but wasn't."
assert_gem "turbo-rails"
assert_gem "stimulus-rails"
assert_file "app/views/layouts/application.html.erb" do |content|
assert_match(/data-turbo-track/, content)
end
assert_file "app/javascript/application.js" do |content|
assert_match(/turbo/, content)
assert_match(/controllers/, content)
end
end

def test_skip_hotwire
run_generator [destination_root, "--skip-hotwire"]
generator [destination_root], ["--skip-hotwire"]
run_generator_instance

assert_no_gem "turbo-rails"
assert_file "app/views/layouts/application.html.erb" do |content|
Expand All @@ -923,11 +902,11 @@ def test_skip_hotwire
end

def test_css_option_with_asset_pipeline_tailwind
run_generator_and_bundler [destination_root, "--css=tailwind"]
generator [destination_root], ["--css=tailwind"]
run_generator_instance

assert_includes @rails_commands, "tailwindcss:install", "`tailwindcss:install` expected to be called, but wasn't."
assert_gem "tailwindcss-rails"
assert_file "app/views/layouts/application.html.erb" do |content|
assert_match(/tailwind/, content)
end
assert_no_node_files
end

Expand All @@ -938,9 +917,11 @@ def test_css_option_with_tailwind_uses_cssbundling_gem_when_using_node
end

def test_css_option_with_asset_pipeline_sass
run_generator_and_bundler [destination_root, "--css=sass"]
generator [destination_root], ["--css=sass"]
run_generator_instance

assert_includes @rails_commands, "dartsass:install", "`dartsass:install` expected to be called, but wasn't."
assert_gem "dartsass-rails"
assert_file "app/assets/stylesheets/application.scss"
assert_no_node_files
end

Expand All @@ -951,9 +932,11 @@ def test_css_option_with_sass_uses_cssbundling_gem_when_using_node
end

def test_css_option_with_cssbundling_gem
run_generator_and_bundler [destination_root, "--css=postcss"]
generator [destination_root], ["--css=postcss"]
run_generator_instance

assert_includes @rails_commands, "css:install:postcss", "`css:install:postcss` expected to be called, but wasn't."
assert_gem "cssbundling-rails"
assert_file "app/assets/stylesheets/application.postcss.css"
assert_node_files
end

Expand All @@ -963,6 +946,16 @@ def test_css_option_with_cssbundling_gem_does_not_force_jsbundling_gem
assert_gem "importmap-rails"
end

def test_default_generator_executes_all_rails_commands
generator [destination_root]
run_generator_instance

expected_commands = [
"credentials:diff --enroll", "importmap:install", "turbo:install stimulus:install"
]
assert_equal expected_commands, @rails_commands
end

def test_skip_dev_gems
run_generator [destination_root, "--skip-dev-gems"]
assert_no_gem "web-console"
Expand Down Expand Up @@ -1250,21 +1243,7 @@ def assert_no_node_files
end
end

def run_generator_and_bundler(args)
option_args, positional_args = args.partition { |arg| arg.start_with?("--") }
option_args << "--no-skip-bundle"
generator(positional_args, option_args)

# Stub `rails_gemfile_entry` so that Bundler resolves `gem "rails"` to the
# current repository instead of searching for an invalid version number
# (for a version that hasn't been released yet).
rails_gemfile_entry = Rails::Generators::AppBase::GemfileEntry.path("rails", Rails::Generators::RAILS_DEV_PATH)
generator.stub(:rails_gemfile_entry, -> { rails_gemfile_entry }) do
quietly { run_generator_instance }
end
end

def run_app_update(app_root = destination_root)
def run_app_update(app_root = destination_root, flags: "--force")
Dir.chdir(app_root) do
gemfile_contents = File.read("Gemfile")
gemfile_contents.sub!(/^(gem "rails").*/, "\\1, path: #{File.expand_path("../../..", __dir__).inspect}")
Expand Down
7 changes: 6 additions & 1 deletion railties/test/generators/shared_generator_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,13 @@ def run_generator_instance
@bundle_commands = []
@bundle_command_stub ||= -> (command, *) { @bundle_commands << command }

@rails_commands = []
@rails_command_stub ||= -> (command, *_) { @rails_commands << command }

generator.stub(:bundle_command, @bundle_command_stub) do
super
generator.stub(:rails_command, @rails_command_stub) do
super
end
end
end

Expand Down
3 changes: 2 additions & 1 deletion railties/test/isolation/abstract_unit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ def build_app(options = {})
add_to_env_config :development, "config.action_view.annotate_rendered_view_with_filenames = false"

remove_from_env_config("development", "config.generators.apply_rubocop_autocorrect_after_generate!")
add_to_env_config :production, "config.log_level = :error"
end

def teardown_app
Expand Down Expand Up @@ -263,7 +264,7 @@ def self.name; "RailtiesTestApp"; end
@app.config.eager_load = false
@app.config.session_store :cookie_store, key: "_myapp_session"
@app.config.active_support.deprecation = :log
@app.config.log_level = :info
@app.config.log_level = :error
@app.config.secret_key_base = "b3c631c314c0bbca50c1b2843150fe33"

yield @app if block_given?
Expand Down

0 comments on commit bfaef20

Please sign in to comment.