Skip to content

Commit b53f08a

Browse files
authored
Merge pull request #955 from rubocop-hq/new-rubocop-autocorrect
New RuboCop autocorrect
2 parents e6857d8 + ac953d8 commit b53f08a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+385
-522
lines changed

.rubocop_todo.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ InternalAffairs/MethodNameEqual:
1414
# Offense count: 1
1515
# Configuration parameters: CountComments.
1616
Metrics/ClassLength:
17-
Max: 104
17+
Max: 106

lib/rubocop/cop/rspec/align_left_let_brace.rb

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,28 @@ module RSpec
1818
# let(:a) { b }
1919
#
2020
class AlignLeftLetBrace < Cop
21+
extend AutoCorrector
22+
2123
MSG = 'Align left let brace'
2224

2325
def self.autocorrect_incompatible_with
2426
[Layout::ExtraSpacing]
2527
end
2628

27-
def investigate(_processed_source)
29+
def on_new_investigation
2830
return if processed_source.blank?
2931

30-
token_aligner.offending_tokens.each do |let|
31-
add_offense(let, location: :begin)
32-
end
33-
end
32+
token_aligner =
33+
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
3434

35-
def autocorrect(let)
36-
lambda do |corrector|
37-
corrector.insert_before(
38-
let.loc.begin,
39-
token_aligner.indent_for(let)
40-
)
35+
token_aligner.offending_tokens.each do |let|
36+
add_offense(let.loc.begin) do |corrector|
37+
corrector.insert_before(
38+
let.loc.begin, token_aligner.indent_for(let)
39+
)
40+
end
4141
end
4242
end
43-
44-
private
45-
46-
def token_aligner
47-
@token_aligner ||=
48-
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
49-
end
5043
end
5144
end
5245
end

lib/rubocop/cop/rspec/align_right_let_brace.rb

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,28 @@ module RSpec
1818
# let(:a) { b }
1919
#
2020
class AlignRightLetBrace < Cop
21+
extend AutoCorrector
22+
2123
MSG = 'Align right let brace'
2224

2325
def self.autocorrect_incompatible_with
2426
[Layout::ExtraSpacing]
2527
end
2628

27-
def investigate(_processed_source)
29+
def on_new_investigation
2830
return if processed_source.blank?
2931

30-
token_aligner.offending_tokens.each do |let|
31-
add_offense(let, location: :end)
32-
end
33-
end
32+
token_aligner =
33+
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
3434

35-
def autocorrect(let)
36-
lambda do |corrector|
37-
corrector.insert_before(
38-
let.loc.end,
39-
token_aligner.indent_for(let)
40-
)
35+
token_aligner.offending_tokens.each do |let|
36+
add_offense(let.loc.end) do |corrector|
37+
corrector.insert_before(
38+
let.loc.end, token_aligner.indent_for(let)
39+
)
40+
end
4141
end
4242
end
43-
44-
private
45-
46-
def token_aligner
47-
@token_aligner ||=
48-
RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
49-
end
5043
end
5144
end
5245
end

lib/rubocop/cop/rspec/be.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Be < Cop
2828

2929
def on_send(node)
3030
be_without_args(node) do |matcher|
31-
add_offense(matcher, location: :selector)
31+
add_offense(matcher.loc.selector)
3232
end
3333
end
3434
end

lib/rubocop/cop/rspec/be_eql.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ module RSpec
3636
# coerce objects for comparison.
3737
#
3838
class BeEql < Cop
39+
extend AutoCorrector
40+
3941
MSG = 'Prefer `be` over `eql`.'
4042

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

4547
def on_send(node)
4648
eql_type_with_identity(node) do |eql|
47-
add_offense(eql, location: :selector)
49+
add_offense(eql.loc.selector) do |corrector|
50+
corrector.replace(eql.loc.selector, 'be')
51+
end
4852
end
4953
end
50-
51-
def autocorrect(node)
52-
->(corrector) { corrector.replace(node.loc.selector, 'be') }
53-
end
5454
end
5555
end
5656
end

lib/rubocop/cop/rspec/capybara/current_path_expectation.rb

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ module Capybara
2424
# expect(page).to have_current_path(/widgets/)
2525
#
2626
class CurrentPathExpectation < Cop
27+
extend AutoCorrector
28+
2729
MSG = 'Do not set an RSpec expectation on `current_path` in ' \
2830
'Capybara feature specs - instead, use the ' \
2931
'`have_current_path` matcher on `page`'
@@ -47,30 +49,30 @@ class CurrentPathExpectation < Cop
4749

4850
def on_send(node)
4951
expectation_set_on_current_path(node) do
50-
add_offense(node, location: :selector)
52+
add_offense(node.loc.selector) do |corrector|
53+
next unless node.chained?
54+
55+
autocorrect(corrector, node)
56+
end
5157
end
5258
end
5359

54-
def autocorrect(node)
55-
lambda do |corrector|
56-
return unless node.chained?
60+
private
5761

58-
as_is_matcher(node.parent) do |to_sym, matcher_node|
59-
rewrite_expectation(corrector, node, to_sym, matcher_node)
60-
end
62+
def autocorrect(corrector, node)
63+
as_is_matcher(node.parent) do |to_sym, matcher_node|
64+
rewrite_expectation(corrector, node, to_sym, matcher_node)
65+
end
6166

62-
regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
63-
rewrite_expectation(corrector, node, to_sym, matcher_node)
64-
convert_regexp_str_to_literal(corrector, matcher_node, regexp)
65-
end
67+
regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
68+
rewrite_expectation(corrector, node, to_sym, matcher_node)
69+
convert_regexp_str_to_literal(corrector, matcher_node, regexp)
6670
end
6771
end
6872

69-
private
70-
7173
def rewrite_expectation(corrector, node, to_symbol, matcher_node)
7274
current_path_node = node.first_argument
73-
corrector.replace(current_path_node.loc.expression, 'page')
75+
corrector.replace(current_path_node, 'page')
7476
corrector.replace(node.parent.loc.selector, 'to')
7577
matcher_method = if to_symbol == :to
7678
'have_current_path'
@@ -84,7 +86,7 @@ def rewrite_expectation(corrector, node, to_symbol, matcher_node)
8486
def convert_regexp_str_to_literal(corrector, matcher_node, regexp_str)
8587
str_node = matcher_node.first_argument
8688
regexp_expr = Regexp.new(regexp_str).inspect
87-
corrector.replace(str_node.loc.expression, regexp_expr)
89+
corrector.replace(str_node, regexp_expr)
8890
end
8991

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

99101
corrector.insert_after(
100-
expectation_last_child.loc.expression,
102+
expectation_last_child,
101103
', ignore_query: true'
102104
)
103105
end

lib/rubocop/cop/rspec/capybara/feature_methods.rb

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ module Capybara
4141
# end
4242
# end
4343
class FeatureMethods < Cop
44+
extend AutoCorrector
45+
4446
MSG = 'Use `%<replacement>s` instead of `%<method>s`.'
4547

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

74-
add_offense(
75-
send_node,
76-
location: :selector,
77-
message: format(MSG, method: match, replacement: MAP[match])
78-
)
76+
add_offense(send_node.loc.selector) do |corrector|
77+
corrector.replace(send_node.loc.selector, MAP[match].to_s)
78+
end
7979
end
8080
end
8181

82-
def autocorrect(node)
83-
lambda do |corrector|
84-
corrector.replace(node.loc.selector, MAP[node.method_name].to_s)
85-
end
82+
def message(range)
83+
name = range.source.to_sym
84+
format(MSG, method: name, replacement: MAP[name])
8685
end
8786

8887
private

lib/rubocop/cop/rspec/context_method.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ module RSpec
2424
# # ...
2525
# end
2626
class ContextMethod < Cop
27+
extend AutoCorrector
28+
2729
MSG = 'Use `describe` for testing methods.'
2830

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

3335
def on_block(node)
3436
context_method(node) do |context|
35-
add_offense(context)
36-
end
37-
end
38-
39-
def autocorrect(node)
40-
lambda do |corrector|
41-
corrector.replace(node.parent.loc.selector, 'describe')
37+
add_offense(context) do |corrector|
38+
corrector.replace(node.send_node.loc.selector, 'describe')
39+
end
4240
end
4341
end
4442

lib/rubocop/cop/rspec/cop.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ module RSpec
1717
# # Patterns:
1818
# # - '_test.rb$'
1919
# # - '(?:^|/)test/'
20-
class Cop < ::RuboCop::Cop::Cop
20+
class Cop < ::RuboCop::Cop::Base
2121
include RuboCop::RSpec::Language
2222
include RuboCop::RSpec::Language::NodePattern
2323

lib/rubocop/cop/rspec/described_class.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ module RSpec
5555
# end
5656
#
5757
class DescribedClass < Cop
58+
extend AutoCorrector
5859
include ConfigurableEnforcedStyle
5960

6061
DESCRIBED_CLASS = 'described_class'
@@ -85,22 +86,24 @@ def on_block(node)
8586
return unless body
8687

8788
find_usage(body) do |match|
88-
add_offense(match, message: message(match.const_name))
89+
msg = message(match.const_name)
90+
add_offense(match, message: msg) do |corrector|
91+
autocorrect(corrector, match)
92+
end
8993
end
9094
end
9195

92-
def autocorrect(node)
96+
private
97+
98+
def autocorrect(corrector, match)
9399
replacement = if style == :described_class
94100
DESCRIBED_CLASS
95101
else
96102
@described_class.const_name
97103
end
98-
lambda do |corrector|
99-
corrector.replace(node.loc.expression, replacement)
100-
end
101-
end
102104

103-
private
105+
corrector.replace(match, replacement)
106+
end
104107

105108
def find_usage(node, &block)
106109
yield(node) if offensive?(node)

0 commit comments

Comments
 (0)