diff --git a/changelog/change_env_local_to_handle_negated_conditions.md b/changelog/change_env_local_to_handle_negated_conditions.md new file mode 100644 index 0000000000..3d0482b15d --- /dev/null +++ b/changelog/change_env_local_to_handle_negated_conditions.md @@ -0,0 +1 @@ +* [#1374](https://github.com/rubocop/rubocop-rails/pull/1374): Change `Rails/EnvLocal` to handle negated conditions. ([@fatkodima][]) diff --git a/lib/rubocop/cop/rails/env_local.rb b/lib/rubocop/cop/rails/env_local.rb index b76a354647..8aea161c71 100644 --- a/lib/rubocop/cop/rails/env_local.rb +++ b/lib/rubocop/cop/rails/env_local.rb @@ -19,20 +19,33 @@ class EnvLocal < Base extend TargetRailsVersion MSG = 'Use `Rails.env.local?` instead.' + MSG_NEGATED = 'Use `!Rails.env.local?` instead.' LOCAL_ENVIRONMENTS = %i[development? test?].to_set.freeze minimum_target_rails_version 7.1 - # @!method rails_env_local_candidate?(node) - def_node_matcher :rails_env_local_candidate?, <<~PATTERN + # @!method rails_env_local_or?(node) + def_node_matcher :rails_env_local_or?, <<~PATTERN (or (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS) (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS) ) PATTERN + # @!method rails_env_local_and?(node) + def_node_matcher :rails_env_local_and?, <<~PATTERN + (and + (send + (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS) + :!) + (send + (send (send (const {cbase nil? } :Rails) :env) $%LOCAL_ENVIRONMENTS) + :!) + ) + PATTERN + def on_or(node) - rails_env_local_candidate?(node) do |*environments| + rails_env_local_or?(node) do |*environments| next unless environments.to_set == LOCAL_ENVIRONMENTS add_offense(node) do |corrector| @@ -40,6 +53,16 @@ def on_or(node) end end end + + def on_and(node) + rails_env_local_and?(node) do |*environments| + next unless environments.to_set == LOCAL_ENVIRONMENTS + + add_offense(node, message: MSG_NEGATED) do |corrector| + corrector.replace(node, '!Rails.env.local?') + end + end + end end end end diff --git a/spec/rubocop/cop/rails/env_local_spec.rb b/spec/rubocop/cop/rails/env_local_spec.rb index 62cef8b1f3..aba7485130 100644 --- a/spec/rubocop/cop/rails/env_local_spec.rb +++ b/spec/rubocop/cop/rails/env_local_spec.rb @@ -10,6 +10,14 @@ RUBY end + it 'registers no offenses for non-local `!Rails.env._? && !Rails.env._?`' do + expect_no_offenses(<<~RUBY) + !Rails.env.development? && Rails.env.production? + !Rails.env.test? && Rails.env.production? + !Rails.env.production? && Rails.env.other? + RUBY + end + it 'registers no offenses for single `Rails.env._?`' do expect_no_offenses(<<~RUBY) Rails.env.development? @@ -35,6 +43,20 @@ RUBY end + it 'registers an offense for `!Rails.env.development? && !Rails.env.test?`' do + expect_offense(<<~RUBY) + !Rails.env.development? && !Rails.env.test? + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `!Rails.env.local?` instead. + !Rails.env.test? && !Rails.env.development? + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `!Rails.env.local?` instead. + RUBY + + expect_correction(<<~RUBY) + !Rails.env.local? + !Rails.env.local? + RUBY + end + it 'registers no offenses for `Rails.env.local?`' do expect_no_offenses(<<~RUBY) Rails.env.local? @@ -52,6 +74,13 @@ RUBY end + it 'registers no offenses for `!Rails.env.development? && !Rails.env.test?`' do + expect_no_offenses(<<~RUBY) + !Rails.env.development? && !Rails.env.test? + !Rails.env.test? && !Rails.env.development? + RUBY + end + it 'registers no offenses for `Rails.env.local?`' do expect_no_offenses(<<~RUBY) Rails.env.local?