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.
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