Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pattern matching for Style/IdenticalConditionalBranches cop #9855

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1 @@
* [#9855](https://github.com/rubocop/rubocop/pull/9855): Support Ruby 2.7's pattern matching for `Style/IdenticalConditionalBranches` cop. ([@koic][])
29 changes: 29 additions & 0 deletions lib/rubocop/cop/style/identical_conditional_branches.rb
Expand Up @@ -67,6 +67,28 @@ module Style
# do_x
# do_z
# end
#
# # bad
# case foo
# in 1
# do_x
# in 2
# do_x
# else
# do_x
# end
#
# # good
# case foo
# in 1
# do_x
# do_y
# in 2
# # nothing
# else
# do_x
# do_z
# end
class IdenticalConditionalBranches < Base
include RangeHelp
extend AutoCorrector
Expand All @@ -87,6 +109,13 @@ def on_case(node)
check_branches(node, branches)
end

def on_case_match(node)
return unless node.else? && node.else_branch

branches = node.in_pattern_branches.map(&:body).push(node.else_branch)
check_branches(node, branches)
end

private

def check_branches(node, branches)
Expand Down
138 changes: 138 additions & 0 deletions spec/rubocop/cop/style/identical_conditional_branches_spec.rb
Expand Up @@ -233,6 +233,144 @@
end
end

context 'when using pattern matching', :ruby27 do
context 'on case-match with identical bodies' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
case something
in :a
do_x
^^^^ Move `do_x` out of the conditional.
in :b
do_x
^^^^ Move `do_x` out of the conditional.
else
do_x
^^^^ Move `do_x` out of the conditional.
end
RUBY

expect_correction(<<~RUBY)
case something
in :a
in :b
else
end
do_x
RUBY
end
end

context 'when one of the case-match branches is empty' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
case value
in cond1
else
if cond2
else
end
end
RUBY
end
end

context 'on case-match with identical trailing lines' do
it 'registers and corrects an offense' do
expect_offense(<<~RUBY)
case something
in :a
x1
do_x
^^^^ Move `do_x` out of the conditional.
in :b
x2
do_x
^^^^ Move `do_x` out of the conditional.
else
x3
do_x
^^^^ Move `do_x` out of the conditional.
end
RUBY

expect_correction(<<~RUBY)
case something
in :a
x1
in :b
x2
else
x3
end
do_x
RUBY
end
end

context 'on case-match with identical leading lines' do
it 'registers and corrects an offense' do
expect_offense(<<~RUBY)
case something
in :a
do_x
^^^^ Move `do_x` out of the conditional.
x1
in :b
do_x
^^^^ Move `do_x` out of the conditional.
x2
else
do_x
^^^^ Move `do_x` out of the conditional.
x3
end
RUBY

expect_correction(<<~RUBY)
do_x
case something
in :a
x1
in :b
x2
else
x3
end
RUBY
end
end

context 'on case-match without else' do
it "doesn't register an offense" do
expect_no_offenses(<<~RUBY)
case something
in :a
do_x
in :b
do_x
end
RUBY
end
end

context 'on case-match with empty when' do
it "doesn't register an offense" do
expect_no_offenses(<<~RUBY)
case something
in :a
do_x
do_y
in :b
else
do_x
do_z
end
RUBY
end
end
end

context 'with empty brace' do
it 'does not raise any error' do
expect_no_offenses(<<~RUBY)
Expand Down