Skip to content

Commit

Permalink
[Fix #8372] Fix Lint/RedundantCopDisableDirective autocorrection re…
Browse files Browse the repository at this point in the history
…moving a preceding newline incorrectly. (#8744)

There were no tests previously for autocorrection, so this change also adds tests to ensure whitespace is managed correctly.

Co-authored-by: Bozhidar Batsov <bozhidar@batsov.com>
  • Loading branch information
dvandersluis and bbatsov committed Sep 23, 2020
1 parent 39f0624 commit b59c48a
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 @@ -15,6 +15,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][])
* [#8764](https://github.com/rubocop-hq/rubocop/issues/8764): Fix `Layout/CaseIndentation` not showing the cop name in output messages. ([@dvandersluis][])
* [#8771](https://github.com/rubocop-hq/rubocop/issues/8771): Fix an error for `Style/OneLineConditional` when using `if-then-elsif-then-end`. ([@koic][])
* [#8576](https://github.com/rubocop-hq/rubocop/issues/8576): Fix `Style/IfUnlessModifier` to ignore cop disable comment directives when considering conversion to the modifier form. ([@dsavochkin][])
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 b59c48a

Please sign in to comment.