Skip to content

Commit

Permalink
Add MultilineWhenThen cop
Browse files Browse the repository at this point in the history
This cop check the use of the `then` keyword in multi-line when
statements.
Its name comes from `Style/MultilineIfThen` cop.
This cop is enabled by default because `Style/MultilineIfThen` cop is
enabled by default.
  • Loading branch information
okuramasafumi authored and bbatsov committed Jul 2, 2019
1 parent c804110 commit 203843f
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### New features

* Add `AllowDoxygenCommentStyle` configuration on `Layout/LeadingCommentSpace`. ([@anthony-robin][])
* [#7114](https://github.com/rubocop-hq/rubocop/pull/7114): Add `MultilineWhenThen` cop. ([@okuramasafumi][])

### Bug fixes

Expand Down Expand Up @@ -4116,3 +4117,4 @@
[@eugeneius]: https://github.com/eugeneius
[@malyshkosergey]: https://github.com/malyshkosergey
[@fwitzke]: https://github.com/fwitzke
[@okuramasafumi]: https://github.com/okuramasafumi
6 changes: 6 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3043,6 +3043,12 @@ Style/MultilineTernaryOperator:
Enabled: true
VersionAdded: '0.9'

Style/MultilineWhenThen:
Description: 'Do not use then for multi-line when statement.'
StyleGuide: '#no-then'
Enabled: true
VersionAdded: '0.72'

Style/MultipleComparison:
Description: >-
Avoid comparing a variable with multiple items in a conditional,
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@
require_relative 'rubocop/cop/style/multiline_method_signature'
require_relative 'rubocop/cop/style/multiline_memoization'
require_relative 'rubocop/cop/style/multiline_ternary_operator'
require_relative 'rubocop/cop/style/multiline_when_then'
require_relative 'rubocop/cop/style/multiple_comparison'
require_relative 'rubocop/cop/style/mutable_constant'
require_relative 'rubocop/cop/style/negated_if'
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/correctors/empty_line_corrector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ def correct(node)
offense_style, range = node
lambda do |corrector|
case offense_style
when :no_empty_lines then
when :no_empty_lines
corrector.remove(range)
when :empty_lines then
when :empty_lines
corrector.insert_before(range, "\n")
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/style/hash_syntax.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ def autocorrect(node)

def alternative_style
case style
when :hash_rockets then
when :hash_rockets
:ruby19
when :ruby19, :ruby19_no_mixed_keys then
when :ruby19, :ruby19_no_mixed_keys
:hash_rockets
end
end
Expand Down
55 changes: 55 additions & 0 deletions lib/rubocop/cop/style/multiline_when_then.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Style
# This cop checks uses of the `then` keyword
# in multi-line when statements.
#
# @example
# # bad
# case foo
# when bar then
# end
#
# # good
# case foo
# when bar
# end
#
# # good
# case foo
# when bar then do_something
# end
#
class MultilineWhenThen < Cop
include RangeHelp

MSG = 'Do not use `then` for multiline `when` statement.'

def on_when(node)
# Without `then`, there's no offense
return unless node.then?

# Single line usage of `then` is not an offense
return if !node.children.last.nil? && !node.multiline? && node.then?

# With more than one statements after then, there's not offense
return if node.children.last&.begin_type?

add_offense(node, location: :begin)
end

def autocorrect(node)
lambda do |corrector|
corrector.remove(
range_with_surrounding_space(
range: node.loc.begin, side: :left
)
)
end
end
end
end
end
end
1 change: 1 addition & 0 deletions manual/cops.md
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ In the following section you find all available cops:
* [Style/MultilineMemoization](cops_style.md#stylemultilinememoization)
* [Style/MultilineMethodSignature](cops_style.md#stylemultilinemethodsignature)
* [Style/MultilineTernaryOperator](cops_style.md#stylemultilineternaryoperator)
* [Style/MultilineWhenThen](cops_style.md#stylemultilinewhenthen)
* [Style/MultipleComparison](cops_style.md#stylemultiplecomparison)
* [Style/MutableConstant](cops_style.md#stylemutableconstant)
* [Style/NegatedIf](cops_style.md#stylenegatedif)
Expand Down
32 changes: 32 additions & 0 deletions manual/cops_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -3785,6 +3785,38 @@ a =

* [https://rubystyle.guide#no-multiline-ternary](https://rubystyle.guide#no-multiline-ternary)

## Style/MultilineWhenThen

Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
--- | --- | --- | --- | ---
Enabled | Yes | Yes | 0.72 | -

This cop checks uses of the `then` keyword
in multi-line when statements.

### Examples

```ruby
# bad
case foo
when bar then
end
# good
case foo
when bar
end
# good
case foo
when bar then do_something
end
```

### References

* [https://rubystyle.guide#no-then](https://rubystyle.guide#no-then)

## Style/MultipleComparison

Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
Expand Down
87 changes: 87 additions & 0 deletions spec/rubocop/cop/style/multiline_when_then_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Style::MultilineWhenThen do
subject(:cop) { described_class.new }

it 'registers an offense for empty when statement with then' do
expect_offense(<<~RUBY)
case foo
when bar then
^^^^ Do not use `then` for multiline `when` statement.
end
RUBY
end

it 'registers an offense for multiline when statement with then' do
expect_offense(<<~RUBY)
case foo
when bar then
^^^^ Do not use `then` for multiline `when` statement.
do_something
end
RUBY
end

it "doesn't register an offense for singleline when statement with then" do
expect_no_offenses(<<~RUBY)
case foo
when bar then do_something
end
RUBY
end

it "doesn't register an offense for multiline when statement
with then followed by other lines" do
expect_no_offenses(<<~RUBY)
case foo
when bar then do_something
do_another_thing
end
RUBY
end

it "doesn't register an offense for empty when statement without then" do
expect_no_offenses(<<~RUBY)
case foo
when bar
end
RUBY
end

it "doesn't register an offense for multiline when statement without then" do
expect_no_offenses(<<~RUBY)
case foo
when bar
do_something
end
RUBY
end

it 'autocorrects then in empty when' do
new_source = autocorrect_source(<<~RUBY)
case foo
when bar then
end
RUBY
expect(new_source).to eq(<<~RUBY)
case foo
when bar
end
RUBY
end

it 'autocorrects then in multiline when' do
new_source = autocorrect_source(<<~RUBY)
case foo
when bar then
do_something
end
RUBY
expect(new_source).to eq(<<~RUBY)
case foo
when bar
do_something
end
RUBY
end
end

0 comments on commit 203843f

Please sign in to comment.