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

[Fix #9525] Add AllowIfMethodWithArguments option to Style/SymbolProc #9535

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 @@
* [#9525](https://github.com/rubocop-hq/rubocop/issues/9525): Add `AllowMethodsWithArguments` option to `Style/SymbolProc`. ([@koic][])
1 change: 1 addition & 0 deletions config/default.yml
Expand Up @@ -4588,6 +4588,7 @@ Style/SymbolProc:
Safe: false
VersionAdded: '0.26'
VersionChanged: '1.5'
AllowMethodsWithArguments: false
# A list of method names to be ignored by the check.
# The names should be fairly unique, otherwise you'll end up ignoring lots of code.
IgnoredMethods:
Expand Down
19 changes: 19 additions & 0 deletions lib/rubocop/cop/style/symbol_proc.rb
Expand Up @@ -5,13 +5,27 @@ module Cop
module Style
# Use symbols as procs when possible.
#
# If you prefer a style that allows block for method with arguments,
# please set `true` to `AllowMethodsWithArguments`.
#
# @example
# # bad
# something.map { |s| s.upcase }
# something.map { _1.upcase }
#
# # good
# something.map(&:upcase)
#
# @example AllowMethodsWithArguments: false (default)
# # bad
# something.do_something(foo) { |o| o.bar }
#
# # good
# something.do_something(foo, &:bar)
#
# @example AllowMethodsWithArguments: true
# # good
# something.do_something(foo) { |o| o.bar }
class SymbolProc < Base
include RangeHelp
include IgnoredMethods
Expand Down Expand Up @@ -42,6 +56,7 @@ def on_block(node)
return if proc_node?(dispatch_node)
return if %i[lambda proc].include?(dispatch_node.method_name)
return if ignored_method?(dispatch_node.method_name)
return if allow_if_method_has_argument?(node)
return if node.block_type? && destructuring_block_argument?(arguments_node)

register_offense(node, method_name, dispatch_node.method_name)
Expand Down Expand Up @@ -103,6 +118,10 @@ def begin_pos_for_replacement(node)
node.loc.begin.begin_pos
end
end

def allow_if_method_has_argument?(node)
!!cop_config.fetch('AllowMethodsWithArguments', false) && !node.arguments.count.zero?
end
end
end
end
Expand Down
55 changes: 46 additions & 9 deletions spec/rubocop/cop/style/symbol_proc_spec.rb
Expand Up @@ -142,16 +142,53 @@
expect(&run).not_to raise_error
end

context 'when `super` has arguments' do
it 'registers an offense' do
expect_offense(<<~RUBY)
super(one, two) { |x| x.test }
^^^^^^^^^^^^^^ Pass `&:test` as an argument to `super` instead of a block.
RUBY
context 'when `AllowMethodsWithArguments: true`' do
let(:cop_config) { { 'AllowMethodsWithArguments' => true } }

context 'when method has arguments' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
do_something(one, two) { |x| x.test }
RUBY
end
end

expect_correction(<<~RUBY)
super(one, two, &:test)
RUBY
context 'when `super` has arguments' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
super(one, two) { |x| x.test }
RUBY
end
end
end

context 'when `AllowMethodsWithArguments: false`' do
let(:cop_config) { { 'AllowMethodsWithArguments' => false } }

context 'when method has arguments' do
it 'registers an offense' do
expect_offense(<<~RUBY)
do_something(one, two) { |x| x.test }
^^^^^^^^^^^^^^ Pass `&:test` as an argument to `do_something` instead of a block.
RUBY

expect_correction(<<~RUBY)
do_something(one, two, &:test)
RUBY
end
end

context 'when `super` has arguments' do
it 'registers an offense' do
expect_offense(<<~RUBY)
super(one, two) { |x| x.test }
^^^^^^^^^^^^^^ Pass `&:test` as an argument to `super` instead of a block.
RUBY

expect_correction(<<~RUBY)
super(one, two, &:test)
RUBY
end
end
end

Expand Down