Skip to content

Commit

Permalink
[rubocop#743] Implement auto-correct for SingleLineMethods cop
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas054 committed Feb 8, 2014
1 parent 7a1e976 commit b51c570
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

## master (unreleased)

### New features

* New cop `FileName` makes sure that source files have snake_case names. ([@bbatsov][])
* [#743](https://github.com/bbatsov/rubocop/issues/743): `SingleLineMethods` cop does auto-correction. ([@jonas054][])

### Changes

Expand Down
37 changes: 37 additions & 0 deletions lib/rubocop/cop/style/single_line_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,46 @@ def check(node, _method_name, _args, body)
empty_body = body.nil?

if start_line == end_line && !(allow_empty? && empty_body)
@body = body
add_offence(node, :expression)
end
end

def autocorrect(node)
body = @body
eol_comment = processed_source.comments.find do |c|
c.loc.line == node.loc.expression.line
end
@corrections << lambda do |corrector|
if body.type == :begin
body.children.each do |part|
break_line_before(part.loc.expression, node, corrector, 1)
end
else
break_line_before(body.loc.expression, node, corrector, 1)
end

break_line_before(node.loc.end, node, corrector, 0)

move_comment(eol_comment, node, corrector) if eol_comment
end
end

def break_line_before(range, node, corrector, indent_steps)
corrector.insert_before(range,
"\n" + ' ' * (node.loc.keyword.column +
indent_steps *
IndentationWidth::
CORRECT_INDENTATION))
end

def move_comment(eol_comment, node, corrector)
text = eol_comment.loc.expression.source
corrector.insert_before(node.loc.expression,
text + "\n" +
' ' * node.loc.keyword.column)
corrector.remove(eol_comment.loc.expression)
end
end
end
end
Expand Down
27 changes: 27 additions & 0 deletions spec/rubocop/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,33 @@ def abs(path)
'end'].join("\n") + "\n")
end

it 'can correct single line methods' do
create_file('example.rb', ['# encoding: utf-8',
'def func1; do_something end # comment',
'def func2() do_1; do_2; end'])
expect(cli.run(%w(--auto-correct --format offences))).to eq(1)
expect(IO.read('example.rb')).to eq(['# encoding: utf-8',
'# comment',
'def func1;',
' do_something',
'end',
'def func2',
' do_1;',
' do_2;',
'end',
''].join("\n"))
expect($stdout.string).to eq(['',
'6 TrailingWhitespace',
'4 Semicolon',
'2 EmptyLineBetweenDefs',
'2 SingleLineMethods',
'1 DefWithParentheses',
'--',
'15 Total',
'',
''].join("\n"))
end

# In this example, the auto-correction (changing "raise" to "fail")
# creates a new problem (alignment of parameters), which is also
# corrected automatically.
Expand Down
38 changes: 38 additions & 0 deletions spec/rubocop/cop/style/single_line_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,42 @@
'end'])
expect(cop.offences).to be_empty
end

it 'auto-corrects def with semicolon after method name' do
corrected = autocorrect_source(cop,
[' def some_method; body end # Cmnt'])
expect(corrected).to eq [' # Cmnt',
' def some_method; ',
' body ',
' end '].join("\n")
end

it 'auto-corrects defs with parentheses after method name' do
corrected = autocorrect_source(cop, [' def self.some_method() body end'])
expect(corrected).to eq [' def self.some_method() ',
' body ',
' end'].join("\n")
end

it 'auto-corrects def with argument in parentheses' do
corrected = autocorrect_source(cop, [' def some_method(arg) body end'])
expect(corrected).to eq [' def some_method(arg) ',
' body ',
' end'].join("\n")
end

it 'auto-corrects def with argument and no parentheses' do
corrected = autocorrect_source(cop, [' def some_method arg; body end'])
expect(corrected).to eq [' def some_method arg; ',
' body ',
' end'].join("\n")
end

it 'auto-corrects def with semicolon before end' do
corrected = autocorrect_source(cop, [' def some_method; b1; b2; end'])
expect(corrected).to eq [' def some_method; ',
' b1; ',
' b2; ',
' end'].join("\n")
end
end

0 comments on commit b51c570

Please sign in to comment.