Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New RuboCop autocorrect #955

Merged
merged 1 commit into from Jul 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Expand Up @@ -14,4 +14,4 @@ InternalAffairs/MethodNameEqual:
# Offense count: 1
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 104
Max: 106
29 changes: 11 additions & 18 deletions lib/rubocop/cop/rspec/align_left_let_brace.rb
Expand Up @@ -18,35 +18,28 @@ module RSpec
# let(:a) { b }
#
class AlignLeftLetBrace < Cop
extend AutoCorrector

MSG = 'Align left let brace'

def self.autocorrect_incompatible_with
[Layout::ExtraSpacing]
end

def investigate(_processed_source)
def on_new_investigation
return if processed_source.blank?

token_aligner.offending_tokens.each do |let|
add_offense(let, location: :begin)
end
end
token_aligner =
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)

def autocorrect(let)
lambda do |corrector|
corrector.insert_before(
let.loc.begin,
token_aligner.indent_for(let)
)
token_aligner.offending_tokens.each do |let|
add_offense(let.loc.begin) do |corrector|
corrector.insert_before(
let.loc.begin, token_aligner.indent_for(let)
)
end
end
end

private

def token_aligner
@token_aligner ||=
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
end
end
end
end
Expand Down
29 changes: 11 additions & 18 deletions lib/rubocop/cop/rspec/align_right_let_brace.rb
Expand Up @@ -18,35 +18,28 @@ module RSpec
# let(:a) { b }
#
class AlignRightLetBrace < Cop
extend AutoCorrector

MSG = 'Align right let brace'

def self.autocorrect_incompatible_with
[Layout::ExtraSpacing]
end

def investigate(_processed_source)
def on_new_investigation
return if processed_source.blank?

token_aligner.offending_tokens.each do |let|
add_offense(let, location: :end)
end
end
token_aligner =
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)

def autocorrect(let)
lambda do |corrector|
corrector.insert_before(
let.loc.end,
token_aligner.indent_for(let)
)
token_aligner.offending_tokens.each do |let|
add_offense(let.loc.end) do |corrector|
corrector.insert_before(
let.loc.end, token_aligner.indent_for(let)
)
end
end
end

private

def token_aligner
@token_aligner ||=
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/rspec/be.rb
Expand Up @@ -28,7 +28,7 @@ class Be < Cop

def on_send(node)
be_without_args(node) do |matcher|
add_offense(matcher, location: :selector)
add_offense(matcher.loc.selector)
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/rubocop/cop/rspec/be_eql.rb
Expand Up @@ -36,6 +36,8 @@ module RSpec
# coerce objects for comparison.
#
class BeEql < Cop
extend AutoCorrector

MSG = 'Prefer `be` over `eql`.'

def_node_matcher :eql_type_with_identity, <<-PATTERN
Expand All @@ -44,13 +46,11 @@ class BeEql < Cop

def on_send(node)
eql_type_with_identity(node) do |eql|
add_offense(eql, location: :selector)
add_offense(eql.loc.selector) do |corrector|
corrector.replace(eql.loc.selector, 'be')
end
end
end

def autocorrect(node)
->(corrector) { corrector.replace(node.loc.selector, 'be') }
end
end
end
end
Expand Down
34 changes: 18 additions & 16 deletions lib/rubocop/cop/rspec/capybara/current_path_expectation.rb
Expand Up @@ -24,6 +24,8 @@ module Capybara
# expect(page).to have_current_path(/widgets/)
#
class CurrentPathExpectation < Cop
extend AutoCorrector

MSG = 'Do not set an RSpec expectation on `current_path` in ' \
'Capybara feature specs - instead, use the ' \
'`have_current_path` matcher on `page`'
Expand All @@ -47,30 +49,30 @@ class CurrentPathExpectation < Cop

def on_send(node)
expectation_set_on_current_path(node) do
add_offense(node, location: :selector)
add_offense(node.loc.selector) do |corrector|
next unless node.chained?

autocorrect(corrector, node)
end
end
end

def autocorrect(node)
lambda do |corrector|
return unless node.chained?
private

as_is_matcher(node.parent) do |to_sym, matcher_node|
rewrite_expectation(corrector, node, to_sym, matcher_node)
end
def autocorrect(corrector, node)
as_is_matcher(node.parent) do |to_sym, matcher_node|
rewrite_expectation(corrector, node, to_sym, matcher_node)
end

regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
rewrite_expectation(corrector, node, to_sym, matcher_node)
convert_regexp_str_to_literal(corrector, matcher_node, regexp)
end
regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
rewrite_expectation(corrector, node, to_sym, matcher_node)
convert_regexp_str_to_literal(corrector, matcher_node, regexp)
end
end

private

def rewrite_expectation(corrector, node, to_symbol, matcher_node)
current_path_node = node.first_argument
corrector.replace(current_path_node.loc.expression, 'page')
corrector.replace(current_path_node, 'page')
corrector.replace(node.parent.loc.selector, 'to')
matcher_method = if to_symbol == :to
'have_current_path'
Expand All @@ -84,7 +86,7 @@ def rewrite_expectation(corrector, node, to_symbol, matcher_node)
def convert_regexp_str_to_literal(corrector, matcher_node, regexp_str)
str_node = matcher_node.first_argument
regexp_expr = Regexp.new(regexp_str).inspect
corrector.replace(str_node.loc.expression, regexp_expr)
corrector.replace(str_node, regexp_expr)
end

# `have_current_path` with no options will include the querystring
Expand All @@ -97,7 +99,7 @@ def add_ignore_query_options(corrector, node)
return if %i[regexp str].include?(expectation_last_child.type)

corrector.insert_after(
expectation_last_child.loc.expression,
expectation_last_child,
', ignore_query: true'
)
end
Expand Down
17 changes: 8 additions & 9 deletions lib/rubocop/cop/rspec/capybara/feature_methods.rb
Expand Up @@ -41,6 +41,8 @@ module Capybara
# end
# end
class FeatureMethods < Cop
extend AutoCorrector

MSG = 'Use `%<replacement>s` instead of `%<method>s`.'

# https://git.io/v7Kwr
Expand Down Expand Up @@ -71,18 +73,15 @@ def on_block(node)
feature_method(node) do |send_node, match|
next if enabled?(match)

add_offense(
send_node,
location: :selector,
message: format(MSG, method: match, replacement: MAP[match])
)
add_offense(send_node.loc.selector) do |corrector|
corrector.replace(send_node.loc.selector, MAP[match].to_s)
end
end
end

def autocorrect(node)
lambda do |corrector|
corrector.replace(node.loc.selector, MAP[node.method_name].to_s)
end
def message(range)
name = range.source.to_sym
format(MSG, method: name, replacement: MAP[name])
end

private
Expand Down
12 changes: 5 additions & 7 deletions lib/rubocop/cop/rspec/context_method.rb
Expand Up @@ -24,6 +24,8 @@ module RSpec
# # ...
# end
class ContextMethod < Cop
extend AutoCorrector

MSG = 'Use `describe` for testing methods.'

def_node_matcher :context_method, <<-PATTERN
Expand All @@ -32,13 +34,9 @@ class ContextMethod < Cop

def on_block(node)
context_method(node) do |context|
add_offense(context)
end
end

def autocorrect(node)
lambda do |corrector|
corrector.replace(node.parent.loc.selector, 'describe')
add_offense(context) do |corrector|
corrector.replace(node.send_node.loc.selector, 'describe')
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/rspec/cop.rb
Expand Up @@ -17,7 +17,7 @@ module RSpec
# # Patterns:
# # - '_test.rb$'
# # - '(?:^|/)test/'
class Cop < ::RuboCop::Cop::Cop
class Cop < ::RuboCop::Cop::Base
include RuboCop::RSpec::Language
include RuboCop::RSpec::Language::NodePattern

Expand Down
17 changes: 10 additions & 7 deletions lib/rubocop/cop/rspec/described_class.rb
Expand Up @@ -55,6 +55,7 @@ module RSpec
# end
#
class DescribedClass < Cop
extend AutoCorrector
include ConfigurableEnforcedStyle

DESCRIBED_CLASS = 'described_class'
Expand Down Expand Up @@ -85,22 +86,24 @@ def on_block(node)
return unless body

find_usage(body) do |match|
add_offense(match, message: message(match.const_name))
msg = message(match.const_name)
add_offense(match, message: msg) do |corrector|
autocorrect(corrector, match)
end
end
end

def autocorrect(node)
private

def autocorrect(corrector, match)
replacement = if style == :described_class
DESCRIBED_CLASS
else
@described_class.const_name
end
lambda do |corrector|
corrector.replace(node.loc.expression, replacement)
end
end

private
corrector.replace(match, replacement)
end

def find_usage(node, &block)
yield(node) if offensive?(node)
Expand Down
15 changes: 4 additions & 11 deletions lib/rubocop/cop/rspec/dialect.rb
Expand Up @@ -42,6 +42,7 @@ module RSpec
# # ...
# end
class Dialect < Cop
extend AutoCorrector
include MethodPreference

MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
Expand All @@ -52,24 +53,16 @@ def on_send(node)
return unless rspec_method?(node)
return unless preferred_methods[node.method_name]

add_offense(node)
end
msg = format(MSG, prefer: preferred_method(node.method_name),
current: node.method_name)

def autocorrect(node)
lambda do |corrector|
add_offense(node, message: msg) do |corrector|
current = node.loc.selector
preferred = preferred_method(current.source)

corrector.replace(current, preferred)
end
end

private

def message(node)
format(MSG, prefer: preferred_method(node.method_name),
current: node.method_name)
end
end
end
end
Expand Down
14 changes: 5 additions & 9 deletions lib/rubocop/cop/rspec/empty_hook.rb
Expand Up @@ -23,6 +23,7 @@ module RSpec
# end
# after(:all) { cleanup_feed }
class EmptyHook < Cop
extend AutoCorrector
include RuboCop::Cop::RangeHelp

MSG = 'Empty hook detected.'
Expand All @@ -33,15 +34,10 @@ class EmptyHook < Cop

def on_block(node)
empty_hook?(node) do |hook|
add_offense(hook)
end
end

def autocorrect(node)
lambda do |corrector|
block = node.parent
range = range_with_surrounding_space(range: block.loc.expression)
corrector.remove(range)
add_offense(hook) do |corrector|
range = range_with_surrounding_space(range: node.loc.expression)
corrector.remove(range)
end
end
end
end
Expand Down