Skip to content

Commit

Permalink
Support more complex argument patterns on Rails/Validation auto-cor…
Browse files Browse the repository at this point in the history
…rection
  • Loading branch information
r7kamura committed Jan 22, 2019
1 parent 95e58a2 commit 430b91c
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -11,6 +11,7 @@
* [#6254](https://github.com/rubocop-hq/rubocop/issues/6254): Fix `Layout/RescueEnsureAlignment` for non-local assignments. ([@marcotc][])
* [#6648](https://github.com/rubocop-hq/rubocop/issues/6648): Fix auto-correction of `Style/EmptyLiteral` when `Hash.new` is passed as the first argument to `super`. ([@rrosenblum][])
* [#6351](https://github.com/rubocop-hq/rubocop/pull/6351): Fix a false positive for `Layout/ClosingParenthesisIndentation` when first argument is multiline. ([@antonzaytsev][])
* [#6689](https://github.com/rubocop-hq/rubocop/pull/6689): Support more complex argument patterns on `Rails/Validation` auto-correction. ([@r7kamura][])

## 0.63.1 (2019-01-22)

Expand Down
13 changes: 9 additions & 4 deletions lib/rubocop/cop/rails/validation.rb
Expand Up @@ -57,6 +57,9 @@ def on_send(node)
end

def autocorrect(node)
last_argument = node.arguments.last
return if !last_argument.literal? && !last_argument.splat_type?

lambda do |corrector|
corrector.replace(node.loc.selector, 'validates')
correct_validate_type(corrector, node)
Expand All @@ -75,12 +78,14 @@ def preferred_method(method)
end

def correct_validate_type(corrector, node)
options = node.arguments.find { |arg| !arg.sym_type? }
last_argument = node.arguments.last
validate_type = node.method_name.to_s.split('_')[1]

if options
corrector.replace(options.loc.expression,
"#{validate_type}: #{braced_options(options)}")
if last_argument.hash_type?
corrector.replace(
last_argument.loc.expression,
"#{validate_type}: #{braced_options(last_argument)}"
)
else
corrector.insert_after(node.loc.expression,
", #{validate_type}: true")
Expand Down
152 changes: 124 additions & 28 deletions spec/rubocop/cop/rails/validation_spec.rb
Expand Up @@ -20,34 +20,130 @@
end
end

describe 'autocorrect' do
described_class::TYPES.each do |parameter|
it "corrects validates_#{parameter}_of" do
new_source = autocorrect_source(
"validates_#{parameter}_of :full_name, :birth_date"
)
expect(new_source).to eq(
"validates :full_name, :birth_date, #{parameter}: true"
)
end
end

it 'corrects validates_numericality_of with options' do
new_source = autocorrect_source(
'validates_numericality_of :age, minimum: 0, maximum: 122'
)
expect(new_source).to eq(
'validates :age, numericality: { minimum: 0, maximum: 122 }'
)
end

it 'autocorrect validates_numericality_of with options in braces' do
new_source = autocorrect_source(
'validates_numericality_of :age, { minimum: 0, maximum: 122 }'
)
expect(new_source).to eq(
'validates :age, numericality: { minimum: 0, maximum: 122 }'
)
describe '#autocorrect' do
shared_examples 'auto-corrects' do
it 'auto-corrects' do
expect(autocorrect_source(source)).to eq(auto_corrected_source)
end
end

shared_examples 'does not auto-correct' do
it 'does not auto-correct' do
expect(autocorrect_source(source)).to eq(source)
end
end

described_class::TYPES.each do |type|
context "with validates_#{type}_of" do
let(:auto_corrected_source) do
"validates :full_name, :birth_date, #{type}: true"
end

let(:source) do
"validates_#{type}_of :full_name, :birth_date"
end

include_examples 'auto-corrects'
end
end

context 'with single attribute name' do
let(:auto_corrected_source) do
'validates :a, numericality: true'
end

let(:source) do
'validates_numericality_of :a'
end

include_examples 'auto-corrects'
end

context 'with multi attribute names' do
let(:auto_corrected_source) do
'validates :a, :b, numericality: true'
end

let(:source) do
'validates_numericality_of :a, :b'
end

include_examples 'auto-corrects'
end

context 'with non-braced hash literal' do
let(:auto_corrected_source) do
'validates :a, :b, numericality: { minimum: 1 }'
end

let(:source) do
'validates_numericality_of :a, :b, minimum: 1'
end

include_examples 'auto-corrects'
end

context 'with braced hash literal' do
let(:auto_corrected_source) do
'validates :a, :b, numericality: { minimum: 1 }'
end

let(:source) do
'validates_numericality_of :a, :b, { minimum: 1 }'
end

include_examples 'auto-corrects'
end

context 'with splat' do
let(:auto_corrected_source) do
'validates :a, *b, numericality: true'
end

let(:source) do
'validates_numericality_of :a, *b'
end

include_examples 'auto-corrects'
end

context 'with splat and options' do
let(:auto_corrected_source) do
'validates :a, *b, :c, numericality: { minimum: 1 }'
end

let(:source) do
'validates_numericality_of :a, *b, :c, minimum: 1'
end

include_examples 'auto-corrects'
end

context 'with trailing send node' do
let(:source) do
'validates_numericality_of :a, b'
end

include_examples 'does not auto-correct'
end

context 'with trailing constant' do
let(:source) do
'validates_numericality_of :a, B'
end

include_examples 'does not auto-correct'
end

context 'with trailing local variable' do
let(:source) do
<<-RUBY.strip_indent
b = { minimum: 1 }
validates_numericality_of :a, b
RUBY
end

include_examples 'does not auto-correct'
end
end
end

0 comments on commit 430b91c

Please sign in to comment.