Skip to content

Commit

Permalink
Make InternalAffairs/SingleLineComparison aware of negative comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
koic committed Aug 21, 2022
1 parent 23a3924 commit dc09aae
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 7 deletions.
9 changes: 5 additions & 4 deletions lib/rubocop/cop/internal_affairs/single_line_comparison.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,21 @@ class SingleLineComparison < Base
extend AutoCorrector

MSG = 'Use `%<preferred>s`.'
RESTRICT_ON_SEND = %i[==].freeze
RESTRICT_ON_SEND = %i[== !=].freeze

# @!method single_line_comparison(node)
def_node_matcher :single_line_comparison, <<~PATTERN
{
(send (send $_receiver {:line :first_line}) :== (send _receiver :last_line))
(send (send $_receiver :last_line) :== (send _receiver {:line :first_line}))
(send (send $_receiver {:line :first_line}) {:== :!=} (send _receiver :last_line))
(send (send $_receiver :last_line) {:== :!=} (send _receiver {:line :first_line}))
}
PATTERN

def on_send(node)
return unless (receiver = single_line_comparison(node))

preferred = "#{extract_receiver(receiver)}.single_line?"
bang = node.method?(:!=) ? '!' : ''
preferred = "#{bang}#{extract_receiver(receiver)}.single_line?"

add_offense(node, message: format(MSG, preferred: preferred)) do |corrector|
corrector.replace(node, preferred)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/layout/redundant_line_break.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def suitable_as_single_line?(node)
!comment_within?(node) &&
node.each_descendant(:if, :case, :kwbegin, :def).none? &&
node.each_descendant(:dstr, :str).none?(&:heredoc?) &&
node.each_descendant(:begin).none? { |b| b.first_line != b.last_line }
node.each_descendant(:begin).none? { |b| !b.single_line? }
end

def convertible_block?(node)
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/mixin/check_line_breakable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def process_args(args)
def already_on_multiple_lines?(node)
return node.first_line != node.arguments.last.last_line if node.def_type?

node.first_line != node.last_line
!node.single_line?
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/multiline_in_pattern_then.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def on_in_pattern(node)

# Requires `then` for write `in` and its body on the same line.
def require_then?(in_pattern_node)
return true if in_pattern_node.pattern.first_line != in_pattern_node.pattern.last_line
return true unless in_pattern_node.pattern.single_line?
return false unless in_pattern_node.body

same_line?(in_pattern_node, in_pattern_node.body)
Expand Down
22 changes: 22 additions & 0 deletions spec/rubocop/cop/internal_affairs/single_line_comparison_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@
RUBY
end

it 'registers and corrects an offense when negative comparing `first_line` with `last_line`' do
expect_offense(<<~RUBY)
node.first_line != node.last_line
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `!node.single_line?`.
RUBY

expect_correction(<<~RUBY)
!node.single_line?
RUBY
end

it 'registers and corrects an offense when negative comparing `last_line` with `first_line`' do
expect_offense(<<~RUBY)
node.last_line != node.first_line
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `!node.single_line?`.
RUBY

expect_correction(<<~RUBY)
!node.single_line?
RUBY
end

it 'does not register an offense when comparing the same line' do
expect_no_offenses(<<~RUBY)
node.loc.first_line == node.loc.line
Expand Down

0 comments on commit dc09aae

Please sign in to comment.