rubocop-rspec 1.40.0 → 1.43.2

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/CODE_OF_CONDUCT.md +17 -0
  4. data/config/default.yml +12 -2
  5. data/lib/rubocop-rspec.rb +3 -1
  6. data/lib/rubocop/cop/rspec/align_left_let_brace.rb +12 -19
  7. data/lib/rubocop/cop/rspec/align_right_let_brace.rb +12 -19
  8. data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
  9. data/lib/rubocop/cop/rspec/around_block.rb +1 -1
  10. data/lib/rubocop/cop/rspec/base.rb +74 -0
  11. data/lib/rubocop/cop/rspec/be.rb +2 -2
  12. data/lib/rubocop/cop/rspec/be_eql.rb +6 -6
  13. data/lib/rubocop/cop/rspec/before_after_all.rb +1 -1
  14. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +19 -17
  15. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +14 -12
  16. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +1 -1
  17. data/lib/rubocop/cop/rspec/context_method.rb +7 -9
  18. data/lib/rubocop/cop/rspec/context_wording.rb +3 -3
  19. data/lib/rubocop/cop/rspec/cop.rb +2 -66
  20. data/lib/rubocop/cop/rspec/describe_class.rb +20 -27
  21. data/lib/rubocop/cop/rspec/describe_method.rb +14 -6
  22. data/lib/rubocop/cop/rspec/describe_symbol.rb +2 -2
  23. data/lib/rubocop/cop/rspec/described_class.rb +12 -9
  24. data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
  25. data/lib/rubocop/cop/rspec/dialect.rb +5 -12
  26. data/lib/rubocop/cop/rspec/empty_example_group.rb +91 -7
  27. data/lib/rubocop/cop/rspec/empty_hook.rb +6 -10
  28. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +5 -7
  29. data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +5 -9
  30. data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +8 -8
  31. data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +5 -9
  32. data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +6 -6
  33. data/lib/rubocop/cop/rspec/example_length.rb +1 -1
  34. data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
  35. data/lib/rubocop/cop/rspec/example_wording.rb +10 -11
  36. data/lib/rubocop/cop/rspec/expect_actual.rb +8 -11
  37. data/lib/rubocop/cop/rspec/expect_change.rb +10 -35
  38. data/lib/rubocop/cop/rspec/expect_in_hook.rb +3 -3
  39. data/lib/rubocop/cop/rspec/expect_output.rb +2 -2
  40. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +24 -21
  41. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +20 -22
  42. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +7 -8
  43. data/lib/rubocop/cop/rspec/file_path.rb +25 -17
  44. data/lib/rubocop/cop/rspec/focus.rb +7 -11
  45. data/lib/rubocop/cop/rspec/hook_argument.rb +16 -23
  46. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +13 -14
  47. data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +1 -1
  48. data/lib/rubocop/cop/rspec/implicit_expect.rb +7 -15
  49. data/lib/rubocop/cop/rspec/implicit_subject.rb +16 -11
  50. data/lib/rubocop/cop/rspec/instance_spy.rb +18 -12
  51. data/lib/rubocop/cop/rspec/instance_variable.rb +4 -8
  52. data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +3 -6
  53. data/lib/rubocop/cop/rspec/it_behaves_like.rb +5 -6
  54. data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
  55. data/lib/rubocop/cop/rspec/leading_subject.rb +27 -20
  56. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +2 -5
  57. data/lib/rubocop/cop/rspec/let_before_examples.rb +13 -11
  58. data/lib/rubocop/cop/rspec/let_setup.rb +21 -6
  59. data/lib/rubocop/cop/rspec/message_chain.rb +7 -6
  60. data/lib/rubocop/cop/rspec/message_expectation.rb +2 -2
  61. data/lib/rubocop/cop/rspec/message_spies.rb +2 -3
  62. data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
  63. data/lib/rubocop/cop/rspec/multiple_describes.rb +11 -8
  64. data/lib/rubocop/cop/rspec/multiple_expectations.rb +7 -11
  65. data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +148 -0
  66. data/lib/rubocop/cop/rspec/multiple_subjects.rb +18 -19
  67. data/lib/rubocop/cop/rspec/named_subject.rb +2 -2
  68. data/lib/rubocop/cop/rspec/nested_groups.rb +12 -13
  69. data/lib/rubocop/cop/rspec/not_to_not.rb +5 -6
  70. data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
  71. data/lib/rubocop/cop/rspec/pending.rb +1 -1
  72. data/lib/rubocop/cop/rspec/predicate_matcher.rb +32 -69
  73. data/lib/rubocop/cop/rspec/rails/http_status.rb +5 -9
  74. data/lib/rubocop/cop/rspec/receive_counts.rb +15 -17
  75. data/lib/rubocop/cop/rspec/receive_never.rb +12 -12
  76. data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
  77. data/lib/rubocop/cop/rspec/repeated_example.rb +2 -2
  78. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +1 -1
  79. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +1 -1
  80. data/lib/rubocop/cop/rspec/return_from_stub.rb +12 -22
  81. data/lib/rubocop/cop/rspec/scattered_let.rb +8 -11
  82. data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
  83. data/lib/rubocop/cop/rspec/shared_context.rb +8 -21
  84. data/lib/rubocop/cop/rspec/shared_examples.rb +6 -9
  85. data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +15 -18
  86. data/lib/rubocop/cop/rspec/subject_stub.rb +5 -11
  87. data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -1
  88. data/lib/rubocop/cop/rspec/variable_definition.rb +6 -6
  89. data/lib/rubocop/cop/rspec/variable_name.rb +28 -9
  90. data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
  91. data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
  92. data/lib/rubocop/cop/rspec/yield.rb +14 -11
  93. data/lib/rubocop/cop/rspec_cops.rb +1 -0
  94. data/lib/rubocop/rspec/corrector/move_node.rb +7 -5
  95. data/lib/rubocop/rspec/description_extractor.rb +1 -1
  96. data/lib/rubocop/rspec/{blank_line_separation.rb → empty_line_separation.rb} +13 -10
  97. data/lib/rubocop/rspec/example_group.rb +21 -49
  98. data/lib/rubocop/rspec/factory_bot.rb +7 -1
  99. data/lib/rubocop/rspec/language.rb +6 -4
  100. data/lib/rubocop/rspec/language/node_pattern.rb +10 -1
  101. data/lib/rubocop/rspec/top_level_describe.rb +2 -2
  102. data/lib/rubocop/rspec/top_level_group.rb +57 -0
  103. data/lib/rubocop/rspec/variable.rb +1 -1
  104. data/lib/rubocop/rspec/version.rb +1 -1
  105. metadata +29 -11
@@ -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
 
@@ -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
 
@@ -43,7 +43,7 @@ module RuboCop
43
43
  # it { is_expected.to respond_to :each }
44
44
  # end
45
45
  #
46
- class RepeatedExampleGroupBody < Cop
46
+ class RepeatedExampleGroupBody < Base
47
47
  MSG = 'Repeated %<group>s block body on line(s) %<loc>s'
48
48
 
49
49
  def_node_matcher :several_example_groups?, <<-PATTERN
@@ -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
@@ -26,7 +26,9 @@ module RuboCop
26
26
  # let!(:baz) { 3 }
27
27
  # end
28
28
  #
29
- class ScatteredLet < Cop
29
+ class ScatteredLet < Base
30
+ extend AutoCorrector
31
+
30
32
  MSG = 'Group all let/let! blocks in the example group together.'
31
33
 
32
34
  def on_block(node)
@@ -35,15 +37,6 @@ module RuboCop
35
37
  check_let_declarations(node.body)
36
38
  end
37
39
 
38
- def autocorrect(node)
39
- lambda do |corrector|
40
- first_let = find_first_let(node.parent)
41
- RuboCop::RSpec::Corrector::MoveNode.new(
42
- node, corrector, processed_source
43
- ).move_after(first_let)
44
- end
45
- end
46
-
47
40
  private
48
41
 
49
42
  def check_let_declarations(body)
@@ -53,7 +46,11 @@ module RuboCop
53
46
  lets.each_with_index do |node, idx|
54
47
  next if node.sibling_index == first_let.sibling_index + idx
55
48
 
56
- add_offense(node)
49
+ add_offense(node) do |corrector|
50
+ RuboCop::RSpec::Corrector::MoveNode.new(
51
+ node, corrector, processed_source
52
+ ).move_after(first_let)
53
+ end
57
54
  end
58
55
  end
59
56
 
@@ -22,7 +22,7 @@ module RuboCop
22
22
  # end
23
23
  # end
24
24
  #
25
- class ScatteredSetup < Cop
25
+ class ScatteredSetup < Base
26
26
  MSG = 'Do not define multiple `%<hook_name>s` hooks in the same '\
27
27
  'example group (also defined on %<lines>s).'
28
28
 
@@ -50,7 +50,9 @@ module RuboCop
50
50
  # end
51
51
  # end
52
52
  #
53
- class SharedContext < Cop
53
+ class SharedContext < Base
54
+ extend AutoCorrector
55
+
54
56
  MSG_EXAMPLES = "Use `shared_examples` when you don't "\
55
57
  'define context.'
56
58
 
@@ -68,22 +70,14 @@ module RuboCop
68
70
 
69
71
  def on_block(node)
70
72
  context_with_only_examples(node) do
71
- add_shared_item_offense(node.send_node, MSG_EXAMPLES)
73
+ add_offense(node.send_node, message: MSG_EXAMPLES) do |corrector|
74
+ corrector.replace(node.send_node.loc.selector, 'shared_examples')
75
+ end
72
76
  end
73
77
 
74
78
  examples_with_only_context(node) do
75
- add_shared_item_offense(node.send_node, MSG_CONTEXT)
76
- end
77
- end
78
-
79
- def autocorrect(node)
80
- lambda do |corrector|
81
- context_with_only_examples(node.parent) do
82
- corrector.replace(node.loc.selector, 'shared_examples')
83
- end
84
-
85
- examples_with_only_context(node.parent) do
86
- corrector.replace(node.loc.selector, 'shared_context')
79
+ add_offense(node.send_node, message: MSG_CONTEXT) do |corrector|
80
+ corrector.replace(node.send_node.loc.selector, 'shared_context')
87
81
  end
88
82
  end
89
83
  end
@@ -97,13 +91,6 @@ module RuboCop
97
91
  def examples_with_only_context(node)
98
92
  shared_example(node) { yield if context?(node) && !examples?(node) }
99
93
  end
100
-
101
- def add_shared_item_offense(node, message)
102
- add_offense(
103
- node,
104
- message: message
105
- )
106
- end
107
94
  end
108
95
  end
109
96
  end
@@ -20,7 +20,9 @@ module RuboCop
20
20
  # shared_examples_for 'foo bar baz'
21
21
  # include_examples 'foo bar baz'
22
22
  #
23
- class SharedExamples < Cop
23
+ class SharedExamples < Base
24
+ extend AutoCorrector
25
+
24
26
  def_node_matcher :shared_examples,
25
27
  (SharedGroups::ALL + Includes::ALL).send_pattern
26
28
 
@@ -30,14 +32,9 @@ module RuboCop
30
32
  next unless ast_node&.sym_type?
31
33
 
32
34
  checker = Checker.new(ast_node)
33
- add_offense(checker.node, message: checker.message)
34
- end
35
- end
36
-
37
- def autocorrect(node)
38
- lambda do |corrector|
39
- checker = Checker.new(node)
40
- corrector.replace(node.loc.expression, checker.preferred_style)
35
+ add_offense(checker.node, message: checker.message) do |corrector|
36
+ corrector.replace(checker.node, checker.preferred_style)
37
+ end
41
38
  end
42
39
  end
43
40
 
@@ -16,7 +16,9 @@ module RuboCop
16
16
  # allow(foo).to receive(:bar, :baz)
17
17
  # allow(foo).to receive("bar.baz")
18
18
  #
19
- class SingleArgumentMessageChain < Cop
19
+ class SingleArgumentMessageChain < Base
20
+ extend AutoCorrector
21
+
20
22
  MSG = 'Use `%<recommended>s` instead of calling '\
21
23
  '`%<called>s` with a single argument.'
22
24
 
@@ -30,22 +32,23 @@ module RuboCop
30
32
  message_chain(node) do |arg|
31
33
  return if valid_usage?(arg)
32
34
 
33
- add_offense(node, location: :selector)
34
- end
35
- end
35
+ method = node.method_name
36
+ msg = format(MSG, recommended: replacement(method), called: method)
36
37
 
37
- def autocorrect(node)
38
- lambda do |corrector|
39
- corrector.replace(node.loc.selector, replacement(node.method_name))
40
- message_chain(node) do |arg|
41
- autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg)
42
- autocorrect_array_arg(corrector, arg) if arg.array_type?
38
+ add_offense(node.loc.selector, message: msg) do |corrector|
39
+ autocorrect(corrector, node, method, arg)
43
40
  end
44
41
  end
45
42
  end
46
43
 
47
44
  private
48
45
 
46
+ def autocorrect(corrector, node, method, arg)
47
+ corrector.replace(node.loc.selector, replacement(method))
48
+ autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg)
49
+ autocorrect_array_arg(corrector, arg) if arg.array_type?
50
+ end
51
+
49
52
  def valid_usage?(node)
50
53
  return true unless node.literal? || node.array_type?
51
54
 
@@ -63,7 +66,7 @@ module RuboCop
63
66
  def autocorrect_hash_arg(corrector, arg)
64
67
  key, value = *arg.children.first
65
68
 
66
- corrector.replace(arg.loc.expression, key_to_arg(key))
69
+ corrector.replace(arg, key_to_arg(key))
67
70
  corrector.insert_after(arg.parent.loc.end,
68
71
  ".and_return(#{value.source})")
69
72
  end
@@ -71,7 +74,7 @@ module RuboCop
71
74
  def autocorrect_array_arg(corrector, arg)
72
75
  value = arg.children.first
73
76
 
74
- corrector.replace(arg.loc.expression, value.source)
77
+ corrector.replace(arg, value.source)
75
78
  end
76
79
 
77
80
  def key_to_arg(node)
@@ -82,12 +85,6 @@ module RuboCop
82
85
  def replacement(method)
83
86
  method.equal?(:receive_message_chain) ? 'receive' : 'stub'
84
87
  end
85
-
86
- def message(node)
87
- method = node.method_name
88
-
89
- format(MSG, recommended: replacement(method), called: method)
90
- end
91
88
  end
92
89
  end
93
90
  end