rubocop / rubocop-rspec

Code style checking for RSpec files.
https://docs.rubocop.org/rubocop-rspec
MIT License
811 stars 276 forks source link

Add RSpec-Cop unexpected requires #1950

Closed TheWudu closed 3 months ago

TheWudu commented 3 months ago

We were facing issues with files required in spec-files only, which made the tests work, but at the staging or production environment the service was not able to start up due to missing requires.

This cop prevents adding requires to spec files, except for spec/rails_helper and except requires in spec/rails_helpers.

pirj commented 3 months ago

Can you please run this cop against real-world-rspec repos to see the offences?

ydah commented 3 months ago

I ran it through real-world-rspec:

Errors occur in the following cases:

require Rails.root.join("db/migrate/20230910021213_update_category_setting_approval_values.rb")

Errors that occur are as follows:

bundle exec rubocop -d --only Rspec/UnexpectedRequires /ydah/real-world-rspec/discourse/spec/migrations/uppdate_category_setting_approval_values_spec.rb
For /ydah/rubocop-rspec: configuration from /ydah/rubocop-rspec/.rubocop.yml
configuration from /ydah/rubocop-rspec/config/default.yml
configuration from /ydah/rubocop-rspec/config/default.yml
Default configuration from /.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/config/default.yml
Use parallel by default.
Skipping parallel inspection: only a single file needs inspection
Inspecting 1 file
Scanning /ydah/real-world-rspec/discourse/spec/migrations/uppdate_category_setting_approval_values_spec.rb
For /ydah/real-world-rspec/discourse/spec/migrations: --only option: Rspec/UnexpectedRequires has the wrong namespace - replace it with RSpec/UnexpectedRequires
An error occurred while RSpec/UnexpectedRequires cop was inspecting /ydah/real-world-rspec/discourse/spec/migrations/uppdate_category_setting_approval_values_spec.rb:3:0.
undefined method `value' for an instance of RuboCop::AST::SendNode
/ydah/rubocop-rspec/lib/rubocop/cop/rspec/unexpected_requires.rb:44:in `block in on_send'
/ydah/rubocop-rspec/lib/rubocop/cop/rspec/unexpected_requires.rb:41:in `require_symbol?'
/ydah/rubocop-rspec/lib/rubocop/cop/rspec/unexpected_requires.rb:43:in `on_send'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:107:in `public_send'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:107:in `block (2 levels) in trigger_responding_cops'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:171:in `with_cop_error_handling'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:106:in `block in trigger_responding_cops'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:105:in `each'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:105:in `trigger_responding_cops'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:69:in `on_send'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-ast-1.32.0/lib/rubocop/ast/traversal.rb:137:in `block in on_dstr'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-ast-1.32.0/lib/rubocop/ast/traversal.rb:137:in `each'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-ast-1.32.0/lib/rubocop/ast/traversal.rb:137:in `on_dstr'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:71:in `on_begin'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-ast-1.32.0/lib/rubocop/ast/traversal.rb:20:in `walk'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/commissioner.rb:87:in `investigate'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/team.rb:164:in `investigate_partial'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cop/team.rb:102:in `investigate'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:349:in `block in inspect_file'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:348:in `each'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:348:in `flat_map'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:348:in `inspect_file'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:291:in `block in do_inspection_loop'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:325:in `block in iterate_until_no_changes'
<internal:kernel>:187:in `loop'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:318:in `iterate_until_no_changes'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:287:in `do_inspection_loop'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:168:in `block in file_offenses'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:193:in `file_offense_cache'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:167:in `file_offenses'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:158:in `process_file'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:139:in `block in each_inspected_file'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:138:in `each'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:138:in `reduce'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:138:in `each_inspected_file'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:124:in `inspect_files'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/runner.rb:77:in `run'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli/command/execute_runner.rb:26:in `block in execute_runner'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli/command/execute_runner.rb:52:in `with_redirect'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli/command/execute_runner.rb:25:in `execute_runner'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli/command/execute_runner.rb:17:in `run'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli/command.rb:11:in `run'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli/environment.rb:18:in `run'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli.rb:122:in `run_command'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli.rb:129:in `execute_runners'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli.rb:51:in `block in run'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli.rb:81:in `profile_if_needed'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/lib/rubocop/cli.rb:43:in `run'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/exe/rubocop:19:in `block in <top (required)>'
/.rbenv/versions/3.3.0/lib/ruby/3.3.0/benchmark.rb:313:in `realtime'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/rubocop-1.65.1/exe/rubocop:19:in `<top (required)>'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/bin/rubocop:25:in `load'
/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/bin/rubocop:25:in `<top (required)>'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/cli/exec.rb:58:in `load'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/cli/exec.rb:58:in `kernel_load'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/cli/exec.rb:23:in `run'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/cli.rb:451:in `exec'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/cli.rb:34:in `dispatch'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/cli.rb:28:in `start'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/exe/bundle:28:in `block in <top (required)>'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/.local/share/gem/ruby/3.3.0/gems/bundler-2.5.7/exe/bundle:20:in `<top (required)>'
/.rbenv/versions/3.3.0/bin/bundle:25:in `load'
/.rbenv/versions/3.3.0/bin/bundle:25:in `<main>'
.

1 file inspected, no offenses detected

1 error occurred:
An error occurred while RSpec/UnexpectedRequires cop was inspecting /ydah/real-world-rspec/discourse/spec/migrations/uppdate_category_setting_approval_values_spec.rb:3:0.
TheWudu commented 3 months ago

I ran it through real-world-rspec:

Errors occur in the following cases:

require Rails.root.join("db/migrate/20230910021213_update_category_setting_approval_values.rb")

Errors that occur are as follows:

bundle exec rubocop -d --only Rspec/UnexpectedRequires /ydah/real-world-rspec/discourse/spec/migrations/uppdate_category_setting_approval_values_spec.rb
...

1 file inspected, no offenses detected

1 error occurred:
An error occurred while RSpec/UnexpectedRequires cop was inspecting /ydah/real-world-rspec/discourse/spec/migrations/uppdate_category_setting_approval_values_spec.rb:3:0.

I fixed this. The reason is that only "string" nodes have the value method, and this require Rails.root is a node (require) with a "nested" node "Rails.root"...

E.g.

(send nil :require
  (str "base64"))

vs

(send nil :require
  (send
    (send
      (const nil :Rails) :root) :join
    (str "db/migrate/20230910021213_update_category_setting_approval_values.rb")))