diff --git a/changelog/fix_fix_a_false_negative_for_double_negation.md b/changelog/fix_fix_a_false_negative_for_double_negation.md new file mode 100644 index 00000000000..8002098f338 --- /dev/null +++ b/changelog/fix_fix_a_false_negative_for_double_negation.md @@ -0,0 +1 @@ +* [#10846](https://github.com/rubocop/rubocop/issues/10846): Fix a false negative for `Style/DoubleNegation` when there is a hash or an array at return location of method. ([@nobuyo][]) diff --git a/lib/rubocop/cop/style/double_negation.rb b/lib/rubocop/cop/style/double_negation.rb index 4e6c52d54c7..a0fe54a8892 100644 --- a/lib/rubocop/cop/style/double_negation.rb +++ b/lib/rubocop/cop/style/double_negation.rb @@ -93,6 +93,8 @@ def end_of_method_definition?(node) if conditional_node double_negative_condition_return_value?(node, last_child, conditional_node) + elsif last_child.pair_type? || last_child.hash_type? || last_child.parent.array_type? + false else last_child.last_line <= node.last_line end diff --git a/spec/rubocop/cop/style/double_negation_spec.rb b/spec/rubocop/cop/style/double_negation_spec.rb index 780fde67b29..96920eb3c9b 100644 --- a/spec/rubocop/cop/style/double_negation_spec.rb +++ b/spec/rubocop/cop/style/double_negation_spec.rb @@ -291,6 +291,147 @@ def foo? RUBY end + it 'registers an offense and corrects for `!!` with multi-line array at return location' do + expect_offense(<<~RUBY) + def foo + [ + foo1, + !!bar1, + ^ Avoid the use of double negation (`!!`). + !!baz1 + ^ Avoid the use of double negation (`!!`). + ] + end + RUBY + + expect_correction(<<~RUBY) + def foo + [ + foo1, + !bar1.nil?, + !baz1.nil? + ] + end + RUBY + end + + it 'registers an offense and corrects for `!!` with single-line array at return location' do + expect_offense(<<~RUBY) + def foo + [foo1, !!bar1, baz1] + ^ Avoid the use of double negation (`!!`). + end + RUBY + + expect_correction(<<~RUBY) + def foo + [foo1, !bar1.nil?, baz1] + end + RUBY + end + + it 'registers an offense and corrects for `!!` with multi-line hash at return location' do + expect_offense(<<~RUBY) + def foo + { + foo: foo1, + bar: !!bar1, + ^ Avoid the use of double negation (`!!`). + baz: !!baz1 + ^ Avoid the use of double negation (`!!`). + } + end + RUBY + + expect_correction(<<~RUBY) + def foo + { + foo: foo1, + bar: !bar1.nil?, + baz: !baz1.nil? + } + end + RUBY + end + + it 'registers an offense and corrects for `!!` with single-line hash at return location' do + expect_offense(<<~RUBY) + def foo + { foo: foo1, bar: !!bar1, baz: baz1 } + ^ Avoid the use of double negation (`!!`). + end + RUBY + + expect_correction(<<~RUBY) + def foo + { foo: foo1, bar: !bar1.nil?, baz: baz1 } + end + RUBY + end + + it 'registers an offense and corrects for `!!` with nested hash at return location' do + expect_offense(<<~RUBY) + def foo + { + foo: foo1, + bar: { baz: !!quux } + ^ Avoid the use of double negation (`!!`). + } + end + RUBY + + expect_correction(<<~RUBY) + def foo + { + foo: foo1, + bar: { baz: !quux.nil? } + } + end + RUBY + end + + it 'registers an offense and corrects for `!!` with nested array at return location' do + expect_offense(<<~RUBY) + def foo + [ + foo1, + [baz, !!quux] + ^ Avoid the use of double negation (`!!`). + ] + end + RUBY + + expect_correction(<<~RUBY) + def foo + [ + foo1, + [baz, !quux.nil?] + ] + end + RUBY + end + + it 'registers an offense and corrects for `!!` with complex array at return location' do + expect_offense(<<~RUBY) + def foo + [ + foo1, + { baz: !!quux } + ^ Avoid the use of double negation (`!!`). + ] + end + RUBY + + expect_correction(<<~RUBY) + def foo + [ + foo1, + { baz: !quux.nil? } + ] + end + RUBY + end + # rubocop:disable RSpec/RepeatedExampleGroupDescription context 'Ruby >= 2.7', :ruby27 do # rubocop:enable RSpec/RepeatedExampleGroupDescription