rubocop-rspec 3.3.0 → 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: 3ca108a17fe360c345896a230b0bec34f36430cfff3eb7b06d9fd28fa302da06
4
- data.tar.gz: 8eaf93b36c0cf29b2718e86fc8d99e85601f517966d008fd00d53f4315cd1745
3
+ metadata.gz: 4a2433cc3212de48725bca4fa2f8216ef0742950d1b0ad0a52e0d717050ede4e
4
+ data.tar.gz: 3e43165a772275ece7344813b6dfc5196669763013c0bedc3b75107cf6fa0f30
5
5
  SHA512:
6
- metadata.gz: f3375145facfb2e91f2cfee6949544947756e965f23fd713a09aba5f301b8558dc40be1b9cc3a66cb629c2b14f643a8bfb9aab12bff509dcfbcb2f9b05e801ac
7
- data.tar.gz: 75ea9be799c2868fbc4b7333b20d95ecf3934f0d8d38339c9c412010b037811cb2d45b2c3e494e01ea6f1be3619ac39290c22af5b1b76cc75a3ec0e0c3a9f6c3
6
+ metadata.gz: 41a9171c098150e3349977cd08df5f369fe2d33c0bb4f1b29edcfb2633eae2c880ab1ff71a9c4a1ee5dc28645a6359ecd3e4ab99a822ac576523386e78364ee2
7
+ data.tar.gz: af1c164ac3d8c9e9ed61611fa9877c459656f695fd45c057c776af99304fcd8471fa00d958d7bf650ba46f82056ae96accd12cfeec17eb1a00129baffdb51768
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
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
+
5
11
  ## 3.3.0 (2024-12-12)
6
12
 
7
13
  - Deprecate `top_level_group?` method from `TopLevelGroup` mixin as all of its callers were intentionally removed from `Rubocop/RSpec`. ([@corsonknowles])
@@ -93,7 +99,7 @@ Read more about how to upgrade in https://docs.rubocop.org/rubocop-rspec/upgrade
93
99
  - Add new `RSpec/IsExpectedSpecify` cop. ([@ydah])
94
100
  - Add new `RSpec/RepeatedSubjectCall` cop. ([@drcapulet])
95
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])
96
- - Support asserts with messages in `Rspec/BeEmpty`. ([@G-Rath])
102
+ - Support asserts with messages in `RSpec/BeEmpty`. ([@G-Rath])
97
103
  - Fix a false positive for `RSpec/ExpectActual` when used with rspec-rails routing matchers. ([@naveg])
98
104
  - Add configuration option `ResponseMethods` to `RSpec/Rails/HaveHttpStatus`. ([@ydah])
99
105
  - Fix a false negative for `RSpec/DescribedClass` when class with constant. ([@ydah])
@@ -288,7 +294,7 @@ Read more about how to upgrade in https://docs.rubocop.org/rubocop-rspec/upgrade
288
294
  ## 2.13.0 (2022-09-12)
289
295
 
290
296
  - Fix `RSpec/FilePath` cop missing mismatched expanded namespace. ([@sl4vr])
291
- - Add new `AllowConsecutiveOneLiners` (default true) option for `Rspec/EmptyLineAfterHook` cop. ([@ngouy])
297
+ - Add new `AllowConsecutiveOneLiners` (default true) option for `RSpec/EmptyLineAfterHook` cop. ([@ngouy])
292
298
  - Add autocorrect support for `RSpec/EmptyExampleGroup`. ([@r7kamura])
293
299
  - Fix `RSpec/ChangeByZero` with compound expressions using `&` or `|` operators. ([@BrianHawley])
294
300
  - Add `RSpec/NoExpectationExample`. ([@r7kamura])
@@ -989,6 +995,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
989
995
  [@leoarnold]: https://github.com/leoarnold
990
996
  [@liberatys]: https://github.com/Liberatys
991
997
  [@lokhi]: https://github.com/lokhi
998
+ [@lovro-bikic]: https://github.com/lovro-bikic
992
999
  [@luke-hill]: https://github.com/luke-hill
993
1000
  [@m-yamashita01]: https://github.com/M-Yamashita01
994
1001
  [@marocchino]: https://github.com/marocchino
data/config/default.yml CHANGED
@@ -930,13 +930,6 @@ RSpec/SpecFilePathSuffix:
930
930
  - "**/spec/**/*"
931
931
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SpecFilePathSuffix
932
932
 
933
- RSpec/StringAsInstanceDoubleConstant:
934
- Description: Do not use a string as `instance_double` constant.
935
- Enabled: pending
936
- Safe: false
937
- VersionAdded: '3.1'
938
- Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/StringAsInstanceDoubleConstant
939
-
940
933
  RSpec/StubbedMock:
941
934
  Description: Checks that message expectations do not have a configured response.
942
935
  Enabled: true
@@ -995,12 +988,8 @@ RSpec/VerifiedDoubleReference:
995
988
  Description: Checks for consistent verified double reference style.
996
989
  Enabled: true
997
990
  SafeAutoCorrect: false
998
- EnforcedStyle: constant
999
- SupportedStyles:
1000
- - constant
1001
- - string
1002
991
  VersionAdded: 2.10.0
1003
- VersionChanged: '2.12'
992
+ VersionChanged: '3.4'
1004
993
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubleReference
1005
994
 
1006
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
@@ -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
  #
@@ -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) }
@@ -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
@@ -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
  #
@@ -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
@@ -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))
@@ -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
@@ -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
@@ -99,7 +99,6 @@ require_relative 'rspec/skip_block_inside_example'
99
99
  require_relative 'rspec/sort_metadata'
100
100
  require_relative 'rspec/spec_file_path_format'
101
101
  require_relative 'rspec/spec_file_path_suffix'
102
- require_relative 'rspec/string_as_instance_double_constant'
103
102
  require_relative 'rspec/stubbed_mock'
104
103
  require_relative 'rspec/subject_declaration'
105
104
  require_relative 'rspec/subject_stub'
@@ -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?
@@ -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.3.0'
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.3.0
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-12-12 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
@@ -157,7 +156,6 @@ files:
157
156
  - lib/rubocop/cop/rspec/sort_metadata.rb
158
157
  - lib/rubocop/cop/rspec/spec_file_path_format.rb
159
158
  - lib/rubocop/cop/rspec/spec_file_path_suffix.rb
160
- - lib/rubocop/cop/rspec/string_as_instance_double_constant.rb
161
159
  - lib/rubocop/cop/rspec/stubbed_mock.rb
162
160
  - lib/rubocop/cop/rspec/subject_declaration.rb
163
161
  - lib/rubocop/cop/rspec/subject_stub.rb
@@ -193,7 +191,6 @@ metadata:
193
191
  changelog_uri: https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md
194
192
  documentation_uri: https://docs.rubocop.org/rubocop-rspec/
195
193
  rubygems_mfa_required: 'true'
196
- post_install_message:
197
194
  rdoc_options: []
198
195
  require_paths:
199
196
  - lib
@@ -208,8 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
205
  - !ruby/object:Gem::Version
209
206
  version: '0'
210
207
  requirements: []
211
- rubygems_version: 3.5.22
212
- signing_key:
208
+ rubygems_version: 3.6.2
213
209
  specification_version: 4
214
210
  summary: Code style checking for RSpec files
215
211
  test_files: []
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module RSpec
6
- # Do not use a string as `instance_double` constant.
7
- #
8
- # @safety
9
- # This cop is unsafe because the correction requires loading the class.
10
- # Loading before stubbing causes RSpec to only allow instance methods
11
- # to be stubbed.
12
- #
13
- # @example
14
- # # bad
15
- # instance_double('User', name: 'John')
16
- #
17
- # # good
18
- # instance_double(User, name: 'John')
19
- #
20
- class StringAsInstanceDoubleConstant < Base
21
- extend AutoCorrector
22
-
23
- MSG = 'Do not use a string as `instance_double` constant.'
24
- RESTRICT_ON_SEND = %i[instance_double].freeze
25
-
26
- # @!method stringified_instance_double_const?(node)
27
- def_node_matcher :stringified_instance_double_const?, <<~PATTERN
28
- (send nil? :instance_double $str ...)
29
- PATTERN
30
-
31
- def on_send(node)
32
- stringified_instance_double_const?(node) do |args_node|
33
- add_offense(args_node) do |corrector|
34
- autocorrect(corrector, args_node)
35
- end
36
- end
37
- end
38
-
39
- def autocorrect(corrector, node)
40
- corrector.replace(node, node.value)
41
- end
42
- end
43
- end
44
- end
45
- end