diff --git a/changelog/fix_false_positive_for_style_unless_logical_operators.md b/changelog/fix_false_positive_for_style_unless_logical_operators.md new file mode 100644 index 00000000000..09ad78584ae --- /dev/null +++ b/changelog/fix_false_positive_for_style_unless_logical_operators.md @@ -0,0 +1 @@ +* [#9551](https://github.com/rubocop/rubocop/issues/9551): Fix a false positive for `Style/UnlessLogicalOperators` when using `||` operator and invoked method name includes "or" in the conditional branch. ([@koic][]) diff --git a/lib/rubocop/cop/style/unless_logical_operators.rb b/lib/rubocop/cop/style/unless_logical_operators.rb index 5f992b8d674..70e86a805fe 100644 --- a/lib/rubocop/cop/style/unless_logical_operators.rb +++ b/lib/rubocop/cop/style/unless_logical_operators.rb @@ -87,11 +87,17 @@ def mixed_logical_operator?(node) end def mixed_precedence_and?(node) - node.source.include?('&&') && node.source.include?('and') + and_sources = node.condition.each_descendant(:and).map(&:operator) + and_sources << node.condition.operator if node.condition.and_type? + + !(and_sources.all? { |s| s == '&&' } || and_sources.all? { |s| s == 'and' }) end def mixed_precedence_or?(node) - node.source.include?('||') && node.source.include?('or') + or_sources = node.condition.each_descendant(:or).map(&:operator) + or_sources << node.condition.operator if node.condition.or_type? + + !(or_sources.all? { |s| s == '||' } || or_sources.all? { |s| s == 'or' }) end end end diff --git a/spec/rubocop/cop/style/unless_logical_operators_spec.rb b/spec/rubocop/cop/style/unless_logical_operators_spec.rb index 3a7c66480fd..bd7bbaa8061 100644 --- a/spec/rubocop/cop/style/unless_logical_operators_spec.rb +++ b/spec/rubocop/cop/style/unless_logical_operators_spec.rb @@ -116,6 +116,26 @@ def condition? return unless a? RUBY end + + it 'does not register an offense when using `||` operator and invoked method name includes "or" in the conditional branch' do + expect_no_offenses(<<~RUBY) + unless condition + includes_or_in_the_name + + foo || bar + end + RUBY + end + + it 'does not register an offense when using `&&` operator and invoked method name includes "and" in the conditional branch' do + expect_no_offenses(<<~RUBY) + unless condition + includes_and_in_the_name + + foo && bar + end + RUBY + end end context 'EnforcedStyle is `forbid_logical_operators`' do