rubocop-rspec 1.38.1 → 1.43.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -0
  3. data/CODE_OF_CONDUCT.md +17 -0
  4. data/README.md +1 -61
  5. data/config/default.yml +159 -19
  6. data/lib/rubocop-rspec.rb +5 -2
  7. data/lib/rubocop/cop/rspec/align_left_let_brace.rb +12 -19
  8. data/lib/rubocop/cop/rspec/align_right_let_brace.rb +12 -19
  9. data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
  10. data/lib/rubocop/cop/rspec/around_block.rb +1 -1
  11. data/lib/rubocop/cop/rspec/base.rb +74 -0
  12. data/lib/rubocop/cop/rspec/be.rb +2 -2
  13. data/lib/rubocop/cop/rspec/be_eql.rb +6 -6
  14. data/lib/rubocop/cop/rspec/before_after_all.rb +1 -1
  15. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +19 -17
  16. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +14 -12
  17. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +69 -0
  18. data/lib/rubocop/cop/rspec/context_method.rb +7 -9
  19. data/lib/rubocop/cop/rspec/context_wording.rb +3 -3
  20. data/lib/rubocop/cop/rspec/cop.rb +3 -87
  21. data/lib/rubocop/cop/rspec/describe_class.rb +29 -23
  22. data/lib/rubocop/cop/rspec/describe_method.rb +14 -7
  23. data/lib/rubocop/cop/rspec/describe_symbol.rb +2 -2
  24. data/lib/rubocop/cop/rspec/described_class.rb +12 -9
  25. data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
  26. data/lib/rubocop/cop/rspec/dialect.rb +5 -12
  27. data/lib/rubocop/cop/rspec/empty_example_group.rb +91 -7
  28. data/lib/rubocop/cop/rspec/empty_hook.rb +46 -0
  29. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +5 -7
  30. data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +5 -9
  31. data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +8 -8
  32. data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +5 -9
  33. data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +6 -6
  34. data/lib/rubocop/cop/rspec/example_length.rb +1 -1
  35. data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
  36. data/lib/rubocop/cop/rspec/example_wording.rb +10 -11
  37. data/lib/rubocop/cop/rspec/expect_actual.rb +8 -11
  38. data/lib/rubocop/cop/rspec/expect_change.rb +10 -35
  39. data/lib/rubocop/cop/rspec/expect_in_hook.rb +3 -3
  40. data/lib/rubocop/cop/rspec/expect_output.rb +2 -2
  41. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +24 -21
  42. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +20 -22
  43. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +7 -8
  44. data/lib/rubocop/cop/rspec/file_path.rb +57 -21
  45. data/lib/rubocop/cop/rspec/focus.rb +7 -11
  46. data/lib/rubocop/cop/rspec/hook_argument.rb +16 -23
  47. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +10 -29
  48. data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -1
  49. data/lib/rubocop/cop/rspec/implicit_expect.rb +7 -15
  50. data/lib/rubocop/cop/rspec/implicit_subject.rb +16 -11
  51. data/lib/rubocop/cop/rspec/instance_spy.rb +18 -12
  52. data/lib/rubocop/cop/rspec/instance_variable.rb +4 -8
  53. data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +3 -6
  54. data/lib/rubocop/cop/rspec/it_behaves_like.rb +5 -6
  55. data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
  56. data/lib/rubocop/cop/rspec/leading_subject.rb +22 -26
  57. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +2 -5
  58. data/lib/rubocop/cop/rspec/let_before_examples.rb +10 -26
  59. data/lib/rubocop/cop/rspec/let_setup.rb +21 -6
  60. data/lib/rubocop/cop/rspec/message_chain.rb +7 -6
  61. data/lib/rubocop/cop/rspec/message_expectation.rb +2 -2
  62. data/lib/rubocop/cop/rspec/message_spies.rb +2 -3
  63. data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
  64. data/lib/rubocop/cop/rspec/multiple_describes.rb +11 -8
  65. data/lib/rubocop/cop/rspec/multiple_expectations.rb +7 -11
  66. data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +148 -0
  67. data/lib/rubocop/cop/rspec/multiple_subjects.rb +18 -19
  68. data/lib/rubocop/cop/rspec/named_subject.rb +8 -8
  69. data/lib/rubocop/cop/rspec/nested_groups.rb +12 -13
  70. data/lib/rubocop/cop/rspec/not_to_not.rb +5 -6
  71. data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
  72. data/lib/rubocop/cop/rspec/pending.rb +1 -1
  73. data/lib/rubocop/cop/rspec/predicate_matcher.rb +32 -69
  74. data/lib/rubocop/cop/rspec/rails/http_status.rb +7 -9
  75. data/lib/rubocop/cop/rspec/receive_counts.rb +15 -17
  76. data/lib/rubocop/cop/rspec/receive_never.rb +12 -12
  77. data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
  78. data/lib/rubocop/cop/rspec/repeated_example.rb +2 -2
  79. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +12 -2
  80. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +1 -1
  81. data/lib/rubocop/cop/rspec/return_from_stub.rb +12 -22
  82. data/lib/rubocop/cop/rspec/scattered_let.rb +12 -2
  83. data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
  84. data/lib/rubocop/cop/rspec/shared_context.rb +8 -21
  85. data/lib/rubocop/cop/rspec/shared_examples.rb +7 -9
  86. data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +15 -18
  87. data/lib/rubocop/cop/rspec/subject_stub.rb +25 -53
  88. data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -1
  89. data/lib/rubocop/cop/rspec/variable_definition.rb +56 -0
  90. data/lib/rubocop/cop/rspec/variable_name.rb +66 -0
  91. data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
  92. data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
  93. data/lib/rubocop/cop/rspec/yield.rb +14 -11
  94. data/lib/rubocop/cop/rspec_cops.rb +6 -1
  95. data/lib/rubocop/rspec/corrector/move_node.rb +54 -0
  96. data/lib/rubocop/rspec/description_extractor.rb +2 -6
  97. data/lib/rubocop/rspec/{blank_line_separation.rb → empty_line_separation.rb} +13 -10
  98. data/lib/rubocop/rspec/example_group.rb +21 -49
  99. data/lib/rubocop/rspec/factory_bot.rb +7 -1
  100. data/lib/rubocop/rspec/language.rb +13 -3
  101. data/lib/rubocop/rspec/language/node_pattern.rb +11 -2
  102. data/lib/rubocop/rspec/top_level_describe.rb +2 -2
  103. data/lib/rubocop/rspec/top_level_group.rb +55 -0
  104. data/lib/rubocop/rspec/variable.rb +16 -0
  105. data/lib/rubocop/rspec/version.rb +1 -1
  106. metadata +36 -13
  107. 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
- add_offense(
19
- node,
20
- message: message_inflected(predicate)
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 |_actual, matcher|
147
- add_offense(
148
- node,
149
- message: message_explicit(matcher)
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 |_actual, matcher|
158
- add_offense(
159
- node,
160
- message: message_explicit(matcher)
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 autocorrect_explicit(node)
197
- autocorrect_explicit_send(node) ||
198
- autocorrect_explicit_block(node)
199
- end
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', 'respond_to'
242
- matcher + '?'
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.method_name == :to]
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 < Cop
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 < Cop
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
- end
47
- end
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 < Cop
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
- add_offense(
42
- offending_node,
43
- message: message_for(offending_node, offending_range.source),
44
- location: offending_range
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
- def autocorrect(node)
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
- original = range(node.parent, node)
57
- corrector.replace(original, replacement)
58
- end
59
- end
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
- private
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 < Cop
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.method_name == :never && method_on_stub?(node)
23
+ return unless node.method?(:never) && method_on_stub?(node)
23
24
 
24
- add_offense(
25
- node,
26
- location: :selector
27
- )
25
+ add_offense(node.loc.selector) do |corrector|
26
+ autocorrect(corrector, node)
27
+ end
28
28
  end
29
29
 
30
- def autocorrect(node)
31
- lambda do |corrector|
32
- corrector.replace(node.parent.loc.selector, 'not_to')
33
- range = node.loc.dot.with(end_pos: node.loc.selector.end_pos)
34
- corrector.remove(range)
35
- end
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
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # end
41
41
  # end
42
42
  #
43
- class RepeatedDescription < Cop
43
+ class RepeatedDescription < Base
44
44
  MSG = "Don't repeat descriptions within an example group."
45
45
 
46
46
  def on_block(node)
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # expect(user).to be_valid
16
16
  # end
17
17
  #
18
- class RepeatedExample < Cop
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.method_name == :its
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
- class RepeatedExampleGroupBody < Cop
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 < Cop
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 < Cop
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
- location: :selector,
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
- location: :begin,
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.loc.expression,
145
+ block,
156
146
  "#{block.send_node.source}.and_return(#{body.source})"
157
147
  )
158
148
  end