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
@@ -45,22 +45,18 @@ module RuboCop
45
45
  # end
46
46
  # end
47
47
  #
48
- class MultipleExpectations < Cop
48
+ class MultipleExpectations < Base
49
49
  include ConfigurableMax
50
50
 
51
51
  MSG = 'Example has too many expectations [%<total>d/%<max>d].'
52
52
 
53
- def_node_matcher :aggregate_failures?, <<-PATTERN
54
- (block {
55
- (send _ _ <(sym :aggregate_failures) ...>)
56
- (send _ _ ... (hash <(pair (sym :aggregate_failures) true) ...>))
57
- } ...)
58
- PATTERN
53
+ ANYTHING = ->(_node) { true }
54
+ TRUE = ->(node) { node.true_type? }
59
55
 
60
- def_node_matcher :aggregate_failures_present?, <<-PATTERN
56
+ def_node_matcher :aggregate_failures?, <<-PATTERN
61
57
  (block {
62
58
  (send _ _ <(sym :aggregate_failures) ...>)
63
- (send _ _ ... (hash <(pair (sym :aggregate_failures) _) ...>))
59
+ (send _ _ ... (hash <(pair (sym :aggregate_failures) %1) ...>))
64
60
  } ...)
65
61
  PATTERN
66
62
 
@@ -89,12 +85,12 @@ module RuboCop
89
85
  node_with_aggregate_failures = find_aggregate_failures(example_node)
90
86
  return false unless node_with_aggregate_failures
91
87
 
92
- aggregate_failures?(node_with_aggregate_failures)
88
+ aggregate_failures?(node_with_aggregate_failures, TRUE)
93
89
  end
94
90
 
95
91
  def find_aggregate_failures(example_node)
96
92
  example_node.send_node.each_ancestor(:block)
97
- .find { |block_node| aggregate_failures_present?(block_node) }
93
+ .find { |block_node| aggregate_failures?(block_node, ANYTHING) }
98
94
  end
99
95
 
100
96
  def find_expectation(node, &block)
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks if example groups contain too many `let` and `subject` calls.
7
+ #
8
+ # This cop is configurable using the `Max` option and the `AllowSubject`
9
+ # which will configure the cop to only register offenses on calls to
10
+ # `let` and not calls to `subject`.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # describe MyClass do
15
+ # let(:foo) { [] }
16
+ # let(:bar) { [] }
17
+ # let!(:baz) { [] }
18
+ # let(:qux) { [] }
19
+ # let(:quux) { [] }
20
+ # let(:quuz) { {} }
21
+ # end
22
+ #
23
+ # describe MyClass do
24
+ # let(:foo) { [] }
25
+ # let(:bar) { [] }
26
+ # let!(:baz) { [] }
27
+ #
28
+ # context 'when stuff' do
29
+ # let(:qux) { [] }
30
+ # let(:quux) { [] }
31
+ # let(:quuz) { {} }
32
+ # end
33
+ # end
34
+ #
35
+ # # good
36
+ # describe MyClass do
37
+ # let(:bar) { [] }
38
+ # let!(:baz) { [] }
39
+ # let(:qux) { [] }
40
+ # let(:quux) { [] }
41
+ # let(:quuz) { {} }
42
+ # end
43
+ #
44
+ # describe MyClass do
45
+ # context 'when stuff' do
46
+ # let(:foo) { [] }
47
+ # let(:bar) { [] }
48
+ # let!(:booger) { [] }
49
+ # end
50
+ #
51
+ # context 'when other stuff' do
52
+ # let(:qux) { [] }
53
+ # let(:quux) { [] }
54
+ # let(:quuz) { {} }
55
+ # end
56
+ # end
57
+ #
58
+ # @example when disabling AllowSubject configuration
59
+ #
60
+ # # rubocop.yml
61
+ # # RSpec/MultipleMemoizedHelpers:
62
+ # # AllowSubject: false
63
+ #
64
+ # # bad - `subject` counts towards memoized helpers
65
+ # describe MyClass do
66
+ # subject { {} }
67
+ # let(:foo) { [] }
68
+ # let(:bar) { [] }
69
+ # let!(:baz) { [] }
70
+ # let(:qux) { [] }
71
+ # let(:quux) { [] }
72
+ # end
73
+ #
74
+ # @example with Max configuration
75
+ #
76
+ # # rubocop.yml
77
+ # # RSpec/MultipleMemoizedHelpers:
78
+ # # Max: 1
79
+ #
80
+ # # bad
81
+ # describe MyClass do
82
+ # let(:foo) { [] }
83
+ # let(:bar) { [] }
84
+ # end
85
+ #
86
+ class MultipleMemoizedHelpers < Base
87
+ include ConfigurableMax
88
+ include RuboCop::RSpec::Variable
89
+
90
+ MSG = 'Example group has too many memoized helpers [%<count>d/%<max>d]'
91
+
92
+ def on_block(node)
93
+ return unless spec_group?(node)
94
+
95
+ count = all_helpers(node).uniq.count
96
+
97
+ return if count <= max
98
+
99
+ self.max = count
100
+ add_offense(node, message: format(MSG, count: count, max: max))
101
+ end
102
+
103
+ def on_new_investigation
104
+ @example_group_memoized_helpers = {}
105
+ end
106
+
107
+ private
108
+
109
+ attr_reader :example_group_memoized_helpers
110
+
111
+ def all_helpers(node)
112
+ [
113
+ *helpers(node),
114
+ *node.each_ancestor(:block).flat_map(&method(:helpers))
115
+ ]
116
+ end
117
+
118
+ def helpers(node)
119
+ @example_group_memoized_helpers[node] ||=
120
+ variable_nodes(node).map do |variable_node|
121
+ if variable_node.block_type?
122
+ variable_definition?(variable_node.send_node)
123
+ else # block-pass (`let(:foo, &bar)`)
124
+ variable_definition?(variable_node)
125
+ end
126
+ end
127
+ end
128
+
129
+ def variable_nodes(node)
130
+ example_group = RuboCop::RSpec::ExampleGroup.new(node)
131
+ if allow_subject?
132
+ example_group.lets
133
+ else
134
+ example_group.lets + example_group.subjects
135
+ end
136
+ end
137
+
138
+ def max
139
+ cop_config['Max']
140
+ end
141
+
142
+ def allow_subject?
143
+ cop_config['AllowSubject']
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -33,7 +33,8 @@ module RuboCop
33
33
  # - If subjects are defined with `subject!` then we don't autocorrect.
34
34
  # This is enough of an edge case that people can just move this to
35
35
  # a `before` hook on their own
36
- class MultipleSubjects < Cop
36
+ class MultipleSubjects < Base
37
+ extend AutoCorrector
37
38
  include RangeHelp
38
39
 
39
40
  MSG = 'Do not set more than one subject per example group'
@@ -44,38 +45,36 @@ module RuboCop
44
45
  subjects = RuboCop::RSpec::ExampleGroup.new(node).subjects
45
46
 
46
47
  subjects[0...-1].each do |subject|
47
- add_offense(subject)
48
+ add_offense(subject) do |corrector|
49
+ autocorrect(corrector, subject)
50
+ end
48
51
  end
49
52
  end
50
53
 
51
- def autocorrect(node)
52
- return unless node.method_name.equal?(:subject) # Ignore `subject!`
54
+ private
55
+
56
+ def autocorrect(corrector, subject)
57
+ return unless subject.method_name.equal?(:subject) # Ignore `subject!`
53
58
 
54
- if named_subject?(node)
55
- rename_autocorrect(node)
59
+ if named_subject?(subject)
60
+ rename_autocorrect(corrector, subject)
56
61
  else
57
- remove_autocorrect(node)
62
+ remove_autocorrect(corrector, subject)
58
63
  end
59
64
  end
60
65
 
61
- private
62
-
63
66
  def named_subject?(node)
64
67
  node.send_node.arguments?
65
68
  end
66
69
 
67
- def rename_autocorrect(node)
68
- lambda do |corrector|
69
- corrector.replace(node.send_node.loc.selector, 'let')
70
- end
70
+ def rename_autocorrect(corrector, node)
71
+ corrector.replace(node.send_node.loc.selector, 'let')
71
72
  end
72
73
 
73
- def remove_autocorrect(node)
74
- lambda do |corrector|
75
- range = range_by_whole_lines(node.source_range,
76
- include_final_newline: true)
77
- corrector.remove(range)
78
- end
74
+ def remove_autocorrect(corrector, node)
75
+ range = range_by_whole_lines(node.source_range,
76
+ include_final_newline: true)
77
+ corrector.remove(range)
79
78
  end
80
79
  end
81
80
  end
@@ -41,7 +41,7 @@ module RuboCop
41
41
  #
42
42
  # it { is_expected.to be_valid }
43
43
  # end
44
- class NamedSubject < Cop
44
+ class NamedSubject < Base
45
45
  MSG = 'Name your test subject if you need '\
46
46
  'to reference it explicitly.'
47
47
 
@@ -62,7 +62,7 @@ module RuboCop
62
62
  return if !rspec_block?(node) || ignored_shared_example?(node)
63
63
 
64
64
  subject_usage(node) do |subject_node|
65
- add_offense(subject_node, location: :selector)
65
+ add_offense(subject_node.loc.selector)
66
66
  end
67
67
  end
68
68
 
@@ -85,9 +85,9 @@ module RuboCop
85
85
  # end
86
86
  # end
87
87
  #
88
- class NestedGroups < Cop
88
+ class NestedGroups < Base
89
89
  include ConfigurableMax
90
- include RuboCop::RSpec::TopLevelDescribe
90
+ include RuboCop::RSpec::TopLevelGroup
91
91
 
92
92
  MSG = 'Maximum example group nesting exceeded [%<total>d/%<max>d].'
93
93
 
@@ -97,13 +97,11 @@ module RuboCop
97
97
  "Configuration key `#{DEPRECATED_MAX_KEY}` for #{cop_name} is " \
98
98
  'deprecated in favor of `Max`. Please use that instead.'
99
99
 
100
- def_node_search :find_contexts, ExampleGroups::ALL.block_pattern
101
-
102
- def on_top_level_describe(node, _args)
103
- find_nested_contexts(node.parent) do |context, nesting|
100
+ def on_top_level_group(node)
101
+ find_nested_example_groups(node) do |example_group, nesting|
104
102
  self.max = nesting
105
103
  add_offense(
106
- context.send_node,
104
+ example_group.send_node,
107
105
  message: message(nesting)
108
106
  )
109
107
  end
@@ -111,13 +109,14 @@ module RuboCop
111
109
 
112
110
  private
113
111
 
114
- def find_nested_contexts(node, nesting: 1, &block)
115
- find_contexts(node) do |nested_context|
116
- yield(nested_context, nesting) if nesting > max_nesting
112
+ def find_nested_example_groups(node, nesting: 1, &block)
113
+ example_group = example_group?(node)
114
+ yield node, nesting if example_group && nesting > max_nesting
115
+
116
+ next_nesting = example_group ? nesting + 1 : nesting
117
117
 
118
- nested_context.each_child_node do |child|
119
- find_nested_contexts(child, nesting: nesting + 1, &block)
120
- end
118
+ node.each_child_node(:block, :begin) do |child|
119
+ find_nested_example_groups(child, nesting: next_nesting, &block)
121
120
  end
122
121
  end
123
122
 
@@ -15,7 +15,8 @@ module RuboCop
15
15
  # it '...' do
16
16
  # expect(false).not_to be_true
17
17
  # end
18
- class NotToNot < Cop
18
+ class NotToNot < Base
19
+ extend AutoCorrector
19
20
  include ConfigurableEnforcedStyle
20
21
 
21
22
  MSG = 'Prefer `%<replacement>s` over `%<original>s`.'
@@ -24,14 +25,12 @@ module RuboCop
24
25
 
25
26
  def on_send(node)
26
27
  not_to_not_offense(node, alternative_style) do
27
- add_offense(node, location: :selector)
28
+ add_offense(node.loc.selector) do |corrector|
29
+ corrector.replace(node.loc.selector, style.to_s)
30
+ end
28
31
  end
29
32
  end
30
33
 
31
- def autocorrect(node)
32
- ->(corrector) { corrector.replace(node.loc.selector, style.to_s) }
33
- end
34
-
35
34
  private
36
35
 
37
36
  def message(_node)
@@ -21,7 +21,7 @@ module RuboCop
21
21
  # let(:foo) { bar }
22
22
  # let(:baz) { baz }
23
23
  # let!(:other) { other }
24
- class OverwritingSetup < Cop
24
+ class OverwritingSetup < Base
25
25
  MSG = '`%<name>s` is already defined.'
26
26
 
27
27
  def_node_matcher :setup?, (Helpers::ALL + Subject::ALL).block_pattern
@@ -31,7 +31,7 @@ module RuboCop
31
31
  # # good
32
32
  # describe MyClass do
33
33
  # end
34
- class Pending < Cop
34
+ class Pending < Base
35
35
  MSG = 'Pending spec found.'
36
36
 
37
37
  PENDING = Examples::PENDING + Examples::SKIPPED + ExampleGroups::SKIPPED
@@ -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