From bf8aaba44648f4f1292da24d840c011c246de805 Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Sat, 27 Jun 2020 20:55:46 +0900 Subject: [PATCH] Support auto-correction for `Style/IfUnlessModifierOfIfUnless` This PR supports auto-correction for `Style/IfUnlessModifierOfIfUnless`. From: ```ruby condition ? then_part : else_part unless external_condition ``` To: ```ruby unless external_condition condition ? then_part : else_part end ``` Branch indentation is left to `Layout/IndentationWidth` cop to keep the code simple. --- CHANGELOG.md | 1 + config/default.yml | 1 + docs/modules/ROOT/pages/cops_style.adoc | 4 +- .../style/if_unless_modifier_of_if_unless.rb | 12 +++++ .../if_unless_modifier_of_if_unless_spec.rb | 47 ++++++++++++++++++- 5 files changed, 61 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74846fcab1b..fc579ec8c99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * [#7868](https://github.com/rubocop-hq/rubocop/pull/7868): `Cop::Base` is the new recommended base class for cops. ([@marcandre][]) * [#8213](https://github.com/rubocop-hq/rubocop/pull/8213): Permit to specify TargetRubyVersion 2.8 (experimental). ([@koic][]) * [#8164](https://github.com/rubocop-hq/rubocop/pull/8164): Support auto-correction for `Lint/InterpolationCheck`. ([@koic][]) +* [#8223](https://github.com/rubocop-hq/rubocop/pull/8223): Support auto-correction for `Style/IfUnlessModifierOfIfUnless`. ([@koic][]) ### Bug fixes diff --git a/config/default.yml b/config/default.yml index c637cc0323b..34a2b52e190 100644 --- a/config/default.yml +++ b/config/default.yml @@ -2997,6 +2997,7 @@ Style/IfUnlessModifierOfIfUnless: Avoid modifier if/unless usage on conditionals. Enabled: true VersionAdded: '0.39' + VersionChanged: '0.87' Style/IfWithSemicolon: Description: 'Do not use if x; .... Use the ternary operator instead.' diff --git a/docs/modules/ROOT/pages/cops_style.adoc b/docs/modules/ROOT/pages/cops_style.adoc index 584b5e521df..6586aa98e32 100644 --- a/docs/modules/ROOT/pages/cops_style.adoc +++ b/docs/modules/ROOT/pages/cops_style.adoc @@ -3683,9 +3683,9 @@ end | Enabled | Yes -| No +| Yes | 0.39 -| - +| 0.87 |=== Checks for if and unless statements used as modifiers of other if or diff --git a/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb b/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb index ff5030a4892..5ad87fe567f 100644 --- a/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +++ b/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb @@ -33,6 +33,18 @@ def on_if(node) add_offense(node, location: :keyword, message: format(MSG, keyword: node.keyword)) end + + def autocorrect(node) + lambda do |corrector| + keyword = node.if? ? 'if' : 'unless' + + corrector.replace(node, <<~RUBY.chop) + #{keyword} #{node.condition.source} + #{node.if_branch.source} + end + RUBY + end + end end end end diff --git a/spec/rubocop/cop/style/if_unless_modifier_of_if_unless_spec.rb b/spec/rubocop/cop/style/if_unless_modifier_of_if_unless_spec.rb index 9165144792a..a20eb0e9f63 100644 --- a/spec/rubocop/cop/style/if_unless_modifier_of_if_unless_spec.rb +++ b/spec/rubocop/cop/style/if_unless_modifier_of_if_unless_spec.rb @@ -10,25 +10,68 @@ condition ? then_part : else_part unless external_condition ^^^^^^ Avoid modifier `unless` after another conditional. RUBY + + expect_correction(<<~RUBY) + unless external_condition + condition ? then_part : else_part + end + RUBY end context 'ternary with modifier' do - it 'registers an offense' do + it 'registers an offense and corrects' do expect_offense(<<~RUBY) condition ? then_part : else_part unless external_condition ^^^^^^ Avoid modifier `unless` after another conditional. RUBY + + expect_correction(<<~RUBY) + unless external_condition + condition ? then_part : else_part + end + RUBY end end context 'conditional with modifier' do - it 'registers an offense' do + it 'registers an offense and corrects' do + expect_offense(<<~RUBY) + unless condition + then_part + end if external_condition + ^^ Avoid modifier `if` after another conditional. + RUBY + + expect_correction(<<~RUBY) + if external_condition + unless condition + then_part + end + end + RUBY + end + end + + context '`unless` / `else` with modifier' do + it 'registers an offense and corrects' do expect_offense(<<~RUBY) unless condition then_part + else + else_part end if external_condition ^^ Avoid modifier `if` after another conditional. RUBY + + expect_correction(<<~RUBY) + if external_condition + unless condition + then_part + else + else_part + end + end + RUBY end end