Skip to content

Commit

Permalink
Fix an incorrect auto-correct for Layout/ClassStructure
Browse files Browse the repository at this point in the history
This PR fixes the following incorrect auto-correct for `Layout/ClassStructure`
when heredoc constant is defined after public method.

```console
% cat example.rb
class Foo
  def foo
  end

  CONSTANT = <<~EOS.freeze
    str
  EOS
end

% bundle exec rubocop --only Layout/ClassStructure -a
(snip)

% cat example.rb
class Foo
  CONSTANT = <<~EOS.freeze
  def foo
  end

    str
  EOS
end
```
  • Loading branch information
koic authored and bbatsov committed Oct 19, 2020
1 parent 35baf2e commit a6dd18c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,7 @@

* [#8892](https://github.com/rubocop-hq/rubocop/issues/8892): Fix an error for `Style/StringConcatenation` when correcting nested concatenable parts. ([@fatkodima][])
* [#8781](https://github.com/rubocop-hq/rubocop/issues/8781): Fix handling of comments in `Style/SafeNavigation` autocorrection. ([@dvandersluis][])
* [#8907](https://github.com/rubocop-hq/rubocop/pull/8907): Fix an incorrect auto-correct for `Layout/ClassStructure` when heredoc constant is defined after public method. ([@koic][])

### Changes

Expand Down
7 changes: 7 additions & 0 deletions lib/rubocop/cop/layout/class_structure.rb
Expand Up @@ -265,6 +265,9 @@ def source_range_with_comment(node)
end

def end_position_for(node)
heredoc = find_heredoc(node)
return heredoc.location.heredoc_end.end_pos + 1 if heredoc

end_line = buffer.line_for_position(node.loc.expression.end_pos)
buffer.line_range(end_line).end_pos
end
Expand All @@ -284,6 +287,10 @@ def start_line_position(node)
buffer.line_range(node.loc.line).begin_pos - 1
end

def find_heredoc(node)
node.each_node(:str, :dstr, :xstr).find(&:heredoc?)
end

def buffer
processed_source.buffer
end
Expand Down
75 changes: 75 additions & 0 deletions spec/rubocop/cop/layout/class_structure_spec.rb
Expand Up @@ -214,4 +214,79 @@ class Foo
end
end
end

it 'registers an offense and corrects when str heredoc constant is defined after public method' do
expect_offense(<<~RUBY)
class Foo
def do_something
end
CONSTANT = <<~EOS
^^^^^^^^^^^^^^^^^ `constants` is supposed to appear before `public_methods`.
str
EOS
end
RUBY

expect_correction(<<~RUBY)
class Foo
CONSTANT = <<~EOS
str
EOS
def do_something
end
end
RUBY
end

it 'registers an offense and corrects when dstr heredoc constant is defined after public method' do
expect_offense(<<~'RUBY')
class Foo
def do_something
end
CONSTANT = <<~EOS
^^^^^^^^^^^^^^^^^ `constants` is supposed to appear before `public_methods`.
#{str}
EOS
end
RUBY

expect_correction(<<~'RUBY')
class Foo
CONSTANT = <<~EOS
#{str}
EOS
def do_something
end
end
RUBY
end

it 'registers an offense and corrects when xstr heredoc constant is defined after public method' do
expect_offense(<<~'RUBY')
class Foo
def do_something
end
CONSTANT = <<~`EOS`
^^^^^^^^^^^^^^^^^^^ `constants` is supposed to appear before `public_methods`.
str
EOS
end
RUBY

expect_correction(<<~'RUBY')
class Foo
CONSTANT = <<~`EOS`
str
EOS
def do_something
end
end
RUBY
end
end

0 comments on commit a6dd18c

Please sign in to comment.