rubocop-rspec 1.38.1 → 1.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +57 -0
- data/CODE_OF_CONDUCT.md +17 -0
- data/README.md +1 -61
- data/config/default.yml +159 -19
- data/lib/rubocop-rspec.rb +5 -2
- data/lib/rubocop/cop/rspec/align_left_let_brace.rb +12 -19
- data/lib/rubocop/cop/rspec/align_right_let_brace.rb +12 -19
- data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
- data/lib/rubocop/cop/rspec/around_block.rb +1 -1
- data/lib/rubocop/cop/rspec/base.rb +74 -0
- data/lib/rubocop/cop/rspec/be.rb +2 -2
- data/lib/rubocop/cop/rspec/be_eql.rb +6 -6
- data/lib/rubocop/cop/rspec/before_after_all.rb +1 -1
- data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +19 -17
- data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +14 -12
- data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +69 -0
- data/lib/rubocop/cop/rspec/context_method.rb +7 -9
- data/lib/rubocop/cop/rspec/context_wording.rb +3 -3
- data/lib/rubocop/cop/rspec/cop.rb +3 -87
- data/lib/rubocop/cop/rspec/describe_class.rb +29 -23
- data/lib/rubocop/cop/rspec/describe_method.rb +14 -7
- data/lib/rubocop/cop/rspec/describe_symbol.rb +2 -2
- data/lib/rubocop/cop/rspec/described_class.rb +12 -9
- data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
- data/lib/rubocop/cop/rspec/dialect.rb +5 -12
- data/lib/rubocop/cop/rspec/empty_example_group.rb +91 -7
- data/lib/rubocop/cop/rspec/empty_hook.rb +46 -0
- data/lib/rubocop/cop/rspec/empty_line_after_example.rb +5 -7
- data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +5 -9
- data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +8 -8
- data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +5 -9
- data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +6 -6
- data/lib/rubocop/cop/rspec/example_length.rb +1 -1
- data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
- data/lib/rubocop/cop/rspec/example_wording.rb +10 -11
- data/lib/rubocop/cop/rspec/expect_actual.rb +8 -11
- data/lib/rubocop/cop/rspec/expect_change.rb +10 -35
- data/lib/rubocop/cop/rspec/expect_in_hook.rb +3 -3
- data/lib/rubocop/cop/rspec/expect_output.rb +2 -2
- data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +24 -21
- data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +20 -22
- data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +7 -8
- data/lib/rubocop/cop/rspec/file_path.rb +57 -21
- data/lib/rubocop/cop/rspec/focus.rb +7 -11
- data/lib/rubocop/cop/rspec/hook_argument.rb +16 -23
- data/lib/rubocop/cop/rspec/hooks_before_examples.rb +10 -29
- data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/implicit_expect.rb +7 -15
- data/lib/rubocop/cop/rspec/implicit_subject.rb +16 -11
- data/lib/rubocop/cop/rspec/instance_spy.rb +18 -12
- data/lib/rubocop/cop/rspec/instance_variable.rb +4 -8
- data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +3 -6
- data/lib/rubocop/cop/rspec/it_behaves_like.rb +5 -6
- data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
- data/lib/rubocop/cop/rspec/leading_subject.rb +22 -26
- data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +2 -5
- data/lib/rubocop/cop/rspec/let_before_examples.rb +10 -26
- data/lib/rubocop/cop/rspec/let_setup.rb +21 -6
- data/lib/rubocop/cop/rspec/message_chain.rb +7 -6
- data/lib/rubocop/cop/rspec/message_expectation.rb +2 -2
- data/lib/rubocop/cop/rspec/message_spies.rb +2 -3
- data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
- data/lib/rubocop/cop/rspec/multiple_describes.rb +11 -8
- data/lib/rubocop/cop/rspec/multiple_expectations.rb +7 -11
- data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +148 -0
- data/lib/rubocop/cop/rspec/multiple_subjects.rb +18 -19
- data/lib/rubocop/cop/rspec/named_subject.rb +8 -8
- data/lib/rubocop/cop/rspec/nested_groups.rb +12 -13
- data/lib/rubocop/cop/rspec/not_to_not.rb +5 -6
- data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/pending.rb +1 -1
- data/lib/rubocop/cop/rspec/predicate_matcher.rb +32 -69
- data/lib/rubocop/cop/rspec/rails/http_status.rb +7 -9
- data/lib/rubocop/cop/rspec/receive_counts.rb +15 -17
- data/lib/rubocop/cop/rspec/receive_never.rb +12 -12
- data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
- data/lib/rubocop/cop/rspec/repeated_example.rb +2 -2
- data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +12 -2
- data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +1 -1
- data/lib/rubocop/cop/rspec/return_from_stub.rb +12 -22
- data/lib/rubocop/cop/rspec/scattered_let.rb +12 -2
- data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
- data/lib/rubocop/cop/rspec/shared_context.rb +8 -21
- data/lib/rubocop/cop/rspec/shared_examples.rb +7 -9
- data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +15 -18
- data/lib/rubocop/cop/rspec/subject_stub.rb +25 -53
- data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -1
- data/lib/rubocop/cop/rspec/variable_definition.rb +56 -0
- data/lib/rubocop/cop/rspec/variable_name.rb +66 -0
- data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
- data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
- data/lib/rubocop/cop/rspec/yield.rb +14 -11
- data/lib/rubocop/cop/rspec_cops.rb +6 -1
- data/lib/rubocop/rspec/corrector/move_node.rb +54 -0
- data/lib/rubocop/rspec/description_extractor.rb +2 -6
- data/lib/rubocop/rspec/{blank_line_separation.rb → empty_line_separation.rb} +13 -10
- data/lib/rubocop/rspec/example_group.rb +21 -49
- data/lib/rubocop/rspec/factory_bot.rb +7 -1
- data/lib/rubocop/rspec/language.rb +13 -3
- data/lib/rubocop/rspec/language/node_pattern.rb +11 -2
- data/lib/rubocop/rspec/top_level_describe.rb +2 -2
- data/lib/rubocop/rspec/top_level_group.rb +55 -0
- data/lib/rubocop/rspec/variable.rb +16 -0
- data/lib/rubocop/rspec/version.rb +1 -1
- metadata +36 -13
- data/lib/rubocop/rspec/util.rb +0 -19
@@ -14,11 +14,14 @@ module RuboCop
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def check_inflected(node)
|
17
|
-
predicate_in_actual?(node) do |predicate|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
predicate_in_actual?(node) do |predicate, to, matcher|
|
18
|
+
msg = message_inflected(predicate)
|
19
|
+
add_offense(node, message: msg) do |corrector|
|
20
|
+
remove_predicate(corrector, predicate)
|
21
|
+
corrector.replace(node.loc.selector,
|
22
|
+
true?(to, matcher) ? 'to' : 'not_to')
|
23
|
+
rewrite_matcher(corrector, predicate, matcher)
|
24
|
+
end
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
@@ -76,17 +79,6 @@ module RuboCop
|
|
76
79
|
end
|
77
80
|
# rubocop:enable Metrics/MethodLength
|
78
81
|
|
79
|
-
def autocorrect_inflected(node)
|
80
|
-
predicate_in_actual?(node) do |predicate, to, matcher|
|
81
|
-
lambda do |corrector|
|
82
|
-
remove_predicate(corrector, predicate)
|
83
|
-
corrector.replace(node.loc.selector,
|
84
|
-
true?(to, matcher) ? 'to' : 'not_to')
|
85
|
-
rewrite_matcher(corrector, predicate, matcher)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
82
|
def remove_predicate(corrector, predicate)
|
91
83
|
range = predicate.loc.dot.with(
|
92
84
|
end_pos: predicate.loc.expression.end_pos
|
@@ -123,7 +115,6 @@ module RuboCop
|
|
123
115
|
end
|
124
116
|
|
125
117
|
# A helper for `explicit` style
|
126
|
-
# rubocop:disable Metrics/ModuleLength
|
127
118
|
module ExplicitHelper
|
128
119
|
include RuboCop::RSpec::Language
|
129
120
|
extend NodePattern::Macros
|
@@ -143,22 +134,21 @@ module RuboCop
|
|
143
134
|
end
|
144
135
|
|
145
136
|
def check_explicit(node) # rubocop:disable Metrics/MethodLength
|
146
|
-
predicate_matcher_block?(node) do |
|
147
|
-
add_offense(
|
148
|
-
node
|
149
|
-
|
150
|
-
|
137
|
+
predicate_matcher_block?(node) do |actual, matcher|
|
138
|
+
add_offense(node, message: message_explicit(matcher)) do |corrector|
|
139
|
+
to_node = node.send_node
|
140
|
+
corrector_explicit(corrector, to_node, actual, matcher, to_node)
|
141
|
+
end
|
151
142
|
ignore_node(node.children.first)
|
152
143
|
return
|
153
144
|
end
|
154
145
|
|
155
146
|
return if part_of_ignored_node?(node)
|
156
147
|
|
157
|
-
predicate_matcher?(node) do |
|
158
|
-
add_offense(
|
159
|
-
node,
|
160
|
-
|
161
|
-
)
|
148
|
+
predicate_matcher?(node) do |actual, matcher|
|
149
|
+
add_offense(node, message: message_explicit(matcher)) do |corrector|
|
150
|
+
corrector_explicit(corrector, node, actual, matcher, matcher)
|
151
|
+
end
|
162
152
|
end
|
163
153
|
end
|
164
154
|
|
@@ -193,31 +183,11 @@ module RuboCop
|
|
193
183
|
matcher_name: matcher.method_name)
|
194
184
|
end
|
195
185
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
def autocorrect_explicit_send(node)
|
202
|
-
predicate_matcher?(node) do |actual, matcher|
|
203
|
-
corrector_explicit(node, actual, matcher, matcher)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
def autocorrect_explicit_block(node)
|
208
|
-
predicate_matcher_block?(node) do |actual, matcher|
|
209
|
-
to_node = node.send_node
|
210
|
-
corrector_explicit(to_node, actual, matcher, to_node)
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
def corrector_explicit(to_node, actual, matcher, block_child)
|
215
|
-
lambda do |corrector|
|
216
|
-
replacement_matcher = replacement_matcher(to_node)
|
217
|
-
corrector.replace(matcher.loc.expression, replacement_matcher)
|
218
|
-
move_predicate(corrector, actual, matcher, block_child)
|
219
|
-
corrector.replace(to_node.loc.selector, 'to')
|
220
|
-
end
|
186
|
+
def corrector_explicit(corrector, to_node, actual, matcher, block_child)
|
187
|
+
replacement_matcher = replacement_matcher(to_node)
|
188
|
+
corrector.replace(matcher.loc.expression, replacement_matcher)
|
189
|
+
move_predicate(corrector, actual, matcher, block_child)
|
190
|
+
corrector.replace(to_node.loc.selector, 'to')
|
221
191
|
end
|
222
192
|
|
223
193
|
def move_predicate(corrector, actual, matcher, block_child)
|
@@ -238,18 +208,20 @@ module RuboCop
|
|
238
208
|
'is_a?'
|
239
209
|
when 'be_an_instance_of', 'be_instance_of', 'an_instance_of'
|
240
210
|
'instance_of?'
|
241
|
-
when 'include'
|
242
|
-
|
211
|
+
when 'include'
|
212
|
+
'include?'
|
213
|
+
when 'respond_to'
|
214
|
+
'respond_to?'
|
243
215
|
when /^have_(.+)/
|
244
216
|
"has_#{Regexp.last_match(1)}?"
|
245
217
|
else
|
246
|
-
matcher[/^be_(.+)/, 1]
|
218
|
+
"#{matcher[/^be_(.+)/, 1]}?"
|
247
219
|
end
|
248
220
|
end
|
249
221
|
# rubocop:enable Metrics/MethodLength
|
250
222
|
|
251
223
|
def replacement_matcher(node)
|
252
|
-
case [cop_config['Strict'], node.
|
224
|
+
case [cop_config['Strict'], node.method?(:to)]
|
253
225
|
when [true, true]
|
254
226
|
'be(true)'
|
255
227
|
when [true, false]
|
@@ -261,7 +233,6 @@ module RuboCop
|
|
261
233
|
end
|
262
234
|
end
|
263
235
|
end
|
264
|
-
# rubocop:enable Metrics/ModuleLength
|
265
236
|
|
266
237
|
# Prefer using predicate matcher over using predicate method directly.
|
267
238
|
#
|
@@ -277,12 +248,12 @@ module RuboCop
|
|
277
248
|
# expect(foo).to be_something
|
278
249
|
#
|
279
250
|
# # also good - It checks "true" strictly.
|
280
|
-
# expect(foo).to be(true)
|
251
|
+
# expect(foo.something?).to be(true)
|
281
252
|
#
|
282
253
|
# @example Strict: false, EnforcedStyle: inflected
|
283
254
|
# # bad
|
284
255
|
# expect(foo.something?).to be_truthy
|
285
|
-
# expect(foo).to be(true)
|
256
|
+
# expect(foo.something?).to be(true)
|
286
257
|
#
|
287
258
|
# # good
|
288
259
|
# expect(foo).to be_something
|
@@ -300,7 +271,8 @@ module RuboCop
|
|
300
271
|
#
|
301
272
|
# # good - the above code is rewritten to it by this cop
|
302
273
|
# expect(foo.something?).to be_truthy
|
303
|
-
class PredicateMatcher <
|
274
|
+
class PredicateMatcher < Base
|
275
|
+
extend AutoCorrector
|
304
276
|
include ConfigurableEnforcedStyle
|
305
277
|
include InflectedHelper
|
306
278
|
include ExplicitHelper
|
@@ -318,15 +290,6 @@ module RuboCop
|
|
318
290
|
check_explicit(node) if style == :explicit
|
319
291
|
end
|
320
292
|
|
321
|
-
def autocorrect(node)
|
322
|
-
case style
|
323
|
-
when :inflected
|
324
|
-
autocorrect_inflected(node)
|
325
|
-
when :explicit
|
326
|
-
autocorrect_explicit(node)
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
293
|
private
|
331
294
|
|
332
295
|
# returns args location with whitespace
|
@@ -30,7 +30,8 @@ module RuboCop
|
|
30
30
|
# it { is_expected.to have_http_status :success }
|
31
31
|
# it { is_expected.to have_http_status :error }
|
32
32
|
#
|
33
|
-
class HttpStatus <
|
33
|
+
class HttpStatus < Base
|
34
|
+
extend AutoCorrector
|
34
35
|
include ConfigurableEnforcedStyle
|
35
36
|
|
36
37
|
def_node_matcher :http_status, <<-PATTERN
|
@@ -42,14 +43,9 @@ module RuboCop
|
|
42
43
|
checker = checker_class.new(ast_node)
|
43
44
|
return unless checker.offensive?
|
44
45
|
|
45
|
-
add_offense(checker.node, message: checker.message)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
def autocorrect(node)
|
50
|
-
lambda do |corrector|
|
51
|
-
checker = checker_class.new(node)
|
52
|
-
corrector.replace(node.loc.expression, checker.preferred_style)
|
46
|
+
add_offense(checker.node, message: checker.message) do |corrector|
|
47
|
+
corrector.replace(checker.node, checker.preferred_style)
|
48
|
+
end
|
53
49
|
end
|
54
50
|
end
|
55
51
|
|
@@ -70,6 +66,7 @@ module RuboCop
|
|
70
66
|
'to describe HTTP status code.'
|
71
67
|
|
72
68
|
attr_reader :node
|
69
|
+
|
73
70
|
def initialize(node)
|
74
71
|
@node = node
|
75
72
|
end
|
@@ -110,6 +107,7 @@ module RuboCop
|
|
110
107
|
ALLOWED_STATUSES = %i[error success missing redirect].freeze
|
111
108
|
|
112
109
|
attr_reader :node
|
110
|
+
|
113
111
|
def initialize(node)
|
114
112
|
@node = node
|
115
113
|
end
|
@@ -23,7 +23,9 @@ module RuboCop
|
|
23
23
|
# expect(foo).to receive(:bar).at_most(:once)
|
24
24
|
# expect(foo).to receive(:bar).at_most(:twice).times
|
25
25
|
#
|
26
|
-
class ReceiveCounts <
|
26
|
+
class ReceiveCounts < Base
|
27
|
+
extend AutoCorrector
|
28
|
+
|
27
29
|
MSG = 'Use `%<alternative>s` instead of `%<original>s`.'
|
28
30
|
|
29
31
|
def_node_matcher :receive_counts, <<-PATTERN
|
@@ -38,27 +40,23 @@ module RuboCop
|
|
38
40
|
|
39
41
|
offending_range = range(node, offending_node)
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
)
|
43
|
+
msg = message_for(offending_node, offending_range.source)
|
44
|
+
add_offense(offending_range, message: msg) do |corrector|
|
45
|
+
autocorrect(corrector, offending_node, offending_range)
|
46
|
+
end
|
46
47
|
end
|
47
48
|
end
|
48
49
|
|
49
|
-
|
50
|
-
lambda do |corrector|
|
51
|
-
replacement = matcher_for(
|
52
|
-
node.method_name,
|
53
|
-
node.first_argument.source.to_i
|
54
|
-
)
|
50
|
+
private
|
55
51
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
def autocorrect(corrector, node, range)
|
53
|
+
replacement = matcher_for(
|
54
|
+
node.method_name,
|
55
|
+
node.first_argument.source.to_i
|
56
|
+
)
|
60
57
|
|
61
|
-
|
58
|
+
corrector.replace(range, replacement)
|
59
|
+
end
|
62
60
|
|
63
61
|
def message_for(node, source)
|
64
62
|
alternative = matcher_for(
|
@@ -13,26 +13,26 @@ module RuboCop
|
|
13
13
|
# # good
|
14
14
|
# expect(foo).not_to receive(:bar)
|
15
15
|
#
|
16
|
-
class ReceiveNever <
|
16
|
+
class ReceiveNever < Base
|
17
|
+
extend AutoCorrector
|
17
18
|
MSG = 'Use `not_to receive` instead of `never`.'
|
18
19
|
|
19
20
|
def_node_search :method_on_stub?, '(send nil? :receive ...)'
|
20
21
|
|
21
22
|
def on_send(node)
|
22
|
-
return unless node.
|
23
|
+
return unless node.method?(:never) && method_on_stub?(node)
|
23
24
|
|
24
|
-
add_offense(
|
25
|
-
node
|
26
|
-
|
27
|
-
)
|
25
|
+
add_offense(node.loc.selector) do |corrector|
|
26
|
+
autocorrect(corrector, node)
|
27
|
+
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
private
|
31
|
+
|
32
|
+
def autocorrect(corrector, node)
|
33
|
+
corrector.replace(node.parent.loc.selector, 'not_to')
|
34
|
+
range = node.loc.dot.with(end_pos: node.loc.selector.end_pos)
|
35
|
+
corrector.remove(range)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -15,7 +15,7 @@ module RuboCop
|
|
15
15
|
# expect(user).to be_valid
|
16
16
|
# end
|
17
17
|
#
|
18
|
-
class RepeatedExample <
|
18
|
+
class RepeatedExample < Base
|
19
19
|
MSG = "Don't repeat examples within an example group."
|
20
20
|
|
21
21
|
def on_block(node)
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
def example_signature(example)
|
42
42
|
key_parts = [example.metadata, example.implementation]
|
43
43
|
|
44
|
-
if example.definition.
|
44
|
+
if example.definition.method?(:its)
|
45
45
|
key_parts << example.definition.arguments
|
46
46
|
end
|
47
47
|
|
@@ -34,7 +34,16 @@ module RuboCop
|
|
34
34
|
# it { cool_predicate }
|
35
35
|
# end
|
36
36
|
#
|
37
|
-
|
37
|
+
# # good
|
38
|
+
# context Array do
|
39
|
+
# it { is_expected.to respond_to :each }
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# context Hash do
|
43
|
+
# it { is_expected.to respond_to :each }
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
class RepeatedExampleGroupBody < Base
|
38
47
|
MSG = 'Repeated %<group>s block body on line(s) %<loc>s'
|
39
48
|
|
40
49
|
def_node_matcher :several_example_groups?, <<-PATTERN
|
@@ -43,6 +52,7 @@ module RuboCop
|
|
43
52
|
|
44
53
|
def_node_matcher :metadata, '(block (send _ _ _ $...) ...)'
|
45
54
|
def_node_matcher :body, '(block _ args $...)'
|
55
|
+
def_node_matcher :const_arg, '(block (send _ _ $const ...) ...)'
|
46
56
|
|
47
57
|
def_node_matcher :skip_or_pending?, <<-PATTERN
|
48
58
|
(block <(send nil? {:skip :pending}) ...>)
|
@@ -75,7 +85,7 @@ module RuboCop
|
|
75
85
|
end
|
76
86
|
|
77
87
|
def signature_keys(group)
|
78
|
-
[metadata(group), body(group)]
|
88
|
+
[metadata(group), body(group), const_arg(group)]
|
79
89
|
end
|
80
90
|
|
81
91
|
def message(group, repeats)
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
43
43
|
# # example group
|
44
44
|
# end
|
45
45
|
#
|
46
|
-
class RepeatedExampleGroupDescription <
|
46
|
+
class RepeatedExampleGroupDescription < Base
|
47
47
|
MSG = 'Repeated %<group>s block description on line(s) %<loc>s'
|
48
48
|
|
49
49
|
def_node_matcher :several_example_groups?, <<-PATTERN
|
@@ -33,49 +33,41 @@ module RuboCop
|
|
33
33
|
# # also good as the returned value is dynamic
|
34
34
|
# allow(Foo).to receive(:bar) { bar.baz }
|
35
35
|
#
|
36
|
-
class ReturnFromStub <
|
36
|
+
class ReturnFromStub < Base
|
37
|
+
extend AutoCorrector
|
37
38
|
include ConfigurableEnforcedStyle
|
38
39
|
|
39
40
|
MSG_AND_RETURN = 'Use `and_return` for static values.'
|
40
41
|
MSG_BLOCK = 'Use block for static values.'
|
41
42
|
|
42
43
|
def_node_search :contains_stub?, '(send nil? :receive (...))'
|
44
|
+
def_node_matcher :stub_with_block?, '(block #contains_stub? ...)'
|
43
45
|
def_node_search :and_return_value, <<-PATTERN
|
44
46
|
$(send _ :and_return $(...))
|
45
47
|
PATTERN
|
46
48
|
|
47
49
|
def on_send(node)
|
48
|
-
return unless contains_stub?(node)
|
49
50
|
return unless style == :block
|
51
|
+
return unless contains_stub?(node)
|
50
52
|
|
51
53
|
check_and_return_call(node)
|
52
54
|
end
|
53
55
|
|
54
56
|
def on_block(node)
|
55
|
-
return unless contains_stub?(node)
|
56
57
|
return unless style == :and_return
|
58
|
+
return unless stub_with_block?(node)
|
57
59
|
|
58
60
|
check_block_body(node)
|
59
61
|
end
|
60
62
|
|
61
|
-
def autocorrect(node)
|
62
|
-
if style == :block
|
63
|
-
AndReturnCallCorrector.new(node)
|
64
|
-
else
|
65
|
-
BlockBodyCorrector.new(node)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
63
|
private
|
70
64
|
|
71
65
|
def check_and_return_call(node)
|
72
66
|
and_return_value(node) do |and_return, args|
|
73
67
|
unless dynamic?(args)
|
74
|
-
add_offense(
|
75
|
-
and_return
|
76
|
-
|
77
|
-
message: MSG_BLOCK
|
78
|
-
)
|
68
|
+
add_offense(and_return.loc.selector, message: MSG_BLOCK) do |corr|
|
69
|
+
AndReturnCallCorrector.new(and_return).call(corr)
|
70
|
+
end
|
79
71
|
end
|
80
72
|
end
|
81
73
|
end
|
@@ -83,11 +75,9 @@ module RuboCop
|
|
83
75
|
def check_block_body(block)
|
84
76
|
body = block.body
|
85
77
|
unless dynamic?(body) # rubocop:disable Style/GuardClause
|
86
|
-
add_offense(
|
87
|
-
block
|
88
|
-
|
89
|
-
message: MSG_AND_RETURN
|
90
|
-
)
|
78
|
+
add_offense(block.loc.begin, message: MSG_AND_RETURN) do |corrector|
|
79
|
+
BlockBodyCorrector.new(block).call(corrector)
|
80
|
+
end
|
91
81
|
end
|
92
82
|
end
|
93
83
|
|
@@ -152,7 +142,7 @@ module RuboCop
|
|
152
142
|
return if heredoc?
|
153
143
|
|
154
144
|
corrector.replace(
|
155
|
-
block
|
145
|
+
block,
|
156
146
|
"#{block.send_node.source}.and_return(#{body.source})"
|
157
147
|
)
|
158
148
|
end
|