Skip to content

Commit

Permalink
[Fix rubocop#8372] Fix Lint/RedundantCopDisableDirective autocorrec…
Browse files Browse the repository at this point in the history
…tion removing a preceding newline incorrectly.

There were no tests previously for autocorrection, so this change also adds tests to ensure whitespace is managed correctly.
  • Loading branch information
dvandersluis committed Sep 22, 2020
1 parent 30a3d01 commit 5536d63
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -14,6 +14,7 @@
* [#8750](https://github.com/rubocop-hq/rubocop/pull/8750): Fix an incorrect auto-correct for `Style/MultilineWhenThen` when line break for multiple condidate values of `when` statement. ([@koic][])
* [#8754](https://github.com/rubocop-hq/rubocop/pull/8754): Fix an error for `Style/RandomWithOffset` when using a range with non-integer bounds. ([@eugeneius][])
* [#8756](https://github.com/rubocop-hq/rubocop/issues/8756): Fix an infinite loop error for `Layout/EmptyLinesAroundAccessModifier` with `Layout/EmptyLinesAroundBlockBody` when using access modifier with block argument. ([@koic][])
* [#8372](https://github.com/rubocop-hq/rubocop/issues/8372): Fix `Lint/RedundantCopDisableDirective` autocorrection. ([@dvandersluis][])

### Changes

Expand Down
34 changes: 22 additions & 12 deletions lib/rubocop/cop/lint/redundant_cop_disable_directive.rb
Expand Up @@ -56,19 +56,29 @@ def on_new_investigation

private

def previous_line_blank?(range)
processed_source.buffer.source_line(range.line - 1).blank?
end

def comment_range_with_surrounding_space(range)
# Eat the entire comment, the preceding space, and the preceding
# newline if there is one.
original_begin = range.begin_pos
range = range_with_surrounding_space(range: range,
side: :left,
newlines: true)
range_with_surrounding_space(range: range,
side: :right,
# Special for a comment that
# begins the file: remove
# the newline at the end.
newlines: original_begin.zero?)
if previous_line_blank?(range)
# When the previous line is blank, it should be retained
range_with_surrounding_space(range: range, side: :right)
else
# Eat the entire comment, the preceding space, and the preceding
# newline if there is one.
original_begin = range.begin_pos
range = range_with_surrounding_space(range: range,
side: :left,
newlines: true)

range_with_surrounding_space(range: range,
side: :right,
# Special for a comment that
# begins the file: remove
# the newline at the end.
newlines: original_begin.zero?)
end
end

def directive_range_in_list(range, ranges)
Expand Down
152 changes: 152 additions & 0 deletions spec/rubocop/cop/lint/redundant_cop_disable_directive_spec.rb
Expand Up @@ -314,5 +314,157 @@ class One
end
end
end

context 'autocorrecting whitespace' do
context 'when the comment is the first line of the file' do
context 'followed by code' do
it 'removes the comment' do
expect_offense(<<~RUBY)
# rubocop:disable Metrics/MethodLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/MethodLength`.
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY

expect_correction(<<~RUBY)
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY
end
end

context 'followed by a newline' do
it 'removes the comment and newline' do
expect_offense(<<~RUBY)
# rubocop:disable Metrics/MethodLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/MethodLength`.
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY

expect_correction(<<~RUBY)
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY
end
end

context 'followed by another comment' do
it 'removes the comment and newline' do
expect_offense(<<~RUBY)
# rubocop:disable Metrics/MethodLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/MethodLength`.
# @api private
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY

expect_correction(<<~RUBY)
# @api private
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY
end
end
end

context 'when there is only whitespace before the comment' do
it 'leaves the whitespace' do
expect_offense(<<~RUBY)
# rubocop:disable Metrics/MethodLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/MethodLength`.
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY

expect_correction(<<~RUBY)
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY
end
end

context 'when the comment is not the first line of the file' do
it 'preserves whitespace before the comment' do
expect_offense(<<~RUBY)
attr_reader :foo
# rubocop:disable Metrics/MethodLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/MethodLength`.
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY

expect_correction(<<~RUBY)
attr_reader :foo
def my_method
end
# rubocop:enable Metrics/MethodLength
RUBY
end
end

context 'nested inside a namespace' do
it 'preserves indentation' do
expect_offense(<<~RUBY)
module Foo
module Bar
# rubocop:disable Metrics/ClassLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/ClassLength`.
class Baz
end
# rubocop:enable Metrics/ClassLength
end
end
RUBY

expect_correction(<<~RUBY)
module Foo
module Bar
class Baz
end
# rubocop:enable Metrics/ClassLength
end
end
RUBY
end
end

context 'inline comment' do
it 'removes the comment and preceding whitespace' do
expect_offense(<<~RUBY)
module Foo
module Bar
class Baz # rubocop:disable Metrics/ClassLength
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unnecessary disabling of `Metrics/ClassLength`.
end
end
end
RUBY

expect_correction(<<~RUBY)
module Foo
module Bar
class Baz
end
end
end
RUBY
end
end
end
end
end

0 comments on commit 5536d63

Please sign in to comment.