rubocop-rspec 3.0.4 → 3.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 169d3c16af254654f25f5b2d91abbee972be45feaa9b9103c54c00ce6592e41f
4
- data.tar.gz: 140cfd9fe9b060eaaf697aa3eb7e94667ea089635cf2910047c1c63c90c55d76
3
+ metadata.gz: 4a2433cc3212de48725bca4fa2f8216ef0742950d1b0ad0a52e0d717050ede4e
4
+ data.tar.gz: 3e43165a772275ece7344813b6dfc5196669763013c0bedc3b75107cf6fa0f30
5
5
  SHA512:
6
- metadata.gz: ecb48dd3947d2e830c205bf170ba47a9d81bafa685ecfafcbfbd23baa7dc9bee1cdb0002d9de44f8fd3fd3f9249187c4764676259f465f5bb2d0b9b5b3ea38f9
7
- data.tar.gz: 4d63767133ef37bebba948f952b120cb4ef95b891ecbfca78cf0450f9df8e0f712a10a272eb7e6b477869d0c50323926b9791f7afdc8c64df18f8ba03e2f5359
6
+ metadata.gz: 41a9171c098150e3349977cd08df5f369fe2d33c0bb4f1b29edcfb2633eae2c880ab1ff71a9c4a1ee5dc28645a6359ecd3e4ab99a822ac576523386e78364ee2
7
+ data.tar.gz: af1c164ac3d8c9e9ed61611fa9877c459656f695fd45c057c776af99304fcd8471fa00d958d7bf650ba46f82056ae96accd12cfeec17eb1a00129baffdb51768
data/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 3.4.0 (2025-01-20)
6
+
7
+ - Fix `RSpec/SortMetadata` cop to limit sorting to trailing metadata arguments. ([@cbliard])
8
+ - Replace `RSpec/StringAsInstanceDoubleConstant` with `RSpec/VerifiedDoubleReference` configured to only support constant class references. ([@corsonknowles])
9
+ - Fix `RSpec/EmptyExampleGroup` cop false positive when a simple conditional is used inside an iterator. ([@lovro-bikic])
10
+
11
+ ## 3.3.0 (2024-12-12)
12
+
13
+ - Deprecate `top_level_group?` method from `TopLevelGroup` mixin as all of its callers were intentionally removed from `Rubocop/RSpec`. ([@corsonknowles])
14
+ - Fix false positive for RSpec/EmptyMetadata for splat kwargs. ([@pirj])
15
+
16
+ ## 3.2.0 (2024-10-26)
17
+
18
+ - Fix `RSpec/VoidExpect` to only operate inside an example block. ([@corsonknowles])
19
+ - Change `RSpec/ContextWording` cop to always report an offense when both `Prefixes` and `AllowedPatterns` are empty. ([@ydah])
20
+ - Add support for `and` and `or` compound matchers to `RSpec/ChangeByZero` cop. ([@ydah])
21
+
22
+ ## 3.1.0 (2024-10-01)
23
+
24
+ - Add `RSpec/StringAsInstanceDoubleConstant` to check for and correct strings used as instance_doubles. ([@corsonknowles])
25
+ - Fix false-positive for `RSpec/UnspecifiedException` when a method is literally named `raise_exception`. ([@aarestad])
26
+ - Fix false-positive for `RSpec/UnspecifiedException` when `not_to raise_error` is used within a block. ([@aarestad], [@G-Rath])
27
+
28
+ ## 3.0.5 (2024-09-07)
29
+
30
+ - Fix false-negative and error for `RSpec/MetadataStyle` when non-literal args are used in metadata in `EnforceStyle: hash`. ([@cbliard])
31
+ - Improve offense message for `RSpec/IndexedLet`. ([@earlopain])
32
+
5
33
  ## 3.0.4 (2024-08-05)
6
34
 
7
35
  - Fix false-negative for `UnspecifiedException` when matcher is chained. ([@r7kamura])
@@ -71,7 +99,7 @@ Read more about how to upgrade in https://docs.rubocop.org/rubocop-rspec/upgrade
71
99
  - Add new `RSpec/IsExpectedSpecify` cop. ([@ydah])
72
100
  - Add new `RSpec/RepeatedSubjectCall` cop. ([@drcapulet])
73
101
  - Add support for `assert_true`, `assert_false`, `assert_not_equal`, `assert_not_nil`, `*_empty`, `*_predicate`, `*_kind_of`, `*_in_delta`, `*_match`, `*_instance_of` and `*_includes` assertions in `RSpec/Rails/MinitestAssertions`. ([@ydah], [@G-Rath])
74
- - Support asserts with messages in `Rspec/BeEmpty`. ([@G-Rath])
102
+ - Support asserts with messages in `RSpec/BeEmpty`. ([@G-Rath])
75
103
  - Fix a false positive for `RSpec/ExpectActual` when used with rspec-rails routing matchers. ([@naveg])
76
104
  - Add configuration option `ResponseMethods` to `RSpec/Rails/HaveHttpStatus`. ([@ydah])
77
105
  - Fix a false negative for `RSpec/DescribedClass` when class with constant. ([@ydah])
@@ -266,7 +294,7 @@ Read more about how to upgrade in https://docs.rubocop.org/rubocop-rspec/upgrade
266
294
  ## 2.13.0 (2022-09-12)
267
295
 
268
296
  - Fix `RSpec/FilePath` cop missing mismatched expanded namespace. ([@sl4vr])
269
- - Add new `AllowConsecutiveOneLiners` (default true) option for `Rspec/EmptyLineAfterHook` cop. ([@ngouy])
297
+ - Add new `AllowConsecutiveOneLiners` (default true) option for `RSpec/EmptyLineAfterHook` cop. ([@ngouy])
270
298
  - Add autocorrect support for `RSpec/EmptyExampleGroup`. ([@r7kamura])
271
299
  - Fix `RSpec/ChangeByZero` with compound expressions using `&` or `|` operators. ([@BrianHawley])
272
300
  - Add `RSpec/NoExpectationExample`. ([@r7kamura])
@@ -723,7 +751,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
723
751
  ## 1.13.0 (2017-03-07)
724
752
 
725
753
  - Add repeated 'it' detection to `RSpec/ExampleWording` cop. ([@dgollahon])
726
- - Add \[observed_nesting/max_nesting\] info to `RSpec/NestedGroups` messages. ([@dgollahon])
754
+ - Add [observed_nesting/max_nesting] info to `RSpec/NestedGroups` messages. ([@dgollahon])
727
755
  - Add `RSpec/ItBehavesLike` cop. ([@dgollahon])
728
756
  - Add `RSpec/SharedContext` cop. ([@Darhazer])
729
757
  - `RSpec/MultipleExpectations`: Count aggregate_failures block as single expectation. ([@Darhazer])
@@ -894,6 +922,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
894
922
 
895
923
  <!-- Contributors (alphabetically) -->
896
924
 
925
+ [@aarestad]: https://github.com/aarestad
897
926
  [@abrom]: https://github.com/abrom
898
927
  [@ahukkanen]: https://github.com/ahukkanen
899
928
  [@akiomik]: https://github.com/akiomik
@@ -911,9 +940,11 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
911
940
  [@bquorning]: https://github.com/bquorning
912
941
  [@brentwheeldon]: https://github.com/BrentWheeldon
913
942
  [@brianhawley]: https://github.com/BrianHawley
943
+ [@cbliard]: https://github.com/cbliard
914
944
  [@cfabianski]: https://github.com/cfabianski
915
945
  [@clupprich]: https://github.com/clupprich
916
946
  [@composerinteralia]: https://github.com/composerinteralia
947
+ [@corsonknowles]: https://github.com/corsonknowles
917
948
  [@corydiamand]: https://github.com/corydiamand
918
949
  [@darhazer]: https://github.com/Darhazer
919
950
  [@daveworth]: https://github.com/daveworth
@@ -964,6 +995,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
964
995
  [@leoarnold]: https://github.com/leoarnold
965
996
  [@liberatys]: https://github.com/Liberatys
966
997
  [@lokhi]: https://github.com/lokhi
998
+ [@lovro-bikic]: https://github.com/lovro-bikic
967
999
  [@luke-hill]: https://github.com/luke-hill
968
1000
  [@m-yamashita01]: https://github.com/M-Yamashita01
969
1001
  [@marocchino]: https://github.com/marocchino
data/config/default.yml CHANGED
@@ -403,6 +403,7 @@ RSpec/ExampleWithoutDescription:
403
403
  - single_line_only
404
404
  - disallow
405
405
  VersionAdded: '1.22'
406
+ StyleGuide: https://rspec.rubystyle.guide/#it-and-specify
406
407
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWithoutDescription
407
408
 
408
409
  RSpec/ExampleWording:
@@ -987,12 +988,8 @@ RSpec/VerifiedDoubleReference:
987
988
  Description: Checks for consistent verified double reference style.
988
989
  Enabled: true
989
990
  SafeAutoCorrect: false
990
- EnforcedStyle: constant
991
- SupportedStyles:
992
- - constant
993
- - string
994
991
  VersionAdded: 2.10.0
995
- VersionChanged: '2.12'
992
+ VersionChanged: '3.4'
996
993
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubleReference
997
994
 
998
995
  RSpec/VerifiedDoubles:
@@ -12,6 +12,9 @@ changed_parameters:
12
12
  parameters: IgnoredPatterns
13
13
  alternative: AllowedPatterns
14
14
  severity: warning
15
+ - cops: RSpec/VerifiedDoubleReference
16
+ parameters: EnforcedStyle
17
+ reason: String references are not verifying unless the class is loaded.
15
18
 
16
19
  split:
17
20
  RSpec/FilePath:
@@ -23,6 +26,8 @@ removed:
23
26
  RSpec/Capybara/FeatureMethods:
24
27
  reason: >
25
28
  this cop has migrated to `RSpec/Dialect`. Please use `RSpec/Dialect` instead
29
+ RSpec/StringAsInstanceDoubleConstant:
30
+ reason: Please use `RSpec/VerifiedDoubleReference` instead
26
31
 
27
32
  extracted:
28
33
  RSpec/Rails/*: rubocop-rspec_rails
@@ -69,15 +69,13 @@ module RuboCop
69
69
  end
70
70
 
71
71
  def check_for_unused_proxy(block, proxy)
72
- name, = *proxy
73
-
74
72
  find_arg_usage(block) do |usage|
75
- return if usage.include?(s(:lvar, name))
73
+ return if usage.include?(s(:lvar, proxy.name))
76
74
  end
77
75
 
78
76
  add_offense(
79
77
  proxy,
80
- message: format(MSG_UNUSED_ARG, arg: name)
78
+ message: format(MSG_UNUSED_ARG, arg: proxy.name)
81
79
  )
82
80
  end
83
81
 
@@ -104,12 +104,12 @@ module RuboCop
104
104
  # rubocop:disable Metrics/MethodLength
105
105
  def register_offense(node, change_node)
106
106
  if compound_expectations?(node)
107
- add_offense(node.source_range,
107
+ add_offense(node,
108
108
  message: message_compound(change_node)) do |corrector|
109
109
  autocorrect_compound(corrector, node)
110
110
  end
111
111
  else
112
- add_offense(node.source_range,
112
+ add_offense(node,
113
113
  message: message(change_node)) do |corrector|
114
114
  autocorrect(corrector, node, change_node)
115
115
  end
@@ -118,7 +118,8 @@ module RuboCop
118
118
  # rubocop:enable Metrics/MethodLength
119
119
 
120
120
  def compound_expectations?(node)
121
- %i[and or & |].include?(node.parent.method_name)
121
+ node.parent.send_type? &&
122
+ %i[and or & |].include?(node.parent.method_name)
122
123
  end
123
124
 
124
125
  def message(change_node)
@@ -6,6 +6,7 @@ module RuboCop
6
6
  # Checks where `contain_exactly` is used.
7
7
  #
8
8
  # This cop checks for the following:
9
+ #
9
10
  # - Prefer `match_array` when matching array values.
10
11
  # - Prefer `be_empty` when using `contain_exactly` with no arguments.
11
12
  #
@@ -12,6 +12,9 @@ module RuboCop
12
12
  #
13
13
  # @see http://www.betterspecs.org/#contexts
14
14
  #
15
+ # If both `Prefixes` and `AllowedPatterns` are empty, this cop will always
16
+ # report an offense. So you need to set at least one of them.
17
+ #
15
18
  # @example `Prefixes` configuration
16
19
  # # .rubocop.yml
17
20
  # # RSpec/ContextWording:
@@ -58,7 +61,9 @@ module RuboCop
58
61
  class ContextWording < Base
59
62
  include AllowedPattern
60
63
 
61
- MSG = 'Context description should match %<patterns>s.'
64
+ MSG_MATCH = 'Context description should match %<patterns>s.'
65
+ MSG_ALWAYS = 'Current settings will always report an offense. Please ' \
66
+ 'add allowed words to `Prefixes` or `AllowedPatterns`.'
62
67
 
63
68
  # @!method context_wording(node)
64
69
  def_node_matcher :context_wording, <<~PATTERN
@@ -67,8 +72,7 @@ module RuboCop
67
72
 
68
73
  def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
69
74
  context_wording(node) do |context|
70
- if bad_pattern?(context)
71
- message = format(MSG, patterns: expect_patterns)
75
+ unless matches_allowed_pattern?(description(context))
72
76
  add_offense(context, message: message)
73
77
  end
74
78
  end
@@ -84,12 +88,6 @@ module RuboCop
84
88
  @prefix_regexes ||= prefixes.map { |pre| /^#{Regexp.escape(pre)}\b/ }
85
89
  end
86
90
 
87
- def bad_pattern?(node)
88
- return false if allowed_patterns.empty?
89
-
90
- !matches_allowed_pattern?(description(node))
91
- end
92
-
93
91
  def description(context)
94
92
  if context.xstr_type?
95
93
  context.value.value
@@ -98,6 +96,14 @@ module RuboCop
98
96
  end
99
97
  end
100
98
 
99
+ def message
100
+ if allowed_patterns.empty?
101
+ MSG_ALWAYS
102
+ else
103
+ format(MSG_MATCH, patterns: expect_patterns)
104
+ end
105
+ end
106
+
101
107
  def expect_patterns
102
108
  inspected = allowed_patterns.map do |pattern|
103
109
  pattern.inspect.gsub(/\A"|"\z/, '/')
@@ -130,6 +130,7 @@ module RuboCop
130
130
  def_node_matcher :examples?, <<~PATTERN
131
131
  {
132
132
  #examples_directly_or_in_block?
133
+ #examples_in_branches?
133
134
  (begin <#examples_directly_or_in_block? ...>)
134
135
  (begin <#examples_in_branches? ...>)
135
136
  }
@@ -170,6 +171,7 @@ module RuboCop
170
171
  end
171
172
 
172
173
  def examples_in_branches?(condition_node)
174
+ return false unless condition_node
173
175
  return false if !condition_node.if_type? && !condition_node.case_type?
174
176
 
175
177
  condition_node.branches.any? { |branch| examples?(branch) }
@@ -21,6 +21,7 @@ module RuboCop
21
21
 
22
22
  def on_metadata(_symbols, hash)
23
23
  return unless hash&.pairs&.empty?
24
+ return if hash.children.any?(&:kwsplat_type?)
24
25
 
25
26
  add_offense(hash) do |corrector|
26
27
  remove_empty_metadata(corrector, hash)
@@ -69,7 +69,7 @@ module RuboCop
69
69
  expect_literal(node) do |actual, send_node, matcher, expected|
70
70
  next if SKIPPED_MATCHERS.include?(matcher)
71
71
 
72
- add_offense(actual.source_range) do |corrector|
72
+ add_offense(actual) do |corrector|
73
73
  next unless CORRECTABLE_MATCHERS.include?(matcher)
74
74
  next if literal?(expected)
75
75
 
@@ -29,12 +29,6 @@ module RuboCop
29
29
  # describe 'test' do; end
30
30
  #
31
31
  # # bad
32
- # fdescribe 'test' do; end
33
- #
34
- # # good
35
- # describe 'test' do; end
36
- #
37
- # # bad
38
32
  # shared_examples 'test', focus: true do; end
39
33
  #
40
34
  # # good
@@ -48,8 +48,8 @@ module RuboCop
48
48
  include AllowedIdentifiers
49
49
  include AllowedPattern
50
50
 
51
- MSG = 'This `let` statement uses index in its name. Please give it ' \
52
- 'a meaningful name.'
51
+ MSG = 'This `let` statement uses `%<index>s` in its name. ' \
52
+ 'Please give it a meaningful name.'
53
53
 
54
54
  # @!method let_name(node)
55
55
  def_node_matcher :let_name, <<~PATTERN
@@ -66,7 +66,8 @@ module RuboCop
66
66
  return unless children
67
67
 
68
68
  filter_indexed_lets(children).each do |let_node|
69
- add_offense(let_node)
69
+ index = let_name(let_node)[INDEX_REGEX]
70
+ add_offense(let_node, message: format(MSG, index: index))
70
71
  end
71
72
  end
72
73
 
@@ -6,6 +6,7 @@ module RuboCop
6
6
  # Checks where `match_array` is used.
7
7
  #
8
8
  # This cop checks for the following:
9
+ #
9
10
  # - Prefer `contain_exactly` when matching an array with values.
10
11
  # - Prefer `eq` when using `match_array` with an empty array literal.
11
12
  #
@@ -45,13 +45,8 @@ module RuboCop
45
45
  PATTERN
46
46
 
47
47
  def on_metadata(symbols, hash)
48
- # RSpec example groups accept two string arguments. In such a case,
49
- # the rspec_metadata matcher will interpret the second string
50
- # argument as a metadata symbol.
51
- symbols.shift if symbols.first&.str_type?
52
-
53
48
  symbols.each do |symbol|
54
- on_metadata_symbol(symbol)
49
+ on_metadata_symbol(symbol) if symbol.sym_type?
55
50
  end
56
51
 
57
52
  return unless hash
@@ -47,15 +47,12 @@ module RuboCop
47
47
  private
48
48
 
49
49
  def on_metadata_arguments(metadata_arguments)
50
- *symbols, last = metadata_arguments
51
- hash = nil
52
- case last&.type
53
- when :hash
54
- hash = last
55
- when :sym
56
- symbols << last
50
+ if metadata_arguments.last&.hash_type?
51
+ *metadata_arguments, hash = metadata_arguments
52
+ on_metadata(metadata_arguments, hash)
53
+ else
54
+ on_metadata(metadata_arguments, nil)
57
55
  end
58
- on_metadata(symbols, hash)
59
56
  end
60
57
  end
61
58
  end
@@ -7,6 +7,10 @@ module RuboCop
7
7
  module TopLevelGroup
8
8
  extend RuboCop::NodePattern::Macros
9
9
 
10
+ DEPRECATED_MODULE_METHOD_WARNING =
11
+ 'top_level_group? is deprecated and will be ' \
12
+ 'removed in the next major version of rubocop_rspec.'
13
+
10
14
  def on_new_investigation
11
15
  super
12
16
 
@@ -28,7 +32,10 @@ module RuboCop
28
32
 
29
33
  def on_top_level_group(_node); end
30
34
 
35
+ # @private
36
+ # @deprecated All callers of this method have been removed.
31
37
  def top_level_group?(node)
38
+ warn DEPRECATED_MODULE_METHOD_WARNING, uplevel: 1
32
39
  top_level_groups.include?(node)
33
40
  end
34
41
 
@@ -94,11 +94,6 @@ module RuboCop
94
94
  (send #rspec? ${#ExampleGroups.skipped} ...)
95
95
  PATTERN
96
96
 
97
- # @!method pending_step_without_reason?(node)
98
- def_node_matcher :pending_step_without_reason?, <<~PATTERN
99
- (send nil? {:skip :pending})
100
- PATTERN
101
-
102
97
  def on_send(node)
103
98
  on_pending_by_metadata(node)
104
99
  return unless (parent = parent_node(node))
@@ -67,11 +67,10 @@ module RuboCop
67
67
  end
68
68
 
69
69
  def autocorrect_hash_arg(corrector, arg)
70
- key, value = *arg.children.first
71
-
72
- corrector.replace(arg, key_to_arg(key))
70
+ pair = arg.pairs.first
71
+ corrector.replace(arg, key_to_arg(pair.key))
73
72
  corrector.insert_after(arg.parent.loc.end,
74
- ".and_return(#{value.source})")
73
+ ".and_return(#{pair.value.source})")
75
74
  end
76
75
 
77
76
  def autocorrect_array_arg(corrector, arg)
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module RSpec
6
6
  # Sort RSpec metadata alphabetically.
7
7
  #
8
+ # Only the trailing metadata is sorted.
9
+ #
8
10
  # @example
9
11
  # # bad
10
12
  # describe 'Something', :b, :a
@@ -16,6 +18,9 @@ module RuboCop
16
18
  # context 'Something', baz: true, foo: 'bar'
17
19
  # it 'works', :a, :b, baz: true, foo: 'bar'
18
20
  #
21
+ # # good, trailing metadata is sorted
22
+ # describe 'Something', 'description', :a, :b, :z
23
+ # context 'Something', :z, variable, :a, :b
19
24
  class SortMetadata < Base
20
25
  extend AutoCorrector
21
26
  include Metadata
@@ -23,8 +28,14 @@ module RuboCop
23
28
 
24
29
  MSG = 'Sort metadata alphabetically.'
25
30
 
26
- def on_metadata(symbols, hash)
31
+ # @!method match_ambiguous_trailing_metadata?(node)
32
+ def_node_matcher :match_ambiguous_trailing_metadata?, <<~PATTERN
33
+ (send _ _ _ ... !{hash sym str dstr xstr})
34
+ PATTERN
35
+
36
+ def on_metadata(args, hash)
27
37
  pairs = hash&.pairs || []
38
+ symbols = trailing_symbols(args)
28
39
  return if sorted?(symbols, pairs)
29
40
 
30
41
  crime_scene = crime_scene(symbols, pairs)
@@ -35,6 +46,15 @@ module RuboCop
35
46
 
36
47
  private
37
48
 
49
+ def trailing_symbols(args)
50
+ args = args[...-1] if last_arg_could_be_a_hash?(args)
51
+ args.reverse.take_while(&:sym_type?).reverse
52
+ end
53
+
54
+ def last_arg_could_be_a_hash?(args)
55
+ args.last && match_ambiguous_trailing_metadata?(args.last.parent)
56
+ end
57
+
38
58
  def crime_scene(symbols, pairs)
39
59
  metadata = symbols + pairs
40
60
 
@@ -57,13 +77,7 @@ module RuboCop
57
77
  end
58
78
 
59
79
  def sort_symbols(symbols)
60
- symbols.sort_by do |symbol|
61
- if symbol.str_type? || symbol.sym_type?
62
- symbol.value.to_s.downcase
63
- else
64
- symbol.source.downcase
65
- end
66
- end
80
+ symbols.sort_by { |symbol| symbol.value.to_s.downcase }
67
81
  end
68
82
  end
69
83
  end
@@ -14,8 +14,9 @@ module RuboCop
14
14
  # expect(foo).to receive(:bar).with(42)
15
15
  #
16
16
  class StubbedMock < Base
17
- MSG = 'Prefer `%<replacement>s` over `%<method_name>s` when ' \
17
+ MSG = 'Prefer %<replacement>s over `%<method_name>s` when ' \
18
18
  'configuring a response.'
19
+ RESTRICT_ON_SEND = %i[to].freeze
19
20
 
20
21
  # @!method message_expectation?(node)
21
22
  # Match message expectation matcher
@@ -133,8 +134,6 @@ module RuboCop
133
134
  }
134
135
  PATTERN
135
136
 
136
- RESTRICT_ON_SEND = %i[to].freeze
137
-
138
137
  def on_send(node)
139
138
  expectation(node) do |expectation, method_name, matcher|
140
139
  on_expectation(expectation, method_name, matcher)
@@ -155,19 +154,23 @@ module RuboCop
155
154
  end
156
155
 
157
156
  def msg(method_name)
158
- format(MSG,
159
- method_name: method_name,
160
- replacement: replacement(method_name))
157
+ format(
158
+ MSG,
159
+ method_name: method_name,
160
+ replacement: replacement(method_name)
161
+ )
161
162
  end
162
163
 
163
164
  def replacement(method_name)
164
165
  case method_name
165
166
  when :expect
166
- :allow
167
+ '`allow`'
167
168
  when :is_expected
168
- 'allow(subject)'
169
+ '`allow(subject)`'
169
170
  when :expect_any_instance_of
170
- :allow_any_instance_of
171
+ '`allow_any_instance_of`'
172
+ else
173
+ 'an allow statement'
171
174
  end
172
175
  end
173
176
  end
@@ -62,7 +62,9 @@ module RuboCop
62
62
  end
63
63
 
64
64
  def find_expect_to(node)
65
- node.each_ancestor(:send).find do |ancestor|
65
+ node.each_ancestor.find do |ancestor|
66
+ break if ancestor.block_type?
67
+
66
68
  expect_to?(ancestor)
67
69
  end
68
70
  end
@@ -5,14 +5,14 @@ module RuboCop
5
5
  module RSpec
6
6
  # Checks for consistent verified double reference style.
7
7
  #
8
- # Only investigates references that are one of the supported styles.
9
- #
10
8
  # @see https://rspec.info/features/3-12/rspec-mocks/verifying-doubles
11
9
  #
12
- # This cop can be configured in your configuration using the
13
- # `EnforcedStyle` option and supports `--auto-gen-config`.
10
+ # @safety
11
+ # This cop is unsafe because the correction requires loading the class.
12
+ # Loading before stubbing causes RSpec to only allow instance methods
13
+ # to be stubbed.
14
14
  #
15
- # @example `EnforcedStyle: constant` (default)
15
+ # @example
16
16
  # # bad
17
17
  # let(:foo) do
18
18
  # instance_double('ClassName', method_name: 'returned_value')
@@ -23,18 +23,7 @@ module RuboCop
23
23
  # instance_double(ClassName, method_name: 'returned_value')
24
24
  # end
25
25
  #
26
- # @example `EnforcedStyle: string`
27
- # # bad
28
- # let(:foo) do
29
- # instance_double(ClassName, method_name: 'returned_value')
30
- # end
31
- #
32
- # # good
33
- # let(:foo) do
34
- # instance_double('ClassName', method_name: 'returned_value')
35
- # end
36
- #
37
- # @example Reference is not in the supported style list. No enforcement
26
+ # @example Reference is any dynamic variable. No enforcement
38
27
  #
39
28
  # # good
40
29
  # let(:foo) do
@@ -42,9 +31,9 @@ module RuboCop
42
31
  # end
43
32
  class VerifiedDoubleReference < Base
44
33
  extend AutoCorrector
45
- include ConfigurableEnforcedStyle
46
34
 
47
- MSG = 'Use a %<style>s class reference for verified doubles.'
35
+ MSG = 'Use a constant class reference for verified doubles. ' \
36
+ 'String references are not verifying unless the class is loaded.'
48
37
 
49
38
  RESTRICT_ON_SEND = Set[
50
39
  :class_double,
@@ -57,53 +46,25 @@ module RuboCop
57
46
  :stub_model
58
47
  ].freeze
59
48
 
60
- REFERENCE_TYPE_STYLES = {
61
- str: :string,
62
- const: :constant
63
- }.freeze
64
-
65
49
  # @!method verified_double(node)
66
50
  def_node_matcher :verified_double, <<~PATTERN
67
51
  (send
68
52
  nil?
69
53
  RESTRICT_ON_SEND
70
- $_class_reference
54
+ $str
71
55
  ...)
72
56
  PATTERN
73
57
 
74
58
  def on_send(node)
75
- verified_double(node) do |class_reference|
76
- break correct_style_detected unless opposing_style?(class_reference)
77
-
78
- message = format(MSG, style: style)
79
- expression = class_reference.source_range
80
-
81
- add_offense(expression, message: message) do |corrector|
82
- offense = class_reference.source
83
- corrector.replace(expression, correct_style(offense))
84
-
85
- opposite_style_detected
59
+ verified_double(node) do |string_argument_node|
60
+ add_offense(string_argument_node) do |corrector|
61
+ autocorrect(corrector, string_argument_node)
86
62
  end
87
63
  end
88
64
  end
89
65
 
90
- private
91
-
92
- def opposing_style?(class_reference)
93
- class_reference_style = REFERENCE_TYPE_STYLES[class_reference.type]
94
-
95
- # Only enforce supported styles
96
- return false unless class_reference_style
97
-
98
- class_reference_style != style
99
- end
100
-
101
- def correct_style(offense)
102
- if style == :string
103
- "'#{offense}'"
104
- else
105
- offense.gsub(/^['"]|['"]$/, '')
106
- end
66
+ def autocorrect(corrector, node)
67
+ corrector.replace(node, node.value)
107
68
  end
108
69
  end
109
70
  end
@@ -29,12 +29,14 @@ module RuboCop
29
29
 
30
30
  def on_send(node)
31
31
  return unless expect?(node)
32
+ return unless inside_example?(node)
32
33
 
33
34
  check_expect(node)
34
35
  end
35
36
 
36
37
  def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
37
38
  return unless expect_block?(node)
39
+ return unless inside_example?(node)
38
40
 
39
41
  check_expect(node)
40
42
  end
@@ -49,11 +51,14 @@ module RuboCop
49
51
 
50
52
  def void?(expect)
51
53
  parent = expect.parent
52
- return true unless parent
53
54
  return true if parent.begin_type?
54
55
 
55
56
  parent.block_type? && parent.body == expect
56
57
  end
58
+
59
+ def inside_example?(node)
60
+ node.each_ancestor(:block).any? { |ancestor| example?(ancestor) }
61
+ end
57
62
  end
58
63
  end
59
64
  end
@@ -62,8 +62,8 @@ module RuboCop
62
62
  end
63
63
 
64
64
  def cop_subclass?
65
- yardoc.superclass.path == RSPEC_COP_CLASS_NAME ||
66
- yardoc.superclass.path == RUBOCOP_COP_CLASS_NAME
65
+ [RSPEC_COP_CLASS_NAME,
66
+ RUBOCOP_COP_CLASS_NAME].include?(yardoc.superclass.path)
67
67
  end
68
68
 
69
69
  def abstract?
@@ -45,7 +45,7 @@ module RuboCop
45
45
  private
46
46
 
47
47
  def valid_scope?(node)
48
- node&.sym_type? && Language::HookScopes.all(node.value)
48
+ node.sym_type? && Language::HookScopes.all(node.value)
49
49
  end
50
50
 
51
51
  def transform_metadata(meta)
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # Version information for the RSpec RuboCop plugin.
6
6
  module Version
7
- STRING = '3.0.4'
7
+ STRING = '3.4.0'
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.4
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Backus
8
8
  - Ian MacLeod
9
9
  - Nils Gemeinhardt
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2024-08-05 00:00:00.000000000 Z
12
+ date: 2025-01-20 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rubocop
@@ -192,7 +191,6 @@ metadata:
192
191
  changelog_uri: https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md
193
192
  documentation_uri: https://docs.rubocop.org/rubocop-rspec/
194
193
  rubygems_mfa_required: 'true'
195
- post_install_message:
196
194
  rdoc_options: []
197
195
  require_paths:
198
196
  - lib
@@ -207,8 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
205
  - !ruby/object:Gem::Version
208
206
  version: '0'
209
207
  requirements: []
210
- rubygems_version: 3.5.11
211
- signing_key:
208
+ rubygems_version: 3.6.2
212
209
  specification_version: 4
213
210
  summary: Code style checking for RSpec files
214
211
  test_files: []
OSZAR »