rubocop-rspec 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
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