Skip to content

Commit

Permalink
Add MultilineMethodParameterLineBreaks cop
Browse files Browse the repository at this point in the history
Same as MultilineMethodArgumentLineBreaks but for method definitions,
this completes the set of cops that already existed for method calls,
array definitions, and Hash definitions.
  • Loading branch information
Korri authored and bbatsov committed Jul 9, 2022
1 parent 78ac23a commit 87a0497
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 1 deletion.
@@ -0,0 +1 @@
* [#10691](https://github.com/rubocop/rubocop/pull/10691): Add new `Layout/MultilineMethodParameterLineBreaks` cop. ([@Korri][])
7 changes: 7 additions & 0 deletions config/default.yml
Expand Up @@ -1158,6 +1158,13 @@ Layout/MultilineMethodDefinitionBraceLayout:
- new_line
- same_line

Layout/MultilineMethodParameterLineBreaks:
Description: >-
Checks that each parameter in a multi-line method definition
starts on a separate line.
Enabled: false
VersionAdded: '<<next>>'

Layout/MultilineOperationIndentation:
Description: >-
Checks indentation of binary operations that span more than
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Expand Up @@ -233,6 +233,7 @@
require_relative 'rubocop/cop/layout/multiline_method_call_brace_layout'
require_relative 'rubocop/cop/layout/multiline_method_call_indentation'
require_relative 'rubocop/cop/layout/multiline_method_definition_brace_layout'
require_relative 'rubocop/cop/layout/multiline_method_parameter_line_breaks'
require_relative 'rubocop/cop/layout/multiline_operation_indentation'
require_relative 'rubocop/cop/layout/parameter_alignment'
require_relative 'rubocop/cop/layout/redundant_line_break'
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop/cop/layout/line_length.rb
Expand Up @@ -37,6 +37,7 @@ module Layout
# * MultilineHashBraceLayout
# * MultilineHashKeyLineBreaks
# * MultilineMethodArgumentLineBreaks
# * MultilineMethodParameterLineBreaks
# * ParameterAlignment
#
# Together, these cops will pretty print hashes, arrays,
Expand Down
Expand Up @@ -6,7 +6,7 @@ module Layout
# Ensures that each argument in a multi-line method call
# starts on a separate line.
#
# NOTE: this cop does not move the first argument, if you want that to
# NOTE: This cop does not move the first argument, if you want that to
# be on a separate line, see `Layout/FirstMethodArgumentLineBreak`.
#
# @example
Expand All @@ -22,6 +22,9 @@ module Layout
# b,
# c
# )
#
# # good
# foo(a, b, c)
class MultilineMethodArgumentLineBreaks < Base
include MultilineElementLineBreaks
extend AutoCorrector
Expand Down
45 changes: 45 additions & 0 deletions lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb
@@ -0,0 +1,45 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Layout
# Ensures that each parameter in a multi-line method definition
# starts on a separate line.
#
# NOTE: This cop does not move the first argument, if you want that to
# be on a separate line, see `Layout/FirstMethodParameterLineBreak`.
#
# @example
#
# # bad
# def foo(a, b,
# c
# )
# end
#
# # good
# def foo(
# a,
# b,
# c
# )
# end
#
# # good
# def foo(a, b, c)
# end
class MultilineMethodParameterLineBreaks < Base
include MultilineElementLineBreaks
extend AutoCorrector

MSG = 'Each parameter in a multi-line method definition must start on a separate line.'

def on_def(node)
return if node.arguments.empty?

check_line_breaks(node, node.arguments)
end
end
end
end
end
162 changes: 162 additions & 0 deletions spec/rubocop/cop/layout/multiline_method_parameter_line_breaks_spec.rb
@@ -0,0 +1,162 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Layout::MultilineMethodParameterLineBreaks, :config do
context 'when one parameter on same line' do
it 'does not add any offenses' do
expect_no_offenses(<<~RUBY)
def taz(abc)
end
RUBY
end
end

context 'when there are no parameters' do
it 'does not add any offenses' do
expect_no_offenses(<<~RUBY)
def taz
end
RUBY
end
end

context 'when two parameters are on next line' do
it 'does not add any offenses' do
expect_no_offenses(<<~RUBY)
def taz(
foo, bar
)
end
RUBY
end
end

context 'when many parameter are on multiple lines, two on same line' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
def taz(abc,
foo, bar,
^^^ Each parameter in a multi-line method definition must start on a separate line.
baz
)
end
RUBY

expect_correction(<<~RUBY)
def taz(abc,
foo,#{trailing_whitespace}
bar,
baz
)
end
RUBY
end
end

context 'when many parameters are on multiple lines, three on same line' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
def taz(abc,
foo, bar, barz,
^^^^ Each parameter in a multi-line method definition must start on a separate line.
^^^ Each parameter in a multi-line method definition must start on a separate line.
baz
)
end
RUBY

expect_correction(<<~RUBY)
def taz(abc,
foo,#{trailing_whitespace}
bar,#{trailing_whitespace}
barz,
baz
)
end
RUBY
end
end

context 'when many parameters including hash are on multiple lines, three on same line' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
def taz(abc,
foo, bar, z: "barz",
^^^^^^^^^ Each parameter in a multi-line method definition must start on a separate line.
^^^ Each parameter in a multi-line method definition must start on a separate line.
x:
)
end
RUBY

expect_correction(<<~RUBY)
def taz(abc,
foo,#{trailing_whitespace}
bar,#{trailing_whitespace}
z: "barz",
x:
)
end
RUBY
end
end

context 'when parameter\'s default value starts on same line but ends on different line' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
def taz(abc, foo = {
^^^^^^^ Each parameter in a multi-line method definition must start on a separate line.
foo: "edf",
})
end
RUBY

expect_correction(<<~RUBY)
def taz(abc,#{trailing_whitespace}
foo = {
foo: "edf",
})
end
RUBY
end
end

context 'when second parameter starts on same line as end of first' do
it 'registers an offense and corrects' do
expect_offense(<<~RUBY)
def taz(abc = {
foo: "edf",
}, bar:)
^^^^ Each parameter in a multi-line method definition must start on a separate line.
end
RUBY

expect_correction(<<~RUBY)
def taz(abc = {
foo: "edf",
},#{trailing_whitespace}
bar:)
end
RUBY
end
end

context 'when there are multiple parameters on the first line' do
it 'registers an offense and corrects starting from the 2nd argument' do
expect_offense(<<~RUBY)
def do_something(foo, bar, baz,
^^^ Each parameter in a multi-line method definition must start on a separate line.
^^^ Each parameter in a multi-line method definition must start on a separate line.
quux)
end
RUBY

expect_correction(<<~RUBY)
def do_something(foo,#{trailing_whitespace}
bar,#{trailing_whitespace}
baz,
quux)
end
RUBY
end
end
end

0 comments on commit 87a0497

Please sign in to comment.