Skip to content

Commit

Permalink
[Fix rubocop#10754] Fix an incorrect autocorrect for Style/HashExcept
Browse files Browse the repository at this point in the history
Fixes rubocop#10754.

This PR fixes an incorrect autocorrect for `Style/HashExcept`
when using a non-literal collection receiver for `include?`.
  • Loading branch information
koic committed Jun 28, 2022
1 parent 02d0dcf commit 82d3ebf
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 1 deletion.
@@ -0,0 +1 @@
* [#10754](https://github.com/rubocop/rubocop/issues/10754): Fix an incorrect autocorrect for `Style/HashExcept` when using a non-literal collection receiver for `include?`. ([@koic][])
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/hash_except.rb
Expand Up @@ -144,7 +144,7 @@ def except_key_source(key)
return key.join(', ')
end

key.source
key.literal? ? key.source : "*#{key.source}"
end

def decorate_source(value)
Expand Down
96 changes: 96 additions & 0 deletions spec/rubocop/cop/style/hash_except_spec.rb
Expand Up @@ -142,6 +142,30 @@
{foo: 1, bar: 2, baz: 3}.except("\#{foo}", 'bar')
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `include?` method with variable' do
expect_offense(<<~RUBY)
array = [:foo, :bar]
{foo: 1, bar: 2, baz: 3}.reject { |k, v| !array.include?(k) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
array = [:foo, :bar]
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `include?` method with method call' do
expect_offense(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.reject { |k, v| !array.include?(k) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end
end

context 'using `exclude?`' do
Expand Down Expand Up @@ -316,6 +340,30 @@
{foo: 1, bar: 2, baz: 3}.except("\#{foo}", 'bar')
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `key.in?` method with variable' do
expect_offense(<<~RUBY)
array = %i[foo bar]
{foo: 1, bar: 2, baz: 3}.reject { |k, v| k.in?(array) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
array = %i[foo bar]
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `key.in?` method with method call' do
expect_offense(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.reject { |k, v| k.in?(array) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end
end

context 'using `include?`' do
Expand Down Expand Up @@ -373,6 +421,30 @@
{foo: 1, bar: 2, baz: 3}.except("\#{foo}", 'bar')
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `include?` method with variable' do
expect_offense(<<~RUBY)
array = %i[foo bar]
{foo: 1, bar: 2, baz: 3}.reject { |k, v| !array.include?(k) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
array = %i[foo bar]
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `include?` method with method call' do
expect_offense(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.reject { |k, v| !array.include?(k) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end
end

context 'using `exclude?`' do
Expand Down Expand Up @@ -430,6 +502,30 @@
{foo: 1, bar: 2, baz: 3}.except("\#{foo}", 'bar')
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `!exclude?` method with variable' do
expect_offense(<<~RUBY)
array = %i[foo bar]
{foo: 1, bar: 2, baz: 3}.reject { |k, v| !array.exclude?(k) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
array = %i[foo bar]
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end

it 'registers and corrects an offense when using `reject` and calling `!exclude?` method with method call' do
expect_offense(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.reject { |k, v| !array.exclude?(k) }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `except(*array)` instead.
RUBY

expect_correction(<<~RUBY)
{foo: 1, bar: 2, baz: 3}.except(*array)
RUBY
end
end

it 'does not register an offense when using `reject` and other than comparison by string and symbol using `==`' do
Expand Down

0 comments on commit 82d3ebf

Please sign in to comment.